TEMPLATE-STRUCTURE-01A — Template Validation and Normalization Semantics¶
Status: semantics and characterization only. No validator or normalizer is implemented by this slice.
A. Problem statement¶
A ZIP-valid, well-formed ODF document is not automatically a valid ODT Template Engine template. LibreOffice is free to represent one logical expression with several text nodes, spans, and marker elements. The engine must understand that logical structure without destroying authored formatting, bookmark topology, ordering, or native containers.
The working distinction for future implementation is:
- VALID — the physical structure is unambiguous and needs no repair;
- REPAIRABLE — intent is unambiguous, so a bounded logical projection or a formatting-preserving repair may be possible;
- UNSAFE / AMBIGUOUS — the engine must report the structure rather than guess at author intent.
The classification is operation-sensitive. A structure can be valid for logical recognition while being unsafe for destructive physical normalization.
B. Evidence reviewed¶
This characterization reviewed PRODUCT-01C, ADDRESSABLE-01/02, SECTION-01,
SECTION-02A–D, SECTION-03A–D, the FRAME-LAYOUT-01 documents, ARCH-05 and
ARCH-07 materialization/ownership documentation, and the existing
TEMPLATE-FORMAT-PRESERVATION-01 roadmap entry. It also inspected
OdtTemplate, TemplateProcessor, TemplateExpressionIdentityRewriter,
SectionInstantiationService, the addressable descriptors/resolvers, and
Sample 25 before and after the current load/save path.
C. Physical representation versus logical structure¶
Physical ODF is the node tree: text nodes, text:span elements, bookmark
markers, paragraphs, lists, tables, and sections. Logical template structure is
the token stream interpreted by the template language. For example:
is logically {{position}}, but it is not equivalent to one unstyled text
node. Recognition must therefore be able to project a logical stream while
retaining a mapping to the original physical nodes.
Normalization must not mean “flatten every paragraph.” It is a narrowly bounded repair operation, if one is needed at all.
D. Expression model¶
The current language includes scalar expressions ({{name}}), filtered
scalars ({{upper:name}}, {{date:start|d.m.Y}}), condition markers
({{#if:key}}, {{#ifnot:key}}, {{#elseif:key}}, {{#else}},
{{#endif}}), foreach markers ({{#foreach:key}}, {{#endforeach}}), and
special structured forms such as nl2br, ul, and ol where supported by
the existing processor.
Future validation should parse these as logical expression objects rather than
searching individual text nodes. The variable identity in a filtered scalar is
the value token (name or start), not the filter name. Control expressions
need matching and scope validation; they must not be treated as ordinary
scalars.
E. Logical text scope and boundaries¶
Within one semantic text-flow scope, the following may be transparent to logical token recognition:
- adjacent text nodes;
text:spanelements;text:bookmark;text:bookmark-startandtext:bookmark-end.
The following are hard boundaries and must not be crossed implicitly:
text:pandtext:hboundaries;text:list-itemboundaries;- table-cell and covered-cell boundaries;
text:sectionboundaries;draw:text-boxand custom-shape text-flow boundaries;- document/body/container boundaries.
This matches the bounded logical grouping already used by SECTION-03C/03D. Bookmark markers are transparent for token recognition, but remain physical native objects and must never be moved or deleted by normalization.
F. Style fragmentation¶
A complete expression in one span is VALID. A split expression across spans with equivalent style is REPAIRABLE in principle, provided the physical spans are preserved or merged only when equivalence is proven.
Different styles require a more conservative result. The logical expression may still be recognized for inspection or a bounded operation, but destructive physical normalization is UNSAFE: selecting one style or flattening to plain text would invent formatting semantics. A future implementation should use a virtual token projection by default and reject physical repair unless an operation explicitly defines the style choice.
Sample 25 uses T29, T30, and T29 across the logical {{activity}}
expression. This is evidence for logical recognition, not permission to
flatten the expression.
G. Bookmark intersections¶
The following are acceptable native relationships when their topology is otherwise valid:
- a bookmark outside an expression;
- a paired bookmark surrounding an expression;
- a collapsed bookmark adjacent to an expression;
- a marker between physical fragments of one logical expression.
The last case is VALID for native inspection and bounded identity-preserving
operations, but is UNSAFE for a generic physical normalizer unless marker
placement is proven unchanged. It should produce a diagnostic such as
bookmark_intersects_expression and remain an explicit authoring concern.
Unpaired, mismatched, incorrectly ordered, or overlapping bookmark ranges are UNSAFE. Existing ADDRESSABLE bookmark diagnostics remain authoritative; this document does not redefine them.
H. Section rules¶
An engine-valid named section has a non-empty text:name, a unique name within
the section namespace in the final addressable template, and a structurally
well-formed native boundary. Nested sections are allowed and remain distinct
scopes. An unusual parent, such as Sample 25's custom-shape text flow, is not
invalid merely because it is uncommon.
An expression must not begin outside a section and finish inside it, or cross a nested section boundary. Lists, tables, and drawing text flows remain their own structural contexts. A section may contain those structures when their native boundaries are complete.
I. Bookmark rules¶
Both collapsed text:bookmark and paired start/end bookmarks are supported
native forms. Paired markers must have the same non-empty name and valid order.
Duplicate same-name ranges, unmatched markers, and ambiguous nesting are
invalid for a final template, though inspection may report them as
diagnostics. A valid final template keeps same-type names unique; namespaces
remain type-specific.
J. Variable and bookmark coexistence¶
A bookmark and a visible template expression may occupy the same logical content. This is tolerated only when both native bookmark topology and logical expression scope are unambiguous. It does not create an implicit data-binding relationship: a template value does not automatically mutate a bookmark, and bookmark names are not inferred from data keys.
Sample 25's Activity bookmark intersecting {{activity}} is therefore
readable and usable by the bounded SECTION-03D clone-local binding path, but
is not a license for destructive normalization or automatic bookmark binding.
K. Classification matrix¶
| Physical case | Logical recognition | Physical normalization |
|---|---|---|
One span containing {{name}} |
VALID | No repair needed |
{{na / me}} in adjacent equivalent-style spans |
VALID | REPAIRABLE if styles and topology are preserved |
| Same-style split expression with no markers | VALID | REPAIRABLE, preferably virtually |
| Split expression across incompatible styles | VALID for reading | UNSAFE to flatten; physical repair deferred |
| Split expression with a transparent bookmark marker between fragments | VALID for bounded reading | REPAIRABLE only by marker-preserving operation; generic flattening unsafe |
| Bookmark pair around a complete token | VALID | No generic repair needed |
Expression crossing text:p/text:h |
UNSAFE | Reject |
| Expression crossing a section boundary | UNSAFE | Reject |
| Expression crossing a table cell | UNSAFE | Reject |
| Expression crossing a list item | UNSAFE | Reject |
| Filter token split within one permitted scope | VALID/REPAIRABLE | Only parser-aware, style-preserving repair |
| Condition or foreach marker split within one permitted scope | REPAIRABLE for logical validation | Physical/control-structure repair requires dedicated rules |
Unmatched {{ or }} |
UNSAFE | Reject |
| Unmatched, overlapping, or mismatched bookmark markers | UNSAFE | Reject |
| Nested structural containers treated as transparent | UNSAFE | Never normalize across them |
The distinction between “logical recognition” and “physical normalization” is intentional. It prevents a validator from forcing every recognizable token into a single physical text node.
L. Normalization philosophy¶
The preferred future meaning of normalization is:
repair only physical structures whose logical intent is unambiguous, while preserving formatting, ordering, bookmark topology, and native ODF structure.
The safest first mechanism is a non-mutating logical token map. A physical repair may be considered for equivalent-style fragments with no hard-boundary crossing and no marker ambiguity. It must preserve the original style spans or merge only demonstrably equivalent nodes. It must not recreate styles, move text around markers, or flatten unrelated content.
M. Load-time normalization decision analysis¶
The current path is load-time mutation: prepareLoadedTemplate() calls
normalizeTemplateDom() for content and styles, and the processor reconstructs
balanced placeholder text by removing nodes and appending one plain text node.
This is simple and historically compatible with some fragmented placeholders,
but it is destructive and can change both formatting and physical order.
The alternatives are:
- Non-mutating validation/inspection — safest and most predictable, but requires processing code to consume logical groups.
- Safe physical normalization — compatible with existing downstream code for a narrow green zone, but difficult to prove for styles and markers.
- Lazy logical token projection — preserves the source DOM and gives the processor a semantic stream, with moderate implementation complexity.
- Hybrid — validate/project by default and permit only explicit, proven-safe physical repairs.
The evidence recommends the hybrid direction, beginning with non-mutating validation and lazy logical projection. A future implementation must first characterize templates that rely on current destructive behavior and decide whether a legacy compatibility path is needed. This slice does not change the load behavior.
N. Diagnostics model¶
Future structure diagnostics should be typed data, not prose-only exceptions.
Useful fields are code, severity, location, containerType, target or
bookmark name, logical expression, repairable, reason, and suggested fix.
Candidate codes include:
split_template_expression;style_conflict_in_expression;bookmark_intersects_expression;expression_crosses_paragraph_boundary;expression_crosses_section_boundary;expression_crosses_table_cell_boundary;malformed_template_expression;duplicate_section_name;malformed_bookmark_range;ambiguous_template_structure.
Exact codes should be finalized with the 01B implementation, but the fields must support programmatic/AI recovery without parsing English messages.
O. Strict and lenient modes¶
A future strict mode is recommended for CI and AI-assisted authoring: unsafe structures fail before rendering or mutation, and repairable structures are reported explicitly. A lenient mode could allow only the safe logical projection/repair subset; it must never silently guess across hard boundaries or ambiguous styles/markers. No modes are implemented here.
P. Preliminary authoring contract¶
Authors should prefer one semantic expression in one styled span, stable named sections, and stable native bookmark names. Splitting across equivalent-style spans is tolerable but less robust. Bookmark markers may coexist with a token only when their topology is intentional and preserved. Authors should avoid crossing paragraph, list-item, table-cell, section, and drawing text-flow boundaries. Mismatched bookmarks, overlapping ranges, and incomplete tokens are invalid.
Q. Sample 25 forensic findings¶
The unnormalized fixture contains:
- one outer
ExperienceEntrysection inside a custom-shape text flow; - nested
ActivityEntryand list/list-item structures; Companyas a paired bookmark aroundUnternehmen, Ort;- collapsed
FromTobookmark; Activitypaired markers intersecting the split logical{{activity}}token;- styled
{{note}}and{{position}}placeholders; - activity fragments using
T29,T30, andT29.
The current load/save characterization was run directly against the fixture.
The styled position content is serialized as a plain {{position}} text node
after the Company bookmark, rather than remaining in its original styled
span position. The activity fragments are reduced to plain {{activity}}
text between the bookmark markers. This confirms both formatting loss and
placeholder relocation. The native sections, lists, and bookmark markers are
still present, so SECTION-03D's clone/identity/local-binding semantics are not
fundamentally invalid; the load-time normalization is the preservation debt.
R. Compatibility risks¶
Current samples and tests may rely on fixBrokenVariables() and global
normalization to turn fragmented placeholders into text that later scalar,
filter, conditional, foreach, nl2br, and list processing can consume. Removing
that behavior without characterization could break existing templates or
change repeated render/save behavior. Different-style fragments, control tags,
structured placeholders, and row-local foreach behavior are especially risky.
The existing TEMPLATE-FORMAT-PRESERVATION-01 roadmap item covers preservation
of formatting and DOM structure during template processing. This milestone is
related but distinct: it defines what authors and a future validator may
consider a safe engine template. The two efforts must share boundary and token
semantics rather than create contradictory rules.
S. Future validation API direction¶
The likely direction is a separate typed template-structure report, exposed
later through a carefully named facade operation such as validateTemplate().
Whether that report is returned by inspect() or by a separate
TemplateStructureInspection should remain open until 01B characterization is
implemented. DocumentInspector should continue to own native sections,
bookmarks, tables, frames, and their diagnostics; it should not become the
template-language validator.
T. Responsibility boundaries¶
DocumentInspector: enumerate and diagnose native named document objects.- Future template-structure validator: validate expression topology, boundaries, bookmark interaction, and authoring safety.
TemplateProcessor: evaluate the existing template language.SectionInstantiationService: clone-local identity rewrite and bounded local binding.
These responsibilities should not be collapsed into one normalizer or one universal document object.
U. Relationship to SECTION-03D¶
SECTION-03D is functionally implemented: native cloning, deterministic identity rewriting, and clone-local scalar binding work logically. Sample 25 exposed a pre-existing load-time normalization problem that damages formatting and physical topology. This milestone is therefore a prerequisite to visual and format-preserving confidence before SECTION-03E; it does not redefine SECTION-03D as a failed clone model.
V. Future TEMPLATE-STRUCTURE-01B test plan¶
The implementation slice should characterize at least:
- load/save preserves styled placeholders;
- placeholder order remains unchanged;
- same-style split expressions are recognized;
- different-style split expressions follow the explicit conservative rule;
- bookmark-intersecting expressions preserve marker positions;
- collapsed bookmarks adjacent to expressions;
- paired bookmarks around expressions;
- paragraph-boundary crossing is rejected;
- section-boundary crossing is rejected;
- table-cell-boundary crossing is rejected;
- malformed expressions are diagnosed;
- malformed bookmarks are diagnosed;
- existing simple samples remain unchanged;
- repeated render/save is stable;
- Sample 25 remains structurally and visually preservation-safe.
W. Recommendation¶
Implement TEMPLATE-STRUCTURE-01B as a non-mutating validator and logical token
projection first. Reuse the already bounded transparent-marker and hard-boundary
rules, preserve physical spans during evaluation where possible, and add
regression tests around Sample 25 before changing prepareLoadedTemplate().
Only after that evidence should the project decide whether safe physical
normalization is needed. Do not begin SECTION-03E until the preservation and
validation contract is characterized.