Herramientas
HoopLang se usa con tres herramientas que comparten el mismo compilador: la
línea de comandos hoop (verificar, producir archivos de máquina y
formatear), el playground en el navegador (editor de varios archivos con
el bordado en vivo) y la API WebAssembly sobre la que está construido el
playground. Este capítulo describe cada una, las reglas de formato de hoop fmt y el soporte de editores.
La herramienta hoop#
Desde la raíz del repositorio:
cargo run -q --release --bin hoop -- check <archivo.hoop>
cargo run -q --release --bin hoop -- build <archivo.hoop> <carpeta>
cargo run -q --release --bin hoop -- fmt [--check] <archivo.hoop>…(El binario compilado queda en target/release/hoop; en los ejemplos se
escribe hoop.) Sin argumentos válidos imprime el uso y termina con código
2:
usage: hoop check <file.hoop> | hoop build <file.hoop> <out-dir> | hoop fmt [--check] <file.hoop>…Los import y place se resuelven relativos a la carpeta del archivo que
se pasa (ver Módulos). Si ese archivo no
se puede leer: <archivo>: cannot read: <motivo>, código 2.
hoop check#
Analiza, verifica y compila el archivo (sin coser ni escribir nada) e imprime cada diagnóstico con el formato de Diagnósticos, precedido por la ruta del archivo.
Un
design: se verifica y, si no hay errores, se compila para revisar los límites (E006,W008,W009). Si todo está bien, termina conSalida del compilador<archivo>: ok — T threads, L layers, O objectsdonde
Tcuenta los colores distintos que se cosen (incluidos los de los diseños colocados conplace; dos hilos del mismo color son uno, como enbuild) yOlas primitivas yplacedel archivo (una vez evaluados losforeif), no los objetos del motor. Si eldesigndeclaraframe, también revisa que quepa (ver más abajo).Un
hoop: se monta entero (cada diseño colocado se compila y se ubica) y termina conSalida del compilador<archivo>: ok — N designs, T threads, O objectsdonde
Nes la cantidad de diseños colocados,Tlos colores distintos que se cosen yOlos objetos del motor.Una biblioteca (un archivo con sólo
import,thread,constyshape): se verifica como la ve quien la importa y termina conSalida del compilador<archivo>: library — T threads, C consts, S shapesCódigo de salida: 0 si no hay errores (aunque haya advertencias), 1 si hay al menos un error, 2 por un problema de uso o de lectura.
$ hoop check w008.hoop
w008.hoop:1:1: warning W008: no canvas: bounds are not checked; the design measures 30.0 × 20.0 mm (declare `canvas: rect(size: (30mm, 20mm))`)
w008.hoop: ok — 1 threads, 1 layers, 1 objectsEl frame de un design se revisa con la caja de los objetos, sin coser
(puede diferir en décimas de lo bordado): si no cabe, imprime
<archivo>: error: the design is W × H mm and does not fit the A × B mm frame y termina con 1. Los límites de los formatos de máquina dependen de
las puntadas: los revisa sólo build.
hoop build#
Compila el archivo, borda (genera las puntadas) y escribe los archivos de
máquina y las vistas en <carpeta> (que se crea si no existe). Con <nombre>
el nombre del archivo sin .hoop:
| Archivo | Contenido |
|---|---|
<nombre>.pes | Brother (PES v6, con los nombres, marcas y códigos de los hilos). |
<nombre>.dst | Tajima. |
<nombre>.exp | Melco / Bernina. |
<nombre>.jef | Janome. |
<nombre>.vp3 | Husqvarna / Pfaff. |
<nombre>.xxx | Singer. |
<nombre>.svg | Vista realista del bordado. |
<nombre>.needles.svg | Vista de las agujas (los puntos de cada puntada). |
$ hoop build bastidor.hoop out
bastidor.hoop: 70.4 × 90.4 mm, 6420 stitches, 2 threads, 11 trims, 56 ms- Antes de la línea de resumen se imprimen las advertencias del compilador y
los avisos de límites de máquina (ver
Avisos de máquina), cada uno
precedido por la ruta. Estos avisos no detienen la escritura, pero si
alguno es
error(no cabe en el bastidor, demasiados colores para un formato),buildtermina con código 1 después de escribir los archivos. - El resumen da el tamaño del bordado, las puntadas, los hilos (bloques de color: un color que vuelve después de otro cuenta de nuevo), los cortes y el tiempo que tomó.
- Si hay errores, se imprimen (uno por línea, con la ruta) y termina con código 1 sin escribir archivos de máquina.
- El origen de los archivos de máquina es el centro del bastidor en un
hoopy el centro del bordado en undesign(ver Bastidor). - La salida es determinista: la misma entrada da los mismos bytes.
hoop fmt#
Reescribe cada archivo en el estilo estándar. Acepta varios archivos.
- Sin
--check: un archivo que cambia se sobrescribe y se informa<archivo>: formatted; uno que ya estaba formateado no se toca ni se menciona. - Con
--check: no escribe nada; informa<archivo>: not formattedpor cada archivo que cambiaría. - Un archivo con un error léxico se informa como diagnóstico
(
malo.hoop:1:17: error E000: unclosed string (missing closing quote)) y no se toca. El formateador trabaja sobre los tokens: un archivo con errores de sintaxis o de tipos, pero léxicamente válido, se formatea igual. - Código de salida: 0 si todo está formateado (o se formateó), 1 si con
--checkhay archivos sin formatear, 2 si algún archivo no se pudo leer o tiene un error léxico (o faltan argumentos).
$ hoop fmt --check feo.hoop cuadro.hoop
feo.hoop: not formatted
$ hoop fmt feo.hoop
feo.hoop: formattedOtras herramientas#
palettegenera bibliotecas de hilos de una marca a partir de una carta en CSV, o las de Brother y Janome (ver Módulos).export <carpeta> <entradas>…es una herramienta de auditoría: para cada entrada (.hoop, PNG o SVG) escribe los seis formatos de máquina y las puntadas del motor en JSON, para compararlos con un lector independiente.
Reglas de formato (hoop fmt)#
hoop fmt aplica un solo estilo, como gofmt: no hay opciones. Garantías:
el formateo no cambia los tokens (por lo tanto, tampoco el significado),
conserva los comentarios y es idempotente (formatear dos veces da lo
mismo).
Reglas:
- Saltos de línea: se respetan los de quien escribe. Varias líneas en blanco seguidas se reducen a una; se quitan las líneas en blanco del principio. El archivo termina con un único salto de línea.
- Sangría: 2 espacios por cada
{,(o[abierto al empezar la línea; una línea que empieza con},)o]va un nivel menos. Una continuación dentro de paréntesis queda un nivel adentro. - Espacios dentro de una línea: un espacio entre tokens, salvo:
- ninguno antes de
,,:,),],.y.., ni después de(,[,.y..(0..4,[1, 2],s.inset(1mm)); - ninguno después de un
-de signo (después de(,[,{,,,:,=o de un operador):-2mm,1mm - -2mm; - un nombre seguido de
(queda como se escribió: pegado si estaba pegado (rect(,at() y separado si estaba separado (at (x, y)); - los argumentos de un
placevan pegados a la ruta:place "x.hoop"(nombre: "ANA"); - dos tokens que, pegados, formarían otro token (
.y5mm) se separan. El resultado: un espacio alrededor de=y de los operadores, después de:y,, y alrededor de{y}.
- ninguno antes de
- Comillas: las cadenas entre comillas simples pasan a dobles, salvo que contengan una comilla doble.
- Comentarios: quedan donde están, con un espacio antes si siguen a código en la misma línea. Si en varias líneas seguidas el comentario final empezaba en la misma columna, siguen alineados entre sí (con el menor espacio que tenían).
- Alineación: en las líneas seguidas que empiezan con
threado conconst(con la misma sangría y con=), el=se alinea con espacios. Lasconstcon tipo (const x: Length = …) forman su propio grupo, aparte de las sin tipo.paramyshapeno se alinean.
Antes:
design 'Feo'{canvas:rect(size:(30mm,20mm)),fabric:Twill}
thread negro=#1c1616 "Negro"
thread amarillo = #fcd414
const ancho = 3mm
const alto: Length = 2mm
layer a{
fill amarillo{ shape :canvas.inset( 1mm ),angle:45deg }
satin negro { border: canvas, width: ancho } // borde
}Después de hoop fmt:
design "Feo" { canvas: rect(size: (30mm, 20mm)), fabric: Twill }
thread negro = #1c1616 "Negro"
thread amarillo = #fcd414
const ancho = 3mm
const alto: Length = 2mm
layer a {
fill amarillo { shape: canvas.inset(1mm), angle: 45deg }
satin negro { border: canvas, width: ancho } // borde
}Playground#
apps/playground es un editor de HoopLang que corre entero en el navegador:
el motor compilado a WebAssembly trabaja en un Web Worker, y el sitio es
estático.
cd apps/playground
npm ci
npm run wasm # el motor a WebAssembly (requiere wasm-bindgen-cli)
npm run dev # servidor de desarrollo
npm run build # dist/, sitio estáticoProyectos de varios archivos#
- Un proyecto es un conjunto de archivos
.hoopcon rutas (galeria/,bibliotecas/…), mostrado como árbol de carpetas, con pestañas. Se pueden crear, renombrar, borrar y subir archivos.hoop. Las rutas no pueden contener..y siempre terminan en.hoop. - El proyecto se guarda en el navegador (
localStorage). Empieza con los ejemplos del repositorio (galería, ejemplos y bibliotecas dedocs/lenguaje/); "Volver a los ejemplos" descarta los cambios. - Los
importyplacese resuelven entre los archivos del proyecto, relativos a la carpeta del archivo que se borda (también los de un archivo importado o colocado), con.y.., igual quehoop checkyhoop build.
Compartir, archivos del computador y galería#
- Compartir por enlace: el botón "Compartir" genera una URL sin servidor
con el proyecto entero comprimido en el fragmento
#p=…(CompressionStreamdeflate-raw+ base64url: pestañas abiertas, archivos modificados y sus dependencias transitivas deimport/place, más cuál es el diseño principal). Al abrir esa URL, el playground carga el proyecto compartido en un espacio aparte en memoria, sin pisar el proyecto guardado del usuario enlocalStorage, y muestra una barra para "Guardar como mi proyecto" o "Volver a mi proyecto". Si el enlace supera los 8 000 caracteres, avisa y ofrece descargar el.zip. - Archivos del computador:
- "Abrir archivos .hoop…" y "Abrir carpeta…" agregan archivos
.hoop(con sus subcarpetas cuando el navegador lo permite) al proyecto. - Arrastrar y soltar archivos o carpetas
.hoopsobre el editor o el árbol los incorpora al proyecto y abre el diseño. - "Descargar archivo (.hoop)" baja el archivo activo; "Descargar proyecto (.zip)" baja todos los archivos respetando su estructura de carpetas.
- "Abrir archivos .hoop…" y "Abrir carpeta…" agregan archivos
- Galería: el botón "Galería" abre una vista con tarjetas de los diseños de
docs/lenguaje/galeria. Cada tarjeta muestra la miniatura de las puntadas generada en el build con el motor real (stitch-wasm), nombre, medidas en mm, hilos, puntadas y colores; un clic abre el diseño en el editor.
Qué se borda#
El archivo que se borda es el activo si declara un design o un hoop.
Mientras se edita una biblioteca (un archivo sin design ni hoop), se
sigue mostrando el último diseño, que se recompila con los cambios.
Vista en vivo#
- Cada cambio se compila 350 ms después de dejar de escribir. Primero llega una vista inmediata (formas y errores, en milisegundos) y luego las puntadas; si las puntadas tardan más de 120 ms, mientras tanto se ven las formas. Las compilaciones no se encolan: se compila sólo lo último.
- La vista muestra el área útil del bastidor como tela con una grilla de
10 mm (en un
hoop, desde su esquina; en undesignconframe, centrada en el bordado, como la centra la máquina), los lienzos (el propio y los de cada diseño colocado), el bordado y, a elección, los saltos, las agujas y las reglas en mm. Hay zoom, arrastre de la vista, "Encuadrar" y la posición del puntero en mm. - Reglas y guías de medida (compartidas con la vista previa de VS Code):
- Las reglas superior e izquierda se adaptan al zoom (marcas cada 1, 5, 10,
50… mm) y miden en coordenadas del código (
coordenada − origin, conyhacia abajo):0en la esquina superior izquierda contop_left, en el centro del lienzo en undesignconorigin: center, y en el centro del bastidor en unhoopconorigin: center. Se muestran u ocultan con la casilla Reglas oAlt+R(se recuerda la preferencia). - Arrastrar desde una regla crea una guía horizontal o vertical con imán
a 0,5 mm y etiqueta (
x = 30 mm/y = 12.5 mm). Las guías se mueven arrastrando, se editan con doble clic y se borran arrastrándolas de vuelta a la regla o fuera de la vista. Se guardan por archivo. - La lectura en la esquina inferior derecha muestra la posición del cursor
respecto del origen (
x · y mm) y, al pasar sobre una forma, el tamaño de su caja (▢ ancho × alto mm).
- Las reglas superior e izquierda se adaptan al zoom (marcas cada 1, 5, 10,
50… mm) y miden en coordenadas del código (
- Los errores se subrayan en su línea, aparecen en el margen, en la pestaña
y en un panel de problemas (con clic para ir a la línea). Los de un
importoplacese muestran también en el archivo de origen. Con errores, se sigue viendo lo último que compiló. Los avisos de límites de máquina aparecen en el panel como "máquina".
Ida y vuelta entre código y vista#
- Clic en el bordado: el editor salta a la primitiva que lo produjo (o
al
placeque trajo ese diseño). - Cursor en el código: se resaltan en la vista los objetos de la
primitiva o
placebajo el cursor. - Arrastrar una pieza mueve su posición y reescribe el
aten el código (elat:de una primitiva comotext, o elatde unplace):- si el
ates un literal(x, y)en mm, se cambian los números, redondeados a 0.5 mm:at (40mm, 18mm)→at (52.5mm, 18mm); - si es una expresión calculada (
canvas.center,grid(i, …),p.center), no se reemplaza: se le suma un desplazamiento+ (dx, dy), también redondeado a 0.5 mm (grid(i, cols: 3, …) + (5mm, -2.5mm)). Los arrastres siguientes actualizan ese mismo desplazamiento y, si vuelve a (0, 0), se quita; - si el
atestá dentro de unfor, se mueven todas las copias; - un diseño con
fitno se arrastra (sus medidas no son los mm de la vista). Después de soltar, el compilador revisa de inmediato (un objeto llevado fuera del lienzo daE006).
- si el
Formatear y descargar#
- "Formatear" o Ctrl+S (⌘S) aplica
hoop fmtal archivo activo. - El menú de descargas baja el archivo de máquina del diseño que se borda en PES (Brother), DST (Tajima), EXP (Melco, Bernina), JEF (Janome), VP3 (Husqvarna, Pfaff) o XXX (Singer). Las descargas se desactivan mientras hay errores.
API WebAssembly#
El paquete crates/wasm expone, entre otras, estas funciones para
JavaScript:
| Función | Descripción |
|---|---|
runHoopProject(main, files, live, onProgress) | Compila y borda un proyecto. main es la ruta del archivo a compilar y files un JSON {ruta: texto} con todos los archivos. Devuelve un objeto con diags (JSON), error (texto o null), canvases (JSON: anillos en mm), frame (JSON: [ancho, alto] o null), anchored (si las coordenadas son las del bastidor) y, si compiló, pes, dst, exp, jef, vp3, xxx (bytes), xy, cmd, colors, previewSvg, needlesSvg y summary (JSON). Con live = true no genera archivos de máquina ni vistas SVG. onProgress(etapa, hechas, total) informa el avance. |
previewHoopProject(main, files) | Compila sin coser y devuelve un JSON con ok, diags y, si compiló, shapes (por objeto: color, line, col, rings y open), canvases, frame y anchored. Es la vista inmediata y la base de la ida y vuelta código ↔ vista. |
formatHoop(src) | Devuelve el texto formateado como hoop fmt, o lanza el diagnóstico como texto. |
En ambas funciones de proyecto, un archivo que no está en files se informa
como cannot read …: not found in the project (<ruta>).
Soporte de editores#
El playground (CodeMirror 6) ofrece:
- resaltado de sintaxis (palabras clave, primitivas, funciones, tipos, números con unidad, colores, cadenas y comentarios); es un modo por líneas, sin gramática completa: los errores reales los da el compilador;
- autocompletado de palabras del lenguaje, fuentes, bastidores, propiedades,
fragmentos (
design,fill,satin,text,for,if,place) y los nombres declarados en el archivo (thread,const,shape,paramy los espacios de nombres deimport); - diagnósticos del compilador en la línea, y formateo con Ctrl+S.
Servidor LSP y VS Code#
hoop-lsp es el servidor de lenguaje de HoopLang. Habla LSP por stdio y
usa el lexer, parser, verificador y formateador del compilador, sin otro
intérprete del lenguaje. Se instala desde la raíz del repositorio:
cargo install --path crates/lsp --lockedOfrece:
- errores y advertencias al abrir, cambiar y guardar, con sus códigos, severidades y posiciones convertidas de caracteres Unicode a UTF-16;
- formato de documento con el mismo resultado que
hoop fmt; - completado de declaraciones, primitivas y propiedades del bloque actual,
valores de los catálogos, nombres declarados y miembros de
import; - hover con tipos y valores evaluados, color/marca de hilos y ayuda extraída de esta referencia durante la compilación del servidor;
- ir a la definición de hilos, formas, constantes, parámetros, miembros
importados y rutas de
placeeimport.
Los archivos se cargan relativos al archivo principal, incluidas las
rutas de bibliotecas anidadas, igual que en hoop check. Las ediciones de
archivos abiertos tienen prioridad sobre el disco y actualizan los
diagnósticos de sus clientes. Las bibliotecas se verifican como bibliotecas;
los place se revisan compilando/montando, sin generar puntadas.
La extensión de VS Code está en editors/vscode. Añade resaltado TextMate,
comentarios, pares de delimitadores e ícono de .hoop, y lanza el servidor.
Para instalarla localmente (Node.js 22 o posterior):
cd editors/vscode
npm ci
npm run package
code --install-extension hooplang-0.1.0.vsixEl VSIX contiene el cliente, pero el ejecutable hoop-lsp se instala por
separado: debe estar en el PATH de VS Code o configurarse con una ruta
absoluta en hooplang.serverPath. Después de cambiarla, recarga la ventana.
Ver el README de la extensión.
En otros editores LSP, configura el comando hoop-lsp sin argumentos y con
transporte stdio. No despliega proyectos.
hoop check y hoop fmt siguen disponibles como herramientas externas.
Vista previa en VS Code#
Con un .hoop abierto, ejecuta HoopLang: Abrir vista previa, o usa el
botón de la barra del editor. El panel lateral muestra primero las formas
y después las puntadas por color, junto con medidas, puntadas, hilos,
cortes y avisos de máquina. Respeta el tema claro/oscuro del editor.
La rueda hace zoom, arrastrar desplaza, Ajustar vista encuadra y la
casilla Reglas (Alt+R) muestra u oculta las reglas en mm y las guías de
medida, que se guardan por documento en el estado del panel.
Un clic en una forma selecciona su línea; mover el cursor dentro de una
primitiva resalta la forma correspondiente, y pasar sobre una forma muestra
su posición y su caja (ancho × alto mm).
Las ediciones sin guardar, incluidos place e import, se usan igual que
en los diagnósticos. Tras unos 200 ms se pide una nueva vista; hay una sola
petición en curso y se descartan resultados de revisiones anteriores. No
exporta archivos de máquina ni permite editar formas arrastrándolas.
El LSP ofrece las peticiones propias hoop/preview y hoop/stitches, ambas
con textDocument.uri; el protocolo y las pruebas están descritos en el
README de la extensión.
API HTTP#
El servidor stitch-api (crates/api) expone HoopLang por HTTP, para usar
el lenguaje desde un backend: una tienda que pide "parche con el nombre
MARÍA" y recibe el .pes, o un editor propio. Usa el mismo compilador y el
mismo motor que hoop, el playground y VS Code.
HOOP_TEMPLATES=docs/lenguaje cargo run --release -p stitch-api
# o con Docker, desde la raíz del repositorio:
docker build -f crates/api/Dockerfile -t stitch-api .
docker run -p 8080:8080 stitch-apiEndpoints#
| Método y ruta | Qué hace | Respuesta |
|---|---|---|
POST /v1/hoop/check | Compila sin coser | { ok, name, diags } |
POST /v1/hoop/preview | Las formas, sin coser (milisegundos) | { ok, diags, shapes, canvases, frame, anchored }; cada forma con color, line, col, rings, open |
POST /v1/hoop/build | Borda | { ok, diags, summary, threads, files } |
POST /v1/hoop/format | { "src": … } con el estilo de hoop fmt | { ok, src } |
GET /v1/hoop/templates | Las plantillas del servidor | { templates: [{ template, name, params }] } |
GET /health | Para el balanceador | ok |
check, preview y build reciben el diseño de una de dos formas:
{ "main": "parche.hoop",
"files": { "parche.hoop": "…", "bibliotecas/janome.hoop": "…" },
"params": { "nombre": "MARÍA" } }{ "template": "galeria/parche", "params": { "nombre": "MARÍA" },
"formats": ["pes", "dst", "svg"] }files: el proyecto entero,{ruta: texto}.maines el archivo principal (por omisiónmain.hoop); losimportyplacese resuelven relativos a él, como en el playground.template: un.hoopguardado en la carpetaHOOP_TEMPLATESdel servidor (con o sin.hoop, puede incluir subcarpetas). Susimportyplacese leen de esa misma carpeta, sin salir de ella.params: valores para losparamdel archivo principal, como los de unplace. En JSON: texto ("ANA"), entero (3),true/false,{"mm": 12},{"cm": 1.2},{"deg": 30},{"pct": 80}o{"color": "#cc3f24"}. Unparamque el diseño no declara esE007(con sugerencia); un valor del tipo equivocado, el error del compilador.formats(sólobuild):pes,dst,exp,jef,vp3,xxx(en base64) ysvg(la vista previa, como texto). Por omisiónpesydst.summarytrae puntadas, cortes, cambios de hilo, medidas en mm, metros de hilo, minutos estimados y los avisos de máquina.
Errores#
| Estado | Cuándo | Cuerpo |
|---|---|---|
| 400 | La petición está mal armada (falta el archivo principal, formato desconocido, un param con un valor que no se entiende) | { ok: false, error } |
| 404 | La plantilla no existe, o el servidor no tiene plantillas | { ok: false, error } |
| 413 | La petición pasa HOOP_MAX_BODY_BYTES | |
| 422 | El diseño tiene errores, o más puntadas que HOOP_MAX_STITCHES | { ok: false, error, diags }, con los diagnósticos como los da el compilador (code, severity, pos, msg) |
| 504 | La compilación pasó HOOP_TIMEOUT_SECS | { ok: false, error } |
Configuración#
| Variable | Por omisión | Qué fija |
|---|---|---|
PORT | 8080 | Puerto |
HOOP_TEMPLATES | sin plantillas | Carpeta de plantillas |
HOOP_MAX_BODY_BYTES | 4 MiB | Tamaño máximo de una petición |
HOOP_TIMEOUT_SECS | 20 | Tiempo máximo de una compilación |
HOOP_MAX_STITCHES | 1 000 000 | Puntadas máximas de un diseño bordado |
HOOP_MAX_CONCURRENT | núcleos del procesador | Compilaciones a la vez (las demás esperan) |
Los límites del compilador valen siempre; estas variables permiten que un servidor público sea más estricto.
El servidor también conserva las rutas anteriores al lenguaje
(/v1/stitch, /v1/design, /v1/svg: formas en JSON o un SVG).
Pruebas de robustez#
Los tests habituales incluyen proyectos válidos generados con proptest:
compilación, determinismo y formato idempotente que conserva los valores
del motor. Se ejecutan con cargo test --workspace --release.
El workspace independiente crates/hoop/fuzz ofrece los objetivos
lex_parse, check_compile y format. Para empezar desde la raíz:
rustup toolchain install nightly --profile minimal
cargo install cargo-fuzz --locked
python3 crates/hoop/fuzz/scripts/seed_corpus.py
cargo +nightly fuzz run lex_parse --fuzz-dir crates/hoop/fuzz -- -max_total_time=1800 -dict=crates/hoop/fuzz/hoop.dictRepetir el comando con check_compile y format, al menos 30 minutos por
objetivo. Los detalles de sanitizador, límites de la campaña, reproducción
y minimización están en crates/hoop/fuzz/README.md, en el repositorio.
El compilador y el formateador diagnostican entradas que exceden sus
presupuestos de recursos con E002 (los errores de lectura siguen siendo
E007). Esto incluye tamaño del archivo, cantidad de tokens, profundidad de
sintaxis y valores, tamaño de nombres y cadenas, vértices, texto, cantidad
de objetos, trabajo acumulado de bucles y dependencias. Los valores se
centralizan en crates/hoop/src/limits.rs; MAX_LOOP sigue siendo 1000 por
bucle y se verifica antes de reservar el rango. Un desbordamiento entero
también es E002, igual en debug y release. No se cambian densidades,
subcapas ni recorridos para hacer pasar una entrada excesiva.
Véase también#
- Diagnósticos: formato y códigos.
- Bastidor:
hoop,placey el origen de los archivos de máquina. - Módulos: rutas de
importyplace.
Ejemplos de documentación como pruebas#
cargo test --release -p stitch-tools --test docs recorre todos los Markdown
bajo docs/hooplang/. Compila cada bloque hoop y compara las salidas
text/sh inmediatamente adyacentes que contienen resultados del CLI.
Comprueba posición, código y mensaje; en build, medidas e hilos exactos y
puntadas con tolerancia del 2 %. No compara tiempos ni exige cortes exactos.
Los fragmentos usan un único contexto didáctico definido en el test, con un
lienzo amplio, hilos negro/blanco/rojo/azul/oro/amarillo y nombres de formas y
constantes usados en el libro. Las declaraciones del bloque prevalecen.
Los archivos completos no se envuelven. Las dependencias se buscan primero
en archivos mostrados en la página, después en docs/lenguaje/ y finalmente
en archivos identificados en otras páginas.
Marcas al principio de un bloque (se eliminan antes de compilar):
// error E003: debe fallar con ese código, sin otros errores. Puede enumerar varios códigos si el ejemplo los muestra intencionalmente.// no-check Motivo: sólo para plantillas incompletas; el test enumera todas las exclusiones para que no pasen inadvertidas.// file: lib/colores.hoop: identifica un archivo mostrado en la página para que los otros ejemplos puedan importarlo o colocarlo.
El fallo indica archivo Markdown, línea de la cerca y diferencias concretas.
Los comentarios de metadatos no desplazan las posiciones del archivo .hoop.
Simulador del bordado#
hoop build escribe además un PNG de hilo sobre tela a partir de las
puntadas reales cuantizadas, en su orden y posición. El diámetro inicial es
0,40 mm: si hay huecos entre filas, se ven. Los saltos sin cortar también
se ven por defecto. No simula fruncido ni corrige defectos del plan.
La API acepta formats: ["png"] y opciones
png: {width: 1000, height: 600, rulers: true}; las reglas, en mm, parten
del origen del código, también con origin: center. Se pueden elegir
fabric (twill, pique, fleece), fabric_color, thread_mm y ocultar
saltos explícitamente con hide_jumps (false por defecto).
En VS Code, HoopLang: Abrir vista previa muestra la misma imagen y tiene un control mínimo Reproducir/Pausar con tiempo estimado. Conserva clic al código y resaltado de formas. El reproductor completo es un trabajo aparte.
Todas estas vistas usan stitch-render, sin E/S. WASM ofrece
renderStitches y StitchRenderer incremental: cada cuadro dibuja sólo
los nuevos comandos. Los parámetros visuales son valores iniciales que
se calibrarán con fotos reales. La API, los valores y las pruebas se
documentan en crates/render/README.md.