STXT Plantillas (@stxt.template)
1. Introducción2. Terminología
3. Relación entre STXT y Template
4. Estructura general de un Template
5. Un template por namespace objetivo
6. Bloque `Structure >>`
7. Cardinalidades
8. Tipos
9. ENUM y lista de valores
10. Namespaces dentro de `Structure`
11. Reglas de “nodos definidos”
12. Compilación a Schema (equivalencia semántica)
13. Errores de Template
14. Conformidad
15. Meta-template del propio sistema `@stxt.template`
16. Ejemplos normativos
17. Apéndice A — Gramática (informal)
18. Fin del Documento
1. Introducción
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.schemasemá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.
- 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.
2. Terminología
Las palabras clave "DEBE", "NO DEBE", "DEBERÍA", "NO DEBERÍA", y "PUEDE" deben interpretarse según RFC 2119.
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:
- Parseo del documento STXT a estructura jerárquica.
- Resolución del namespace efectivo de cada nodo.
- Selección del template correspondiente al namespace objetivo.
- 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 Description: Plantilla de ejemplo Structure >> Document (com.example.docs): Title: (1) Body: (1) TEXT
Reglas:
- El nodo raíz
TemplateDEBE 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 un nodo
Description. - 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.
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 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 (para ser un documento STXT válido).<RuleSpec>es opcional e incluye, en este orden lógico:- Cardinalidad opcional (entre paréntesis).
- Referencia opcional a un nodo previamente definido mediante
@Nombre Nodo, o alternativamente un tipo. - 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 aunque declare tipo por defecto
INLINE. Los tipos que prohíben hijos se definen en la sección 8. - Una referencia
@Nombre NodoNO DEBE combinarse con un tipo explícito en la misma línea.
6.3 Reglas de parsing del `Structure >>`
Un parser de templates DEBE:
-
Leer el bloque
Structure >>como una secuencia de líneas (ya canonicalizadas por STXT core: trim derecha por línea). -
Ignorar líneas vacías.
-
Calcular jerarquía por indentación (mismos principios que STXT: indentación consecutiva, sin saltos).
-
Para cada línea, parsear:
- Nombre del nodo + namespace opcional
(ns)si existe. - El carácter
:obligatorio. - La especificación de reglas opcional (
RuleSpec).
- Nombre del nodo + namespace opcional
-
Resolver el namespace efectivo de cada línea.
-
Resolver referencias
@Nombre Nodoúnicamente contra nodos ya definidos previamente en el mismo template.
Un parser de templates DEBE fallar si una línea no contiene :.
6.4 Redefinición de nodos y nodos de otros namespaces
Las plantillas distinguen entre:
- Definición local de nodo: primera aparición de un nodo cuyo namespace efectivo pertenece al namespace objetivo del template.
- Referencia local de nodo: reutilización de una definición local previa mediante
@Nombre Nodo. - Referencia externa: aparición de un nodo cuyo namespace efectivo pertenece a otro namespace.
Reglas:
- 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 NodoDEBE apuntar a una definición local previa del mismo template. - Una referencia
@Nombre NodoPUEDE sobrescribir la cardinalidad, pero NO DEBE redefinir tipo, valoresENUMni hijos. - 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 SÓLO DEBERÍA declararse su cardinalidad.
Ejemplo:
Template (@stxt.template): com.example.dokumentando.doc Structure >> Documento (com.example.dokumentando.doc): Título: (1) Secciones: (*) Sección: (+) TEXT Description: (1) TEXT Tipo Documento: (1) Metadata (org.example.meta): (?) Resumen (com.example.dokumentando.doc): Título: (1) @Título Contenido: (1) TEXT Metadata (org.example.meta): (?)
7. Cardinalidades
La cardinalidad se aplica por instancia del nodo padre, contando sólo hijos directos que coincidan por:
- Nombre canónico del nodo (según STXT-SPEC).
- Namespace efectivo del nodo.
La cardinalidad se expresa como un token opcional entre paréntesis: ( ... ).
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,minymaxDEBEN ser enteros no negativos.- En
min,max, DEBE cumplirsemin <= max. +equivale a1+.?equivale a0,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.
- 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
Una implementación conforme DEBE aplicar estas reglas:
-
Tipos BLOCK-only (por ejemplo
BLOCK,TEXT,BASE64, etc.) NO son compatibles con hijos. Si un nodo plantilla tiene hijos enStructure >>y su tipo efectivo es BLOCK-only, el template DEBE considerarse inválido. -
Tipos GROUP (o equivalentes estructurales sin valor) SÍ admiten hijos.
-
Tipos INLINE (por ejemplo
INLINE,NUMBER,DATE,BOOLEAN,ENUM, etc.) PUEDEN admitir hijos (misma filosofía que Schema). La validación del valor se aplica al nodo, y la validación de estructura se aplica a sus hijos.
8.3 Conjunto de tipos
El conjunto de tipos recomendado es el mismo que STXT-SCHEMA-SPEC.
Una implementación de templates:
- DEBE soportar al menos:
INLINE,GROUP,BLOCK,TEXT,NUMBER,BOOLEAN,DATE,ENUM. - DEBERÍA soportar el resto de tipos definidos en STXT Schema (por ejemplo
INTEGER,NATURAL,TIME,TIMESTAMP,UUID,URL,EMAIL,BASE64, etc.).
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.
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
Structureomite 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 valoresENUM; 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
Structurepasa 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. Compilación a Schema (equivalencia semántica)
Un template puede compilarse a un schema equivalente:
- Cada línea de
Structuregenera una definiciónNodepara el nodo plantilla (en el namespace correspondiente). - La jerarquía de indentación en
StructuregeneraChildren/Childen el schema. - La cardinalidad
( ... )en el template se traduce a:Min/Maxen el schema.
- El tipo se copia a
Type. ENUM [a,b]se traduce aValues/Value.- Una referencia
@Nombre Nodoreutiliza la definición ya generada para ese nodo local y sólo modifica la cardinalidad delChildcorrespondiente. - Un nodo cross-namespace sólo genera una referencia
Child; su definición corresponde al template o schema de ese otro namespace.
Reglas de traducción de cardinalidad:
(num)→Min=num,Max=num(*)→ sinMin, sinMax(+)→Min=1(?)→Max=1(num+)→Min=num(num-)→Max=num(min,max)→Min=min,Max=max
13. Errores de Template
Un template es inválido si ocurre cualquiera de estas condiciones:
- El documento de
Structure>>no es un documento válido STXT (indentación inválida, etc.) - El documento no tiene raíz
Template (@stxt.template): <namespace_objetivo>. - Falta
Structure >>oStructureno es bloque>>. - Una línea no vacía dentro de
Structureno contiene:. - Cardinalidad mal formada o con números inválidos.
- Tipo desconocido (según el conjunto de tipos soportado por la implementación).
- Uso de
[...]si el tipo no esENUM. - Tipo BLOCK-only con hijos definidos en
Structure. - Redefinir un nodo local que ya ha aparecido previamente sin usar referencia
@Nombre Nodo. - Usar una referencia
@Nombre Nodoque no apunta a una definición local previa. - Declarar a la vez referencia
@Nombre Nodoy tipo explícito en la misma línea. - Declarar valores
ENUMduplicados tras la normalización por trim. - Definir hijos, tipo explícito o valores
ENUMen un nodo cross-namespace.
14. Conformidad
Una implementación de templates es conforme si:
- Implementa la gramática de
TemplateyStructurede este documento. - Aplica las reglas de cardinalidad, tipos, referencias
@Nombre NodoyENUM. - Aplica las reglas de compatibilidad de hijos por tipo.
- Rechaza templates inválidos según la sección 13.
- 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.
15. 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): (1) Description: (?) TEXT Structure: (1) BLOCK
Notas:
StructureesBLOCKporque en templates debe ser un bloque>>.Descriptiones opcional y puede serTEXT.
16. Ejemplos normativos
16.1 Template simple (un namespace)
Template (@stxt.template): com.example.docs Description: Plantilla simple Structure >> Document (com.example.docs): Title: (1) Author: (1) Date: (1) DATE Body: (1) TEXT
16.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
16.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]
16.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
16.5 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:
Metadatapertenece aorg.example.meta.- La validación profunda de
Metadatadependerá de si existe un schema/template paraorg.example.meta.
17. Apéndice A — Gramática (informal)
TemplateDoc = "Template" "(" "@stxt.template" ")" ":" NamespaceTarget { TemplateField }
TemplateField = DescriptionField | StructureField
DescriptionField = "Description" ":" Text
StructureField = "Structure" ">>" Newline { StructureLine }
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 = [a-z0-9]+
IdentUpper = [A-Z0-9_]+ ; recomendado en mayúsculas (estilo)