STXT - Semantic Text
Built for humans. Reliable for machines.

Preguntas frecuentes

Respuestas cortas a las dudas que aparecen al empezar con STXT. Cada respuesta enlaza a la sección de la referencia que la fija; ante cualquier discrepancia, manda la referencia.

El lenguaje

¿Por qué no YAML, JSON o TOML?

Porque resuelven otro problema. JSON y TOML están pensados para datos; YAML intenta cubrir datos y texto y paga por ello con una gramática enorme y sorpresas conocidas (NO que se convierte en falso, indentación con anchos variables, anclas, tags que instancian objetos). STXT está pensado para documentos: cosas que una persona escribe y lee, con estructura y con párrafos de texto libre mezclados.

Lo que lo distingue:

Cuando lo que tienes son datos para que los lea otra máquina, JSON sigue siendo una buena elección; y de hecho todo documento STXT tiene una representación JSON canónica (ver ¿Cómo lo convierto a JSON?).

¿Es un formato de datos o de documentos?

Las dos cosas, porque la línea entre ambas es artificial: un email tiene campos y un cuerpo, un contrato tiene cláusulas y metadatos, una configuración tiene valores y comentarios largos. STXT es un árbol de nodos con nombre; cada nodo lleva o bien un valor y unos hijos, o bien un bloque de texto. Con eso se describe tanto una ficha de datos como un documento de veinte páginas. Los casos de uso recorren ese abanico.

¿Qué extensión y qué media type uso?

Extensión .stxt; media type text/stxt, y text/plain como alternativa compatible. Codificación UTF-8 sin BOM, finales de línea LF (se acepta CRLF). Ver STXT-SPEC §3 y §13.

Escribir documentos

¿Tabuladores o espacios?

Los dos valen, y significan lo mismo: un tabulador es un nivel, cuatro espacios son un nivel. Lo que no vale es mezclarlos en la indentación de una misma línea (error MIXED_INDENTATION), ni usar otro ancho (dos espacios no son medio nivel: son un error). Líneas distintas de un documento pueden usar estilos distintos, pero por estilo conviene elegir uno; stxt format --tabs o --spaces lo unifican.

El ancho fijo es deliberado: el nivel de una línea se calcula mirando solo esa línea, y la jerarquía se ve igual en cualquier editor. Quien prefiera una indentación más compacta usa tabuladores y ajusta el ancho de tabulador de su editor. Ver STXT-SPEC §8.1.

¿Importan las mayúsculas, los acentos y los espacios en los nombres?

Los nombres se comparan por su nombre canónico: minúsculas, y toda secuencia de espacios, guiones y guiones bajos reducida a un solo guion. Los acentos y las letras no latinas se conservan. Así:

Los namespaces son más estrictos: solo ASCII [a-z0-9] y puntos, al menos a.b, y se pasan a minúsculas. Ver STXT-SPEC §4.3 y §7.

¿Cómo escribo un valor con dos puntos o almohadilla dentro?

Tal cual. En un nodo inline el valor es todo lo que hay después del primer :, así que Hora: 10:30 vale 10:30, y # solo abre un comentario cuando es el primer carácter de la línea. En un bloque >> no hay que pensar nada: es texto literal.

Cita: 10:30 en la sala 2 # esto forma parte del valor
Notas >>
	# esto también es texto, no un comentario
	Clave: valor >> tampoco es un nodo

¿Puede un documento tener varios nodos raíz?

Sí. Un fichero puede contener varios nodos de nivel 0, cada uno con su árbol, y las herramientas los devuelven en orden. Es lo que permite parsear en streaming ficheros grandes: cada raíz se emite completa en cuanto empieza la siguiente. Los namespaces no se heredan lateralmente entre raíces: cada una declara el suyo. Ver STXT-SPEC §8.5.

¿Y los comentarios?

Una línea cuyo primer carácter no blanco es # es un comentario, y no cuenta para la indentación: ni un comentario ni una línea vacía pueden provocar un error de nivel. Dentro de un bloque >>, una línea con # más indentada que el nodo es texto del bloque; una menos o igual de indentada es un comentario y no cierra el bloque. Ver STXT-SPEC §9.

¿Qué pasa con los comentarios al formatear?

Se conservan. stxt format (y el Format Document de la extensión de VS Code) reescribe solo las líneas que abren un nodo; comentarios, líneas en blanco y el contenido de los bloques quedan como están, salvo el espacio final de línea. Perder comentarios exige un flag explícito, --clean, que reserializa el árbol y descarta todo lo que el árbol no describe. Ninguna herramienta del ecosistema reescribe un fichero sin que se lo pidas (--write).

Esquemas y plantillas

¿Los esquemas son obligatorios?

No. Un documento sin namespace se parsea y punto. Si tiene namespace y en su cadena de resolución no hay ninguna definición, las herramientas solo parsean: no está mal, es que no se puede validar. La validación se activa cuando hay definiciones cerca (un directorio .stxt/), y entonces sí cuenta: un documento con un namespace para el que no hay definición se señala con SCHEMA_NOT_FOUND, porque casi siempre es un namespace mal escrito. En la CLI, --warn-schema lo rebaja a aviso y --no-schema desactiva la validación del todo.

¿Esquema o plantilla?

Son dos sintaxis para el mismo modelo, y toda plantilla equivale a un esquema. La plantilla (@stxt.template) se escribe como el documento que describe, con la cardinalidad y el tipo entre paréntesis, y es la forma recomendada para escribir a mano:

Template (@stxt.template): com.example.docs
	Structure >>
		Email (com.example.docs):
			From: EMAIL
			To: (+) EMAIL
			Subject: (?)
			Body: (1) TEXT

El esquema (@stxt.schema) es la forma explícita, con Node, Children, Child, Min/Max y Type; es lo que se genera y lo que se procesa. Si dudas, plantilla. Ver STXT-TEMPLATE-SPEC y STXT-SCHEMA-SPEC.

¿Dónde pongo los esquemas y plantillas?

En un directorio llamado .stxt/ en el proyecto: se cargan todos los .stxt que haya dentro, recursivamente, sin que importen los nombres de fichero ni los subdirectorios. La cadena de resolución de un documento son todos los .stxt/ de sus directorios ascendentes, luego ~/.stxt y por último /etc/stxt (en Windows, %USERPROFILE%\.stxt y %ProgramData%\stxt). Gana el nivel más cercano, namespace a namespace. La variable STXT_PATH sustituye la cadena entera por una lista de directorios, útil en CI.

stxt install fichero.stxt deja una definición en su sitio y stxt schemas enseña qué aplica en un directorio y de dónde sale. El recorrido completo, con ejemplo, está en El entorno de trabajo; la norma, en STXT-DISCOVERY-SPEC.

¿Qué pasa si escribo Titel en vez de Title?

Que el validador se queja (CHILD_NOT_DECLARED). El modelo de contenido es cerrado: un nodo solo admite los hijos que su definición declara, y si no declara ninguno, no admite ninguno. Es la razón de ser de validar: fallar de forma ruidosa en vez de aceptar en silencio. Ver STXT-SCHEMA-SPEC §6.

¿Se valida el orden de los hijos?

No. Se valida cuántas veces aparece cada hijo, no en qué posición: dos documentos con los mismos hijos en distinto orden validan igual. El orden se conserva en el árbol, así que una aplicación que le dé significado lo obtiene del árbol, no del validador. Tampoco hay expresiones regulares, valores por defecto ni reglas condicionales entre campos: son no-objetivos declarados. Ver STXT-SCHEMA-SPEC §11.

¿Cómo evoluciono un esquema sin romper documentos?

Como el modelo es cerrado, añadir un nodo rompe la validación de los documentos que usen la definición antigua. La práctica recomendada es versionar el namespace (com.example.docs.v1com.example.docs.v2): cada versión tiene su definición y cada documento declara la que usa.

Herramientas

¿Cómo valido en CI?

Con la línea de comandos, sin instalar nada de forma permanente:

npx @stxt-lang/cli validate --recursive docs/
npx @stxt-lang/cli format --check --recursive docs/

El código de salida es 1 si algún documento no pasa y 2 si la llamada está mal, así que el trabajo falla solo. --format json da la salida para máquinas. Y si el entorno de CI no debe depender de lo que haya en ~/.stxt o /etc/stxt, STXT_PATH=./.stxt fija la cadena de resolución. Los detalles, en Herramientas.

¿Cómo lo convierto a JSON?

Todo documento válido tiene un árbol canónico en JSON, definido en STXT-TREE-SPEC: un array de raíces con name, canonicalName, namespace, y value más children (inline) o lines (bloque). stxt describe fichero.stxt lo imprime, y las tres bibliotecas lo exponen desde su API. No incluye posiciones ni comentarios: es el contenido lógico, el mismo en todas las implementaciones.

¿En qué lenguajes hay parser?

TypeScript/JavaScript (@stxt-lang/core), Java (dev.stxt:stxt-core) y Python (stxt), con el mismo alcance, la misma versión y el mismo corpus de conformidad. Sobre el primero corren la extensión de VS Code, la CLI y el playground. Todo está en la página Herramientas; y para probar sin instalar nada, play.stxt.dev.