A document template owns the page shell: doctype, metadata, style and article container. Source text owns none of those structures. Insert the escaped title and renderer-produced body fragments at explicit placeholders.
The supplied template creates a responsive standalone page using system fonts and original CSS. It supports dark/light system preferences. There are no external scripts, font downloads or image dependencies.
Render ordinary block lines through the inline parser and renderer with their retained locations. Headings choose only h1 or h2. Paragraph lines join with one space; list lines become separate li elements.
Fenced code follows a different path: join its literal lines, preserve indentation and append the documented trailing LF when nonempty. Escape it as text. The language attribute is chosen only from text/python, not arbitrary source values.
import html
lines = [' print("<x>")', '', '# literal']
literal = "\n".join(lines)+"\n"
print("<pre><code>"+html.escape(literal,quote=False)+"</code></pre>")Use string.Template.substitute once on the trusted template. Values are inserted, not recursively interpreted as more placeholders. A title equal to $body must remain that exact title text. A sequence of ad hoc replace calls can accidentally rescan newly inserted values.
Escape the title for its text context. A malicious-looking </title><script> string should appear as text within the title rather than terminate it. Body HTML is trusted only because it was produced by the controlled renderers; raw source is never a substitute body fragment.
Exact output is useful here. Fixed block order, newline rules and a fixed template make two builds of equivalent source produce identical bytes. The final lesson will fingerprint those bytes and write an owned output file through the local CLI.
from string import Template
shell = Template("<title>$title</title><main>$body</main>")
print(shell.substitute(title="$body",body="<p>controlled fragment</p>"))Implement document rendering and test semantic tags, escaped title text, literal code, whitelisted language attributes and dollar markers inside values. Verify repeated rendering is identical.
Next we combine the stages and report useful source failures without publishing a partial successful page.