tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Definiciones

⎇ main recipes/typst.toml TOML · 111 líneas · 7.9 KB Historia crudo

feat(recetas): pata y churay entran al catálogo — «no hay pata» era que no existía el paquete 5ba9b5365 · Sergio ·

1# typst — composición tipográfica moderna: el hueco de LaTeX, que este catálogo no tenía de ninguna forma
2#
3# ── POR QUÉ ENTRA ──────────────────────────────────────────────────────────────────────────────
4# 56.592★, Apache-2.0, 435 crates, **Rust puro y CLI**: ni toolkit, ni muro gráfico, ni decisión de
5# distro. Y cubre una función que el catálogo **no tiene por ningún lado** —componer un documento
6# desde texto plano, con bibliografía, fórmulas y PDF reproducible—, que es justo la otra mitad de
7# lo que la suite ArtCraft trajo el 2026-10-13: `wordcraft` edita y exporta, `typst` COMPONE.
8#
9# El dato que la vuelve barata, y que sale del `Cargo.lock`, no del README: **cero dependencias C de
10# tipografía**. Su `fontconfig-parser` es un parser de los ficheros de fontconfig **escrito en Rust**
11# —no la `libfontconfig` de C— y las fuentes van por `fontdb` + `ttf-parser` + fontations
12# (`read-fonts`/`write-fonts`). Lo único C del árbol es `libdeflate-sys`, que trae su propio fuente y
13# lo compila con el crate `cc`; de ahí el envoltorio `AR` de abajo.
14#
15# ── LAS DOS PERILLAS QUE IMPORTAN, Y POR QUÉ SE DEJAN COMO ESTÁN ───────────────────────────────
16# `typst-cli` trae `default = ["embedded-fonts", "http-server"]`:
17#   · **`embedded-fonts` se queda**: mete las fuentes dentro del binario, así que `typst compile`
18#     funciona en una imagen que no declare ni una familia tipográfica. Sin eso, el fallo sería el
19#     clásico de esta casa —binario sellado, presente, y sin con qué dibujar una letra.
20#   · **`self-update` NO está en el default y no se enciende**: se actualiza por `takana install`,
21#     como todo acá, y encenderlo arrastraría `xz2` y `zip` de yapa.
22#   · **`vendor-openssl` tampoco se enciende, pero NO porque openssl no haga falta.** Acá la primera
23#     versión de esta receta se equivocó y el build lo dijo a la primera:
24#
25#         error: failed to run custom build command for `openssl-sys v0.9.116`
26#
27#     Yo había escrito que «en el lock no hay `openssl-sys`». **Lo había, y mi propio filtro de
28#     triaje lo tapó**: la lista de crates `-sys` salía por un `head -8` y `openssl-sys` caía abajo.
29#     Una vista RECORTADA leída como si fuera la verdad entera — la misma figura que el `provee.py`
30#     apuntando al store vacío, y van dos en el mismo día.
31#     La cadena real es `typst-cli` → `typst-kit/system-downloader` → `ureq` → `native-tls` →
32#     `openssl`, y **no hay alternativa de rustls en typst-kit**: sus features son `native-tls` o
33#     nada. Las tres salidas eran: (a) apagar `system-downloader` —y dejar a `typst` sin poder bajar
34#     paquetes de Typst Universe, o sea una herramienta mutilada en silencio—, (b) `vendor-openssl`,
35#     que compila OTRO openssl dentro de este build teniendo uno en el corpus, o (c) darle el del
36#     corpus. Se eligió (c).
37#
38# ── ⚠ Y DE LAS DOS OPENSSL DEL CORPUS, LA QUE LLEVA THREADS ───────────────────────────────────
39# `recipes/openssl.toml` se construye con `link = "static"`, y eso hace que el `Configure` de openssl
40# **apague `threads` y `pic` en silencio** (su línea 1514, ver [[link-static-apaga-threads-openssl]]:
41# es lo que dejó a `python3` sin `_ssl` durante meses). `recipes/openssl-threads.toml` es la misma
42# receta con `link = "dynamic"` —sigue emitiendo `.a`, o sea que no cambia el enlazado estático de
43# acá— y sí define `OPENSSL_THREADS`. Para una herramienta que abre conexiones de red, la variante
44# sin threads es una mina silenciosa: se usa la otra, que es la que ya usan `python3` y `rust`.
45name    = "typst"
46version = "0.15.1"
47license = "Apache-2.0"
48
49[source]
50# `v0.15.1` (release del 2026-07-17). Se pinea el SHA del tag: un tag se mueve.
51# ⚠ El endpoint de tags de GitHub devuelve primero unos `v23-03-28` que son de 2023 y NO son la
52# versión vigente: hay que preguntarle a `releases/latest`, no a `tags`.
53repo   = "https://github.com/typst/typst"
54commit = "9dfd3a08500b7896045f907433cf7b4b02434fad"
55# No committea `vendor/` ni usa `[patch.crates-io]` ⇒ el vendoreo va al `vendor/` por defecto sin
56# pisarle nada (la trampa que mató a `pdfcraft` no aplica; comprobado en el árbol del tag).
57
58[build]
59compiler = "zig-cc"
60target   = "x86_64-linux-musl"
61# `static` y no `dynamic`: es una herramienta de línea de comandos, no carga nada por `dlopen`.
62link     = "static"
63flags    = ["-p", "typst-cli", "--bin", "typst"]
64
65[build.phases]
66compile = '''
67set -e
68# El envoltorio de `AR` no es decorativo: el default de zig-cc exporta `AR="zig ar"` CON ESPACIO, y
69# el crate `cc` —que acá compila `libdeflate-sys`— ejecuta `$AR` como un binario ÚNICO ⇒ busca uno
70# llamado «zig ar» y falla. Es la cicatriz de `mise.toml`.
71printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
72chmod +x "$PWD/.hammer-zig-cc"
73printf '%s\n' '#!/bin/sh' 'exec zig ar "$@"' > "$PWD/.hammer-zig-ar"
74chmod +x "$PWD/.hammer-zig-ar"
75RF="-C linker=$PWD/.hammer-zig-cc"
76rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
77# `OPENSSL_NO_VENDOR` para que `openssl-sys` no caiga nunca al openssl vendoreado del crate (sería
78# un segundo openssl dentro del artefacto, distinto del del corpus), y `OPENSSL_STATIC` porque la
79# capa que se le monta trae `libssl.a`/`libcrypto.a` y nada de `.so`: sin esto, `openssl-sys` puede
80# decidir enlazado dinámico y el fallo aparece recién al LIGAR, lejos de la causa.
81CC="$PWD/.hammer-zig-cc" AR="$PWD/.hammer-zig-ar" RUSTFLAGS="$RF" OPENSSL_NO_VENDOR=1 OPENSSL_STATIC=1 cargo rustc --release --locked --offline -p typst-cli --bin typst -- -C target-feature=+crt-static -C relocation-model=static
82'''
83install = '''
84set -e
85test -x target/release/typst || { echo "no hay target/release/typst — ¿cambió el nombre del bin?" >&2; exit 1; }
86
87# ── LA PRUEBA DE QUE NO ES UN NOMBRE: COMPONER UN DOCUMENTO DE VERDAD ─────────────────────────
88# Un binario sellado, con contenido y reproducible puede igual no hacer NADA (memoria:
89# «subcomando SIN DRIVER = binario inerte»). Acá eso tiene una forma concreta y barata de medirse:
90# que componga. Si `typst compile` no produce un PDF, esta receta NO debe sellar — un typst que no
91# compone es exactamente la clase de artefacto que llega hasta el final diciendo que todo fue bien.
92mkdir -p "$PWD/.smoke"
93printf '%s\n' '#set page(width: 80pt, height: 40pt, margin: 4pt)' '= Takana' 'Compone.' > "$PWD/.smoke/p.typ"
94./target/release/typst compile --font-path "$PWD/.smoke" "$PWD/.smoke/p.typ" "$PWD/.smoke/p.pdf" 2>"$PWD/.smoke/err" || { echo "typst compile FALLÓ:" >&2; cat "$PWD/.smoke/err" >&2; exit 1; }
95test -s "$PWD/.smoke/p.pdf" || { echo "typst compile salió 0 y el PDF quedó VACÍO" >&2; exit 1; }
96head -c 5 "$PWD/.smoke/p.pdf" | grep -q '%PDF-' || { echo "lo que salió no es un PDF" >&2; exit 1; }
97echo "smoke: typst compuso $(wc -c < "$PWD/.smoke/p.pdf") bytes de PDF con las fuentes EMBEBIDAS"
98
99install -Dm755 target/release/typst /out/usr/bin/typst
100install -Dm644 LICENSE /out/usr/share/licenses/typst/LICENSE
101install -Dm644 NOTICE  /out/usr/share/licenses/typst/NOTICE
102test -s /out/usr/bin/typst
103'''
104
105[deps]
106# Lo MÍNIMO que pide, medido tras el fallo de la primera corrida: openssl (con threads) y pkgconf
107# para que `openssl-sys` lo encuentre por `pkg-config`. Lo que sigue siendo cierto del triaje: **no
108# hay fontconfig ni freetype** —`fontconfig-parser` es un parser en Rust y las fuentes van
109# embebidas— y **no hay zlib del sistema**: `libz-rs-sys` es zlib EN RUST y `libdeflate-sys` compila
110# su propio C.
111build = ["openssl-threads", "pkgconf"]