Output functions¶
ProcessingModelFunctions is the abstract base every output format implements.
The generated transform module calls its methods (paragraph, heading,
block, inline, …) to emit output. Subclass it to add a new output format; see
the concrete implementations for HTML, Print, EPUB, Markdown, Typst, DOCX and JSON.
Base class and helpers¶
opm.runtime.output_functions ¶
Output format abstraction for TEI transformation.
Equivalent to html-functions.xql (and sibling format modules) in
tei-publisher-lib/content. Each concrete subclass of
ProcessingModelFunctions implements a specific serialisation
target (HTML, Markdown, …). The generated transformation module
calls methods on config.pmf and never imports a format-specific
module directly.
HTML and Markdown implementations live in opm.html_output_functions and
opm.markdown_output_functions; they are re-exported here for convenience.
TemplateOutput ¶
Bases: str
Preformatted or template text; skip prose normalisation that collapses line breaks.
ProcessingModelFunctions ¶
Bases: ABC
Abstract base for output format implementations.
Method names mirror the TEI Processing Model function vocabulary used by
html-functions.xql / markdown-functions.xql etc. The generated
transformation module calls these methods via config.pmf so that
only the config construction needs to change
when a different output format is required.
Every method receives config, a RenderContext,
as its first argument. Output functions delegate recursive processing
through it without importing the dispatch module:
config.apply – apply(config, nodes) → list
config.apply_children – apply_children(config, node, content,
parent) → None
A run creates its own instance, so per-run caches may live on self.
code ¶
Fallback code behaviour for output modes without dedicated formatting.
code_inline ¶
Inline code span — raw text, no markup escaping applied to the body.
unmatched ¶
Handle an element no model matched, i.e. the generated case _: arm.
Default: recurse into the children, which is what the generated dispatch
does inline for every other output mode. Only the JSON mode overrides
this — it is the sole way to see elements the ODD has no model for,
since they otherwise never reach a pmf method at all.
Source code in src/opm/runtime/output_functions.py
map_rend_to_class ¶
Map @rend attribute tokens directly to CSS class names, e.g. 'bold' → 'bold'.
classes ¶
add_lang_attrs ¶
Copy @xml:lang from source_node as HTML lang/dir attributes on el.
Source code in src/opm/runtime/output_functions.py
normalize ¶
Return content as a flat list of strings and lxml Elements.
Source code in src/opm/runtime/output_functions.py
child_nodes ¶
All child content as a flat list of strings and elements.
Equivalent to the XPath node() axis: preserves interleaved text and
element children (including tail text of each child element).
Source code in src/opm/runtime/output_functions.py
should_preserve_whitespace ¶
Return True when dispatch classes indicate preformatted / code content.
Source code in src/opm/runtime/output_functions.py
apply_children_without_normalization ¶
Call config.apply_children with normalize_text off for this subtree.
Source code in src/opm/runtime/output_functions.py
serialize_element_content_literal ¶
Serialize the mixed content inside el as literal XML/text.
Source code in src/opm/runtime/output_functions.py
literal_code_body ¶
Build a code-block body without running child elements through the PM.
Source code in src/opm/runtime/output_functions.py
join_eol_hyphen ¶
Close up a word the source split across lines at a soft hyphen.
Where an encoder marks the split with U+00AD and indents the continuation
(Arra<lb/>gon), dropping the lb leaves that indentation behind,
and every renderer collapses it to a space: "Arra gon". The soft hyphen is
kept, so a reading system may still break the word there.
Source code in src/opm/runtime/output_functions.py
maybe_normalize_text ¶
Apply norm unless s is template output that must keep \n.
apply_pb_template ¶
Execute a pb:template: parse template_str as XML, substitute [[param]] placeholders, and return the resulting list of nodes (strings and lxml Elements).
config is accepted for API symmetry but not currently used; element-valued params that
appear in text positions are inserted directly into the result tree. The ODD compiler is
expected to pass already-rendered output nodes (see
apply_template_param_value, which expands a context node
to processed children instead of raw TEI).
Source code in src/opm/runtime/output_functions.py
HTML¶
opm.runtime.html_output_functions.HtmlOutputFunctions ¶
Bases: ProcessingModelFunctions
Serialise to HTML5 using lxml elements.
finish ¶
pass_through ¶
Render content without adding a wrapper element.
Source code in src/opm/runtime/html_output_functions.py
note ¶
Emit note - margin notes as inline spans, others as footnotes.
Source code in src/opm/runtime/html_output_functions.py
code ¶
Emit a <pre><code> block so whitespace is preserved without JS.
Source code in src/opm/runtime/html_output_functions.py
Print (paged media)¶
opm.runtime.print_output_functions.PrintOutputFunctions ¶
Bases: HtmlOutputFunctions
Serialise to HTML tuned for paged-media CSS (Prince, Paged.js, print).
Equivalent to the pmf:* overrides in ext-printcss.xql.
note ¶
Emit note as an inline span for CSS float: footnote / margin notes.
Unlike HtmlOutputFunctions.note, does not build callout links or
append bodies to config.state.footnotes. A label (TEI @n) is kept
as data-n so print CSS can show a, b, … instead of the running number.
Source code in src/opm/runtime/print_output_functions.py
alternate ¶
Emit the default reading plus the alternate as a print footnote.
Ignores webcomponents / popovers — print has no interactive UI.
Source code in src/opm/runtime/print_output_functions.py
EPUB¶
opm.runtime.epub_output_functions.EpubOutputFunctions ¶
Bases: HtmlOutputFunctions
Serialise to HTML with EPUB 3 structural semantics.
Equivalent to the pmf:* overrides in ext-epub.xql. Packaging into a
.epub ZIP is handled separately by opm.epub.
note ¶
Emit an EPUB noteref + footnote aside (in-flow; packager may hoist).
Source code in src/opm/runtime/epub_output_functions.py
alternate ¶
Default reading as noteref; alternate body as footnote aside.
Source code in src/opm/runtime/epub_output_functions.py
webcomponent ¶
Degrade custom elements: EPUB 3 XHTML has no place for them.
pb-link keeps its cross-reference as a fragment link (rewritten to
the target chapter file during packaging); everything else becomes a
transparent div / span wrapper.
Source code in src/opm/runtime/epub_output_functions.py
cells ¶
Wrap each content item as a <td> inside a <tr> (ext-epub).
Source code in src/opm/runtime/epub_output_functions.py
EPUB packaging (ZIP / OPF / nav) lives in opm.epub,
not in the PMF.
Markdown¶
opm.runtime.markdown_output_functions.MarkdownOutputFunctions ¶
Bases: ProcessingModelFunctions
Serialise to Markdown text fragments (CommonMark-style).
Mirrors pmf:* in tei-publisher-lib/content/markdown-functions.xql:
paragraph breaks, headings with #, list markers, pipe tables, links,
reference-style notes, and simple rend-based emphasis.
finish ¶
Run pmf:finish-style cleanup: collapse blank lines, tighten _ / ** spans.
Typst¶
opm.runtime.typst_output_functions.TypstOutputFunctions ¶
DOCX¶
opm.runtime.docx_output_functions.DocxOutputFunctions ¶
Bases: ProcessingModelFunctions
DOCX output for TEI processing model.
Style resolution rules (matching tei-publisher-lib):
- For each ODD cssClass that does not start with tei-, look up the name
(case-insensitive) in the template's paragraph / character / table style
index. First match wins; unknown classes are silently skipped.
- Paragraph fallback: "Normal". Character fallback: no style (CSS properties
like bold/italic still apply). Table fallback: "TableGrid".
Source code in src/opm/runtime/docx_output_functions.py
metadata ¶
Collect a header value under key instead of emitting body content.
Mirrors TypstOutputFunctions.metadata: the ODD names the field,
the collected text lands in config.state.metadata and is
mapped onto the .docx core properties by finish.
Source code in src/opm/runtime/docx_output_functions.py
finish ¶
Assemble body elements into a .docx and return [bytes].
Source code in src/opm/runtime/docx_output_functions.py
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | |
JSON¶
Records the processing model's own decisions rather than rendering the document.
It is the only implementation that overrides unmatched, which the generated
dispatch calls for elements no model matched.
opm.runtime.json_output_functions.JsonOutputFunctions ¶
Bases: ProcessingModelFunctions
Emit the processing model's decisions as JSON records.
template ¶
Record a pb:template and keep the content it wraps.
The generator hands templates their parameters already processed, so
params['content'] is a list of finished records. Dropping it would
lose every element a template-heavy ODD wraps — for DocBook that is
most of the document.
Source code in src/opm/runtime/json_output_functions.py
pass_through ¶
Recurse, but still record that a pass_through model won.
Emitting nothing here would hide a real decision: when the model you
expected did not fire because a pass_through one matched first,
the element simply would not appear. The same argument that puts inline
and suppressed behaviours in the tree applies to this one.
Source code in src/opm/runtime/json_output_functions.py
unmatched ¶
Record an element the ODD has no model for, then recurse into it.
The generated dispatch routes its case _: arm here for JSON output.
Without this the element would never reach a pmf method and its
text would surface in some ancestor with no provenance at all — which
is the one thing you most want to find when an ODD looks incomplete.