STXT Template

Estado:
Aurora
última modificación:
2026-09-07

1. Introducción

Este documento es STXT-TEMPLATE-SPEC; las demás especificaciones lo citan con ese nombre.

Este documento define la especificación del lenguaje STXT Template, un mecanismo para describir reglas semánticas (estructura, tipos, cardinalidades y valores permitidos) aplicables a documentos STXT.

Un template:

  • Es un documento STXT cuyo namespace es @stxt.template.
  • Se asocia a un namespace objetivo, de forma análoga a un schema.
  • Describe la estructura esperada mediante un bloque Structure >> con sintaxis simplificada.
  • Puede compilarse a un documento @stxt.schema semánticamente equivalente dentro del subconjunto expresable por templates.

Relación con @stxt.schema:

  • Una implementación PUEDE soportar sólo schemas, sólo templates, o ambos.
  • Si existen ambos (schema y template) para el mismo namespace objetivo, una implementación conforme DEBERÍA establecer un criterio consistente de priorización. Cuando las definiciones se descubren en el sistema de ficheros, ese criterio queda fijado por STXT-DISCOVERY-SPEC: gana la definición del nivel más cercano, y dos definiciones en el mismo nivel son un error.
  • Para una validación concreta, una implementación DEBE usar una única fuente semántica efectiva: o bien schema, o bien template.
  • STXT core NO DEBE imponer semántica: los templates son una capa opcional, posterior al parseo del documento STXT.

1.1 Versión de esta especificación

Esta especificación lleva su propia fecha y su propio estado en los campos Last modif y Status de su Metadata, independientes de los de las demás especificaciones de STXT y con el significado que fija STXT-SPEC §1.1. Está en Aurora. Depende de STXT-SCHEMA-SPEC: toda plantilla se compila a un schema equivalente.

2. Terminología

Las palabras clave "DEBE", "NO DEBE", "DEBERÍA", "NO DEBERÍA", y "PUEDE" deben interpretarse según RFC 2119 y RFC 8174: tienen ese significado únicamente cuando aparecen en mayúsculas, como aquí.

Términos como nodo, indentación, namespace, inline y bloque >> mantienen su significado en STXT-SPEC.

Definiciones adicionales:

  • Namespace objetivo: el namespace STXT al que aplica el template (por ejemplo com.example.docs).
  • Plantilla de nodo: una entrada dentro del bloque Structure >> que define un nodo (y opcionalmente su tipo/cardinalidad y sus hijos).
  • Tipo: una etiqueta semántica de validación (por ejemplo TEXT, DATE, ENUM) equivalente a los tipos de STXT Schema.
  • Cardinalidad: regla que define cuántas veces puede aparecer un nodo hijo respecto a su padre.

3. Relación entre STXT y Template

La validación mediante templates ocurre después del parseo STXT:

  1. Parseo del documento STXT a estructura jerárquica.
  2. Resolución del namespace efectivo de cada nodo.
  3. Selección del template correspondiente al namespace objetivo.
  4. Aplicación de reglas del template (estructura, cardinalidad, tipos, valores).

Una implementación PUEDE aplicar reglas durante el parseo, siempre que esta validación permanezca débilmente acoplada al parser base.

4. Estructura general de un Template

Un documento template DEBE tener como nodo raíz:

Template (@stxt.template): <namespace_objetivo>

El template DEBE contener exactamente un nodo Structure en forma de bloque (>>).

Template (@stxt.template): com.example.docs
	Structure >>
		Document (com.example.docs):
			Title: (1)
			Body: (1) TEXT
	Description >>
		Document: Documento básico con título y cuerpo

Reglas:

  • El nodo raíz Template DEBE pertenecer al namespace @stxt.template.
  • <namespace_objetivo> DEBE ser un namespace válido según STXT-SPEC (sección de namespaces).
  • El documento template PUEDE incluir como máximo un nodo Description, con descripciones por nodo (sección 12).
  • Sólo puede existir un template efectivo por namespace objetivo en una validación concreta (ver sección 5).

5. Un template por namespace objetivo

Para cada namespace lógico:

  • NO DEBE existir más de un template efectivo simultáneamente.
  • Si existen varios templates candidatos para el mismo namespace, la implementación DEBERÍA tener un criterio claro, estable y determinista para decidir cuál aplica.
  • Para una validación concreta, una implementación NO DEBE aplicar varios templates a la vez sobre el mismo namespace objetivo.

6. Bloque Structure >>

El bloque Structure >> define un árbol de plantillas de nodos usando indentación, donde:

  • Cada línea no vacía define una plantilla de nodo.
  • La indentación define nodos hijos (igual que STXT), pero dentro de Structure >> no se está describiendo un documento de datos, sino una estructura esperada.
  • Las reglas de indentación del documento STXT base aplican al documento template fuera del bloque.
  • El contenido de Structure >> se interpreta mediante la gramática de templates definida en este documento.
  • La jerarquía dentro de Structure >> DEBE construirse con el mismo modelo de indentación consecutiva que en STXT-SPEC.

Nivel superior y nodos definidos. Las líneas de nivel superior de Structure no tienen semántica especial de "raíz": son plantillas de nodo como cualquier otra, y su anidamiento define sus hijos. Cada línea de Structure (a cualquier nivel) define o referencia un nodo del namespace correspondiente, exactamente igual que un Node en un schema.

6.1 Convención de estilo recomendada

Por legibilidad, se recomienda:

  • 1 tabulador por nivel.
  • Un solo espacio entre componentes.
  • Mantener consistencia en nombres (usar las mismas mayúsculas/diacríticos que en documentos reales).

6.2 Sintaxis de una línea de Structure

Cada línea del bloque Structure >> tiene la forma:

<NodeName> [<NamespaceOverride>] ":" [<RuleSpec>]

donde:

  • <NodeName> es el nombre del nodo (texto humano; se normaliza según STXT-SPEC, sección 4.3, para comparación).
  • <NamespaceOverride> es opcional y tiene la forma (<namespace>) o (@namespace.especial) y define el namespace efectivo de ese nodo plantilla.
  • ":" es obligatorio. No lo exige el core (el contenido de un bloque >> es texto opaco para él), sino la gramática de templates, por coherencia visual con la sintaxis STXT.
  • <RuleSpec> es opcional e incluye, en este orden lógico:
    1. Cardinalidad opcional (entre paréntesis).
    2. Referencia opcional a un nodo mediante @Nombre Nodo, o alternativamente un tipo.
    3. Valores opcionales si el tipo es ENUM.

Ejemplos:

Title:
Title: (1)
Body: (1) TEXT
Color: (?) ENUM [red, green, blue]
Body Content: (?) @Body Content
Metadata (org.example.meta): (0,1)

Notas:

  • Si <RuleSpec> se omite por completo, se asume cardinalidad por defecto y tipo por defecto (sección 7 y 8).
  • Un nodo plantilla puede tener hijos si su tipo efectivo los admite. El tipo por defecto INLINE admite hijos. Los tipos que prohíben hijos se definen en la sección 8.
  • Una referencia @Nombre Nodo NO DEBE combinarse con un tipo explícito en la misma línea.

6.3 Reglas de parsing del Structure >>

Un parser de templates DEBE:

  1. Leer el bloque Structure >> como una secuencia de líneas ya canonicalizadas por STXT core: nivel de bloque eliminado y trim derecha por línea (STXT-SPEC, sección 10.2).

  2. Ignorar líneas vacías.

  3. Calcular jerarquía por indentación aplicando las reglas de STXT-SPEC (sección 8): en cada línea, solo tabs (1 tab = 1 nivel) o solo espacios en múltiplos de 4, sin mezcla en una misma línea, y con niveles consecutivos, sin saltos.

  4. Para cada línea, parsear:

    • Nombre del nodo + namespace opcional (ns) si existe.
    • El carácter : obligatorio.
    • La especificación de reglas opcional (RuleSpec).
  5. Resolver el namespace efectivo de cada línea.

  6. Resolver referencias @Nombre Nodo según la sección 6.4.

Un parser de templates DEBE fallar si una línea no contiene :.

6.4 Definición, referencia y recursión

Las plantillas distinguen entre:

  • Definición local de nodo: aparición de un nodo cuyo namespace efectivo pertenece al namespace objetivo del template, con su RuleSpec completo (tipo, valores, hijos).
  • Referencia local de nodo: reutilización de una definición local mediante @Nombre Nodo.
  • Referencia externa: aparición de un nodo cuyo namespace efectivo pertenece a otro namespace.

Reglas de definición y referencia:

  • Un nodo local NO DEBE definirse más de una vez por par nombre canónico + namespace efectivo.
  • Si un nodo local vuelve a aparecer en otra parte de Structure, DEBE hacerse mediante referencia @Nombre Nodo.
  • Una referencia @Nombre Nodo PUEDE sobrescribir la cardinalidad, pero NO DEBE redefinir tipo, valores ENUM ni hijos.
  • El nombre canónico de la línea y el nombre canónico de la referencia @Nombre Nodo DEBEN coincidir. Una referencia con nombre distinto al de su línea DEBE provocar un error de template (no existe el renombrado: @ marca "reaparición del mismo nodo", no "puntero a otro").
  • Los nodos de otros namespaces NO DEBEN definirse localmente dentro del template actual.
  • Un nodo externo PUEDE aparecer varias veces, pero en esa línea NO DEBE declararse nada más que la cardinalidad (ver sección 10).

Recursión. Una referencia @Nombre Nodo DEBE apuntar a:

  • una definición local previa (ya cerrada) del mismo template, o
  • un nodo ancestro cuya definición esté abierta en ese punto, incluido el propio nodo que se está definiendo.

Esta segunda opción habilita estructuras recursivas: un nodo puede declararse como hijo de sí mismo o de un ancestro. Para resolver la referencia sólo se necesita la identidad del nodo (nombre + namespace + tipo), que ya está disponible en su línea de definición; no es necesario que su lista de hijos esté completa.

Como escribir Structure equivale a recorrer en profundidad el grafo de nodos, esta regla cubre todo grafo de dependencias: auto-recursión, recursión a través de ancestros y recursión mutua.

Ejemplo (auto-recursión):

Template (@stxt.template): com.example.doc
	Structure >>
		Documento (com.example.doc):
			Título: (1)
			Sección: (*)
				Título: (1) @Título
				Texto: (?) TEXT
				Sección: (*) @Sección

En este ejemplo, la última línea, Sección: (*) @Sección, declara Sección como hijo de sí misma, referenciando al ancestro Sección cuya definición está abierta. Título: (1) @Título reutiliza la definición local previa de Título.

Ejemplo (recursión mutua A/B):

Template (@stxt.template): com.example.tree
	Structure >>
		A (com.example.tree):
			B: (*)
				A: (?) @A

7. Cardinalidades

La cardinalidad se aplica por instancia del nodo padre, contando sólo hijos directos que coincidan por:

La cardinalidad se expresa como un token opcional entre paréntesis: ( ... ). Es independiente del orden de los hijos (cuenta apariciones, no posiciones).

7.1 Formas permitidas

Formas permitidas:

Forma Significado
num Exactamente num.
* Cualquier número (0..∞).
+ Una o más (1..∞).
? Cero o una (0..1).
num+ num o más (num..∞).
num- Hasta num (0..num).
min,max Entre min y max.

Reglas:

  • num, min y max DEBEN ser enteros no negativos y NO DEBEN superar 4294967295 (2³² − 1), la misma cota que Min/Max en un schema (STXT-SCHEMA-SPEC §10); un valor mayor es CARDINALITY_NOT_VALID.
  • En min,max, DEBE cumplirse min <= max.
  • + equivale a 1+.
  • ? equivale a 0,1.
  • La cardinalidad por defecto, si se omite, es *.

7.2 Cardinalidad por defecto

Si no se especifica cardinalidad, el valor por defecto es:

  • * (cualquier número).

8. Tipos

Los tipos en templates reutilizan el conjunto de tipos de STXT Schema, con la misma intención: validar forma del valor y, opcionalmente, su contenido.

El tipo se especifica como una palabra tras la cardinalidad (si existe).

Ejemplos:

Fecha: (1) DATE
Cuerpo: (1) TEXT
Es Público: (1) BOOLEAN

Reglas generales:

  • El tipo explícito DEBE coincidir exactamente con uno de los tipos soportados por la implementación.
  • El tipo DEBE escribirse en mayúsculas (DATE, no date): la comparación es exacta y CASE-SENSITIVE.
  • Si una línea usa referencia @Nombre Nodo, NO DEBE declarar además un tipo explícito.
  • Las reglas semánticas de tipos INLINE, GROUP, BLOCK, TEXT, ENUM, NUMBER, DATE, etc. DEBEN ser coherentes con las definidas en STXT-SCHEMA-SPEC.

8.1 Tipo por defecto

Si se omite el tipo, el tipo por defecto es:

  • INLINE

8.2 Compatibilidad con hijos

La regla de compatibilidad con hijos es la misma que en STXT-SCHEMA-SPEC (sección 9):

Sólo los tipos INLINE y GROUP admiten hijos. Todos los demás tipos son hojas.

Por tanto:

  • Si un nodo plantilla declara hijos en Structure >>, su tipo efectivo DEBE ser INLINE o GROUP. En caso contrario, el template DEBE considerarse inválido.
  • El tipo por defecto INLINE admite hijos, de modo que un nodo sin tipo explícito puede tener hijos.
  • Cualquier tipo con validación de contenido (BLOCK, TEXT, NUMBER, BOOLEAN, DATE, ENUM, BASE64, etc.) NO admite hijos.

8.3 Conjunto de tipos

El conjunto de tipos es el de STXT-SCHEMA-SPEC, con los mismos niveles de soporte:

  • Una implementación de templates DEBE admitir todos los tipos definidos en STXT-SCHEMA-SPEC (sección 9, incluido MARKDOWN).
  • La exigencia de validación de cada grupo es la misma que allí: DEBE validar los tipos estructurales y los básicos de contenido, DEBERÍA validar los ampliados y PUEDE validar los binarios.

9. ENUM y lista de valores

Si el tipo es ENUM, el template DEBE declarar una lista de valores permitidos, con al menos un valor.

La lista de valores se especifica con corchetes [...] tras el tipo:

ENUM [valor1, valor2, valor3]

Color: (1) ENUM [red, green, blue]

Reglas:

  • Si el tipo es ENUM, la lista de valores DEBE existir para que tenga un contenido válido.
  • Si el tipo NO es ENUM, una lista [...] DEBE considerarse error de template.
  • Los valores se separan por comas ,.
  • Se aplica trim (espacios/tab) alrededor de cada valor.
  • La comparación de valores DEBE hacerse sobre el valor inline ya normalizado mediante trim izquierda/derecha.
  • La comparación de valores DEBE ser exacta y CASE-SENSITIVE.
  • La comparación NO DEBE aplicar canonización adicional, eliminación de diacríticos ni normalización equivalente al nombre canónico de nodos.
  • Debe existir al menos un valor en la lista.
  • Los valores NO DEBEN repetirse tras aplicar el trim de normalización.

9.1 Limitación de la sintaxis de lista

Por la forma de la sintaxis [a, b, c], un valor ENUM declarado en un template NO PUEDE contener una coma , (separador de valores) ni un corchete de cierre ] (fin de lista). Tampoco conserva espacios al inicio o final, que el trim elimina.

Esta es una limitación del subconjunto expresable por templates. Si se necesitan valores ENUM con comas, corchetes o espacios significativos, debe usarse un schema (@stxt.schema), cuyos nodos Value admiten cualquier valor inline.

10. Namespaces dentro de Structure

Cada línea puede incluir un namespace explícito para el nodo plantilla:

Metadata (org.example.meta): (?)

Reglas:

  • Si una línea de Structure omite namespace explícito, hereda el namespace efectivo de su padre.
  • Si el nodo no tiene padre dentro de Structure, el namespace por defecto es el namespace objetivo del template.
  • La herencia de namespace funciona como en documentos STXT de datos.
  • Si se especifica (otro.ns), ese nodo plantilla pertenece a ese otro namespace.
  • Si se especifica (otro.ns) y ese namespace es distinto del namespace objetivo, la línea NO DEBE definir hijos, tipo explícito ni valores ENUM; sólo PUEDE declarar cardinalidad.

11. Reglas de "nodos definidos"

En templates, un nodo queda definido por su aparición en Structure. A diferencia de Schema, no existe una sección Node: separada; la propia estructura es la definición.

Reglas:

  • Todo nodo local definido en Structure pasa a formar parte del conjunto de nodos del template.
  • Si un template referencia nodos cross-namespace, un sistema de validación completo DEBERÍA disponer de template o schema correspondiente para ese namespace externo si desea validar profundamente esos nodos.
  • Una implementación PUEDE validar sólo cardinalidad y estructura del namespace objetivo, tratando nodos cross-namespace como "caja negra", según configuración.

12. Descripciones por nodo (Description)

Un template PUEDE incluir un nodo Description, y como máximo uno, en forma inline (:) o de bloque (>>).

Su contenido no es texto libre que describa el template: es un documento STXT cuyos nodos raíz son entradas de descripción. Cada entrada asocia una descripción a un nodo definido en Structure:

  • Nombre Nodo: descripción — entrada inline, para descripciones de una línea.
  • Nombre Nodo >> con la descripción en su bloque de texto — entrada de bloque, para descripciones de varias líneas.

La correspondencia entre una entrada y su nodo de Structure se hace por nombre canónico (STXT-SPEC, sección 4.3). El orden de las entradas es libre: no tiene que seguir el orden de Structure.

Es la misma información que un schema expresa con el nodo Description de cada Node (STXT-SCHEMA-SPEC, sección 7.1); el template la agrupa en un único bloque porque su sintaxis de línea no admite descripciones. Los editores PUEDEN usar estas descripciones, por ejemplo, como ayuda contextual (hover) sobre los nodos de un documento.

Reglas:

  • El contenido de Description DEBE ser STXT válido: si no parsea, el template es inválido.
  • Cada entrada DEBE corresponder, por nombre canónico, a un nodo definido en Structure. Una entrada cuyo nombre no corresponde a ningún nodo definido DEBE provocar un error de template.
  • Una entrada NO DEBE tener hijos estructurados: sólo admite valor inline o bloque de texto.
  • Una entrada NO DEBE declarar un namespace distinto del namespace objetivo del template: los nodos cross-namespace se documentan en el template o schema de su propio namespace.
  • NO DEBE haber más de una entrada para el mismo nodo.

Ejemplo (entrada inline corta y entrada de bloque multilínea):

Template (@stxt.template): org.example.tomcat
	Structure >>
		Server (org.example.tomcat):
			Port: (1) INTEGER
			Shutdown command: (?)
	Description >>
		Port: Puerto TCP en el que escucha el servidor
		Server >>
			Nodo raíz de la configuración del servidor:
			agrupa puertos, comandos y servicios.

13. Compilación a Schema (equivalencia semántica)

Un template puede compilarse a un schema equivalente:

  • Cada nodo local definido en Structure genera una definición Node (en el namespace correspondiente).
  • La jerarquía de indentación en Structure genera Children/Child en el schema.
  • La cardinalidad ( ... ) en el template se traduce a Min / Max en el schema.
  • El tipo se copia a Type.
  • ENUM [a,b] se traduce a Values/Value.
  • Una referencia @Nombre Nodo reutiliza la definición ya generada para ese nodo local y sólo modifica la cardinalidad del Child correspondiente. La recursión (auto-referencia o ancestro abierto) se traduce a un Child que apunta al mismo Node.
  • Un nodo cross-namespace sólo genera una referencia Child; su definición corresponde al template o schema de ese otro namespace.
  • Cada entrada de Description (sección 12) se traduce al nodo Description del Node correspondiente del schema compilado.

Reglas de traducción de cardinalidad:

  • (num)Min=num, Max=num
  • (*) → sin Min, sin Max
  • (+)Min=1
  • (?)Max=1
  • (num+)Min=num
  • (num-)Max=num
  • (min,max)Min=min, Max=max

14. Errores de Template

Un template es inválido si ocurre cualquiera de estas condiciones:

  1. La indentación interna de Structure >> no cumple las reglas de indentación de STXT-SPEC, sección 8 (mezcla de tabs y espacios en una misma línea, niveles no consecutivos, espacios que no son múltiplos de 4, etc.).
  2. El documento no tiene raíz Template (@stxt.template): <namespace_objetivo>.
  3. Falta Structure >> o Structure no es bloque >>.
  4. Una línea no vacía dentro de Structure no contiene :.
  5. Cardinalidad mal formada o con números inválidos (no enteros no negativos, o mayores que 4294967295, sección 7.1).
  6. Tipo desconocido (según el conjunto de tipos soportado por la implementación).
  7. Tipo ENUM sin lista de valores [...], o con una lista vacía.
  8. Uso de [...] si el tipo no es ENUM.
  9. Un nodo con hijos tiene un tipo efectivo que no admite hijos (es decir, distinto de INLINE o GROUP).
  10. Redefinir un nodo local que ya ha aparecido previamente sin usar referencia @Nombre Nodo.
  11. Usar una referencia @Nombre Nodo que no apunta a una definición local previa ni a un ancestro abierto.
  12. El nombre de una referencia @Nombre Nodo no coincide (en nombre canónico) con el nombre de su línea.
  13. Declarar a la vez referencia @Nombre Nodo y tipo explícito en la misma línea.
  14. Declarar valores ENUM duplicados tras la normalización por trim, o vacíos ([a, , b], [a, b,]).
  15. Definir hijos, tipo explícito o valores ENUM en un nodo cross-namespace.
  16. El contenido de Description no es un documento STXT válido.
  17. Una entrada de Description no corresponde, por nombre canónico, a ningún nodo definido en Structure.
  18. Una entrada de Description tiene hijos estructurados.
  19. Una entrada de Description declara un namespace distinto del namespace objetivo del template.
  20. Más de una entrada de Description para el mismo nodo.
  21. Una referencia @Nombre Nodo declara hijos: la estructura la fija la definición referenciada.
  22. Una referencia @Nombre Nodo declara valores ENUM.

La validación de un documento frente a un template es, por definición, la validación frente al schema compilado equivalente (sección 13): las condiciones de invalidez de un documento son las definidas en STXT-SCHEMA-SPEC, sección 13.

14.1 Códigos de error

Como en STXT-SPEC §11.1, cada error lleva un código estable e idéntico en todas las implementaciones, y no se renombra. Los números remiten a las condiciones de la lista anterior. Un documento de plantilla se valida primero como documento contra la meta-plantilla de la sección 16, así que sus errores de forma (una raíz que no es Template, un Structure ausente o escrito en línea) llegan con los códigos de STXT-SCHEMA-SPEC §13.1; las reglas de esta sección se aplican después.

Código Condición
códigos INDENTATION_* de STXT-SPEC 1: indentación de Structure >>
TEMPLATE_ROOT_NOT_VALID 2: la raíz no es Template (@stxt.template): …, o el namespace objetivo no es válido
TEMPLATE_NAMESPACE_EMPTY 2: el namespace objetivo está vacío
TEMPLATE_MULTIPLE_ROOTS el documento template tiene más de un nodo raíz, o ninguno
TEMPLATE_STRUCTURE_REQUIRED 3: falta Structure >> o no es bloque
STRUCTURE_LINE_NOT_VALID 4: línea de Structure escrita en forma >>, o cuya parte de regla no sigue la sección 6.2 (por ejemplo un paréntesis sin cerrar); una línea sin : ni >> la rechaza ya el núcleo con INVALID_LINE (STXT-SPEC §11.1), en la línea de la plantilla
CARDINALITY_NOT_VALID 5: cardinalidad mal formada o con números inválidos
MIN_GREATER_THAN_MAX 5: (min,max) con min mayor que max
TYPE_NOT_VALID 6: tipo desconocido
VALUES_REQUIRED 7: ENUM sin [...] o con lista vacía
VALUES_NOT_ALLOWED_FOR_TYPE 8: [...] en un tipo distinto de ENUM
CHILDREN_NOT_ALLOWED_FOR_TYPE 9: hijos bajo un tipo que no los admite
REFERENCE_REQUIRED 10: segunda aparición de un nodo local sin @
REFERENCE_NOT_FOUND 11: @Nombre Nodo sin definición previa ni ancestro abierto
REFERENCE_NAME_NOT_VALID 12: el nombre tras @ no coincide con el de la línea
REFERENCE_WITH_TYPE_NOT_ALLOWED 13: referencia y tipo explícito en la misma línea
CHILDREN_NOT_ALLOWED_IN_REFERENCE 21: una referencia @Nombre Nodo declara hijos
VALUES_NOT_ALLOWED_IN_REFERENCE 22: una referencia @Nombre Nodo declara valores ENUM
VALUE_DUPLICATED 14: valores ENUM repetidos
VALUE_EMPTY 14: un valor ENUM vacío en la lista
CHILDREN_NOT_ALLOWED_IN_EXTERNAL_NAMESPACE 15: hijos en un nodo cross-namespace
TYPE_NOT_ALLOWED_IN_EXTERNAL_NAMESPACE 15: tipo explícito en un nodo cross-namespace
VALUES_NOT_ALLOWED_IN_EXTERNAL_NAMESPACE 15: valores ENUM en un nodo cross-namespace
códigos de STXT-SPEC §11.1 16: el contenido de Description no parsea
DESCRIPTION_NODE_NOT_FOUND 17: entrada de Description sin nodo en Structure
DESCRIPTION_CHILDREN_NOT_ALLOWED 18: entrada de Description con hijos
DESCRIPTION_NOT_ALLOWED_IN_EXTERNAL_NAMESPACE 19: entrada de Description con otro namespace
DESCRIPTION_DUPLICATED 20: dos entradas de Description para el mismo nodo

Los errores de un documento frente a un template son los de STXT-SCHEMA-SPEC §13.1, porque se valida contra el schema compilado.

15. Conformidad

Una implementación de templates es conforme si:

  • Implementa la gramática de Template y Structure de este documento.
  • Aplica las reglas de cardinalidad, tipos, referencias @Nombre Nodo (incluida recursión por ancestro abierto) y ENUM.
  • Aplica las reglas de compatibilidad de hijos por tipo (sólo INLINE y GROUP admiten hijos).
  • Valida cardinalidades de forma independiente del orden.
  • Rechaza templates inválidos según la sección 14.
  • Define un criterio estable de selección de template (si existieran múltiples fuentes), sin aplicar más de uno simultáneamente por namespace objetivo.

16. Meta-template del propio sistema @stxt.template

Esta sección define un template mínimo recomendado para validar documentos del namespace @stxt.template.

Template (@stxt.template): @stxt.template
	Structure >>
		Template (@stxt.template):
			Description: (?) TEXT
			Structure: (1) BLOCK

Notas:

  • Structure es BLOCK porque en templates debe ser un bloque >>.
  • Description es opcional y puede ser TEXT: para el core y para este meta-template su contenido es texto opaco, pero se interpreta con la gramática de descripciones por nodo de la sección 12, igual que el contenido de Structure se interpreta con la gramática de templates.
  • La línea Template usa cardinalidad por defecto (*): como el nivel superior de Structure no tiene semántica especial de raíz (sección 6), no se le impone una cardinalidad de documento.

17. Ejemplos normativos

17.1 Template simple (un namespace)

Template (@stxt.template): com.example.docs
	Structure >>
		Document (com.example.docs):
			Title: (1)
			Author: (1)
			Date: (1) DATE
			Body: (1) TEXT
	Description >>
		Document: Documento simple con título, autor, fecha y cuerpo

17.2 Template con repetición y nodos anidados

Template (@stxt.template): com.example.blog.post
	Structure >>
		Post (com.example.blog.post):
			Title: (1)
			Slug: (1)
			Published: (1) BOOLEAN
			Tags: (?)
				Tag: (+)
			Sections: (1)
				Section: (+)
					Heading: (1)
					Content: (1) TEXT

17.3 Template con ENUM

Template (@stxt.template): com.example.ui.theme
	Structure >>
		Theme (com.example.ui.theme):
			Name: (1)
			Mode: (1) ENUM [light, dark]
			Accent: (?) ENUM [blue, green, orange]

17.4 Template con reutilización local

Template (@stxt.template): org.example.docs
	Structure >>
		Email (org.example.docs):
			Body Content: (1) TEXT
		Demo (org.example.docs):
			Body Content: (?) @Body Content

17.5 Template con recursión

Template (@stxt.template): com.example.doc
	Structure >>
		Documento (com.example.doc):
			Título: (1)
			Sección: (*)
				Título: (1) @Título
				Texto: (?) TEXT
				Sección: (*) @Sección

Sección se contiene a sí misma a cualquier profundidad. Es el caso que un parser con la regla de "sólo definición previa" rechazaría incorrectamente; por eso se incluye como ejemplo normativo de conformidad.

17.6 Cross-namespace (referencias externas)

Template (@stxt.template): com.example.docs
	Structure >>
		Document (com.example.docs):
			Metadata (org.example.meta): (?)
			Content: (1) TEXT

En este caso:

  • Metadata pertenece a org.example.meta.
  • La validación profunda de Metadata dependerá de si existe un schema/template para org.example.meta.

18. Apéndice A — Gramática (informal)

TemplateDoc      = "Template" "(" "@stxt.template" ")" ":" NamespaceTarget { TemplateField }
TemplateField    = DescriptionField | StructureField
DescriptionField = "Description" ( ":" | ">>" ) DescEntries
StructureField   = "Structure" ">>" Newline { StructureLine }

DescEntries      = { DescEntry }
DescEntry        = NodeName ( ":" Texto | ">>" BloqueTexto )   ; NodeName definido en Structure (sección 12)

StructureLine    = Indent NodeSpec Newline
NodeSpec         = NodeName [NsOverride] ":" [RuleSpec]
NsOverride       = "(" ["@"] Namespace ")"
RuleSpec         = [Card] [NodeRef | Type [EnumValues]]

Card             = "(" CardToken ")"
CardToken        = "*" | "+" | "?" | Num | Num "+" | Num "-" | Num "," Num
NodeRef          = "@" NodeName
Type             = IdentUpper
EnumValues       = "[" Value { "," Value } "]"

NodeName         = Texto hasta `(` o `:`, con trim y compactación de espacios
NamespaceTarget  = Namespace según STXT-SPEC
Namespace        = Ident "." Ident { "." Ident }   ; al menos 2 Ident
Ident            = [A-Za-z0-9]+   ; aceptado en entrada; normalizado a minúsculas (STXT-SPEC sección 7)
IdentUpper       = [A-Z0-9_]+     ; los tipos se escriben en mayúsculas; comparación exacta (sección 8)
Value            = cualquier texto sin "," ni "]", con trim   ; ver sección 9.1