Every fixture, test document, tool example and document now uses an invented kitchen-and-baking handbook series, written in this repository. The package's behaviour is unchanged; src/ changes are comments and help text only. - Generated fixtures are regenerated from their generators. Their structural counts are identical before and after: elements, images, rows, cells, headings, bookmarks and the witness inventory's per-document totals. The image-inbox and accounting documents are renamed kapittel-84-*. - tools/okf_accounting_gate.py: the two options that named one real corpus each are replaced by a generic, repeatable --corpus PATH with no default. Row 5 compares the PDF pair alone. Gate verdict unchanged: RED rows 2, 3, 6. - tools/okf_witness.py: the STS JSON reader for one publisher's delivery is removed, along with its three twins and five tests. The mutation harness loses W09. - docs/: 13 dated reports that documented runs on a retired reference corpus are removed, and 40 are neutralized. Dead links are removed, and no new dangling path is introduced. - The synthetic MCP-gate corpus and the residual probe words are neutral. Valgt: keep the `okf quality --fasit` bar value (the measured fraction, one corpus) and rewrite only its provenance, because the verdict stays unchanged and the number names nothing. Term check with the local list: 0 of 411 tracked files, 0 file names, 0 of 27 binary fixtures. Suite after git add: 2457 passed, 1 skipped. The base tree had 2460 passed and 2 skipped; five tests went with the JSON reader and four were added by the term check. ruff, ruff format and mypy --strict src/ are clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
357 lines
17 KiB
Python
357 lines
17 KiB
Python
"""The accounting corpus's SECOND document per format: the elements the
|
|
witness could not see until 2026-09-18.
|
|
|
|
An independent review of the gate found that the witness -- and therefore the
|
|
whole accounting, because rows 2 and 3 require the build's inventory to EQUAL
|
|
it -- counted no header, no comment, no speaker note, no hidden sheet, no
|
|
formula, no citation and no figure caption. What nothing counts, nothing can
|
|
lose visibly. It also found that 20 of 63 element types had a count of ZERO in
|
|
their only fixture, so six of seven witness mutants survived.
|
|
|
|
These documents are written BY HAND, part by part, for the reason the XML
|
|
fixtures state: a library that writes and then reads its own format proves
|
|
only that it agrees with itself. Every count they carry is written down in
|
|
`tests/fixtures/README.md` by a person reading these strings, not by running
|
|
the witness over them.
|
|
|
|
python3 tests/fixtures/accounting/make_accounting_fixtures.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import io
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
CORPUS = HERE / "corpus"
|
|
|
|
_ZIP_DATE = (2020, 1, 1, 0, 0, 0)
|
|
_XML = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
|
|
|
|
_W = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"'
|
|
_A = 'xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"'
|
|
_P = 'xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"'
|
|
_S = 'xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"'
|
|
|
|
|
|
def build_zip(parts: dict[str, str | bytes]) -> bytes:
|
|
"""Zip the parts with a fixed timestamp, so a regeneration that changes
|
|
nothing leaves the bytes alone and `git diff --quiet` stays a real check."""
|
|
out = io.BytesIO()
|
|
with zipfile.ZipFile(out, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
|
for name, payload in parts.items():
|
|
info = zipfile.ZipInfo(name, date_time=_ZIP_DATE)
|
|
info.compress_type = zipfile.ZIP_DEFLATED
|
|
archive.writestr(info, payload)
|
|
return out.getvalue()
|
|
|
|
|
|
# --- docx: a header, a footer, a comment, an endnote and a text box ----------
|
|
|
|
_DOCX_BODY = (
|
|
'<w:p><w:pPr><w:pStyle w:val="Heading1"/></w:pPr>'
|
|
"<w:r><w:t>Krav til bakebrett</w:t></w:r></w:p>"
|
|
"<w:p><w:r><w:t>Bakebrett skal ha kant paa begge sider.</w:t></w:r></w:p>"
|
|
"<w:tbl><w:tr>"
|
|
"<w:tc><w:p><w:r><w:t>Bredde</w:t></w:r></w:p></w:tc>"
|
|
"<w:tc><w:p><w:r><w:t>0,4 m</w:t></w:r></w:p></w:tc>"
|
|
"</w:tr></w:tbl>"
|
|
"<w:p><w:r><w:pict><w:txbxContent>"
|
|
"<w:p><w:r><w:t>Merk: kravet gjelder ikke engangsbrett.</w:t></w:r></w:p>"
|
|
"</w:txbxContent></w:pict></w:r></w:p>"
|
|
)
|
|
|
|
_DOCX_PARTS: dict[str, str | bytes] = {
|
|
"[Content_Types].xml": _XML
|
|
+ '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'
|
|
+ '<Default Extension="xml" ContentType="application/xml"/>'
|
|
+ '<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.'
|
|
+ 'relationships+xml"/>'
|
|
+ '<Override PartName="/word/document.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.wordprocessingml.document.main+xml"/>'
|
|
+ '<Override PartName="/word/styles.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.wordprocessingml.styles+xml"/>'
|
|
+ "</Types>",
|
|
"_rels/.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/officeDocument" Target="word/document.xml"/></Relationships>',
|
|
"word/_rels/document.xml.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/styles" Target="styles.xml"/></Relationships>',
|
|
"word/styles.xml": _XML
|
|
+ f"<w:styles {_W}>"
|
|
+ '<w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/></w:style>'
|
|
+ "</w:styles>",
|
|
"word/document.xml": _XML + f"<w:document {_W}><w:body>{_DOCX_BODY}</w:body></w:document>",
|
|
"word/header1.xml": _XML
|
|
+ f"<w:hdr {_W}><w:p><w:r><w:t>Utkast - gjelder ikke etter 2026-01-01</w:t></w:r></w:p>"
|
|
+ "</w:hdr>",
|
|
"word/footer1.xml": _XML
|
|
+ f"<w:ftr {_W}><w:p><w:r><w:t>Eksempelforlaget, side 1</w:t></w:r></w:p></w:ftr>",
|
|
"word/comments.xml": _XML
|
|
+ f"<w:comments {_W}>"
|
|
+ '<w:comment w:id="1"><w:p><w:r><w:t>Unntak: gjelder IKKE bakebrett i kjeller.'
|
|
+ "</w:t></w:r></w:p></w:comment></w:comments>",
|
|
"word/footnotes.xml": _XML
|
|
+ f"<w:footnotes {_W}>"
|
|
+ '<w:footnote w:id="0"><w:p><w:r><w:t>separator</w:t></w:r></w:p></w:footnote>'
|
|
+ '<w:footnote w:id="2"><w:p><w:r><w:t>Se kokebok Q400 kapittel 5.</w:t></w:r></w:p>'
|
|
+ "</w:footnote></w:footnotes>",
|
|
"word/endnotes.xml": _XML
|
|
+ f"<w:endnotes {_W}>"
|
|
+ '<w:endnote w:id="0"><w:p><w:r><w:t>separator</w:t></w:r></w:p></w:endnote>'
|
|
+ '<w:endnote w:id="3"><w:p><w:r><w:t>Kravet ble skjerpet i 2024.</w:t></w:r></w:p>'
|
|
+ "</w:endnote></w:endnotes>",
|
|
}
|
|
|
|
|
|
# --- pptx: a speaker note and a hidden slide --------------------------------
|
|
|
|
|
|
def _slide(title: str, body: str, *, hidden: bool = False) -> str:
|
|
show = ' show="0"' if hidden else ""
|
|
return (
|
|
_XML
|
|
+ f"<p:sld {_P} {_A}{show}><p:cSld><p:spTree>"
|
|
+ '<p:sp><p:nvSpPr><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr>'
|
|
+ f"<p:txBody><a:p><a:r><a:t>{title}</a:t></a:r></a:p></p:txBody></p:sp>"
|
|
+ "<p:sp><p:nvSpPr><p:nvPr/></p:nvSpPr>"
|
|
+ f"<p:txBody><a:p><a:r><a:t>{body}</a:t></a:r></a:p></p:txBody></p:sp>"
|
|
+ "<p:graphicFrame><a:graphic><a:graphicData "
|
|
+ 'uri="http://schemas.openxmlformats.org/drawingml/2006/table">'
|
|
+ "<a:tbl><a:tr>"
|
|
+ "<a:tc><a:txBody><a:p><a:r><a:t>Post</a:t></a:r></a:p></a:txBody></a:tc>"
|
|
+ "<a:tc><a:txBody><a:p><a:r><a:t>84.1</a:t></a:r></a:p></a:txBody></a:tc>"
|
|
+ "</a:tr></a:tbl></a:graphicData></a:graphic></p:graphicFrame>"
|
|
+ "</p:spTree></p:cSld></p:sld>"
|
|
)
|
|
|
|
|
|
_PPTX_PARTS: dict[str, str | bytes] = {
|
|
"[Content_Types].xml": _XML
|
|
+ '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'
|
|
+ '<Default Extension="xml" ContentType="application/xml"/>'
|
|
+ '<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.'
|
|
+ 'relationships+xml"/>'
|
|
+ '<Override PartName="/ppt/presentation.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.presentationml.presentation.main+xml"/>'
|
|
+ "".join(
|
|
f'<Override PartName="/ppt/slides/slide{n}.xml" ContentType="application/vnd.'
|
|
f'openxmlformats-officedocument.presentationml.slide+xml"/>'
|
|
for n in (1, 2)
|
|
)
|
|
+ '<Override PartName="/ppt/notesSlides/notesSlide1.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.presentationml.notesSlide+xml"/>'
|
|
+ "</Types>",
|
|
"_rels/.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/officeDocument" Target="ppt/presentation.xml"/></Relationships>',
|
|
"ppt/_rels/presentation.xml.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/slide" Target="slides/slide1.xml"/>'
|
|
+ '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/slide" Target="slides/slide2.xml"/></Relationships>',
|
|
"ppt/slides/_rels/slide1.xml.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/notesSlide" Target="../notesSlides/notesSlide1.xml"/></Relationships>',
|
|
"ppt/presentation.xml": _XML
|
|
+ f"<p:presentation {_P}><p:sldIdLst>"
|
|
+ '<p:sldId id="256" r:id="rId1"/><p:sldId id="257" r:id="rId2"/>'
|
|
+ "</p:sldIdLst></p:presentation>",
|
|
"ppt/slides/slide1.xml": _slide("Kapittel 84 Boller", "Hevetider er gitt i tabell."),
|
|
"ppt/slides/slide2.xml": _slide("Utgaatt lysbilde", "Ikke vis dette.", hidden=True),
|
|
"ppt/notesSlides/notesSlide1.xml": _XML
|
|
+ f"<p:notes {_P} {_A}><p:cSld><p:spTree><p:sp><p:txBody>"
|
|
+ "<a:p><a:r><a:t>Husk aa nevne at hevetidsklassen er skjerpet.</a:t></a:r></a:p>"
|
|
+ "</p:txBody></p:sp></p:spTree></p:cSld></p:notes>",
|
|
}
|
|
|
|
|
|
# --- xlsx: a hidden sheet and a formula --------------------------------------
|
|
|
|
_XLSX_STRINGS = ["Post", "Enhet", "Mengde", "Sum", "Internt", "Kladd"]
|
|
|
|
_XLSX_PARTS: dict[str, str | bytes] = {
|
|
"[Content_Types].xml": _XML
|
|
+ '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'
|
|
+ '<Default Extension="xml" ContentType="application/xml"/>'
|
|
+ '<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.'
|
|
+ 'relationships+xml"/>'
|
|
+ '<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-'
|
|
+ 'officedocument.spreadsheetml.sheet.main+xml"/>'
|
|
# Declaring the parts is not decoration. Without the sharedStrings
|
|
# override every `t="s"` cell converts to an EMPTY cell -- the fixture
|
|
# would have reported four cells lost that the build never lost.
|
|
+ '<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>'
|
|
+ '<Override PartName="/xl/worksheets/sheet2.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>'
|
|
+ '<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.'
|
|
+ 'openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>'
|
|
+ "</Types>",
|
|
"_rels/.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>',
|
|
"xl/workbook.xml": _XML
|
|
+ f'<workbook {_S} xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships"><sheets>'
|
|
+ '<sheet name="Mengder" sheetId="1" r:id="rId1"/>'
|
|
+ '<sheet name="Internt" sheetId="2" state="hidden" r:id="rId2"/>'
|
|
+ "</sheets></workbook>",
|
|
"xl/_rels/workbook.xml.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/worksheet" Target="worksheets/sheet1.xml"/>'
|
|
+ '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/worksheet" Target="worksheets/sheet2.xml"/>'
|
|
# The shared string table is reached through the WORKBOOK's relationship,
|
|
# not by its path: without this line every `t="s"` cell converts empty and
|
|
# the fixture reports four cells lost that the build never lost.
|
|
+ '<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/sharedStrings" Target="sharedStrings.xml"/></Relationships>',
|
|
"xl/sharedStrings.xml": _XML
|
|
+ f'<sst {_S} count="{len(_XLSX_STRINGS)}" uniqueCount="{len(_XLSX_STRINGS)}">'
|
|
+ "".join(f"<si><t>{value}</t></si>" for value in _XLSX_STRINGS)
|
|
+ "</sst>",
|
|
"xl/worksheets/sheet1.xml": _XML
|
|
+ f'<worksheet {_S}><dimension ref="A1:C3"/><sheetData>'
|
|
+ '<row r="1"><c r="A1" t="s"><v>0</v></c><c r="B1" t="s"><v>1</v></c>'
|
|
+ '<c r="C1" t="s"><v>2</v></c></row>'
|
|
+ '<row r="2"><c r="A2" t="s"><v>3</v></c><c r="B2"><v>12</v></c>'
|
|
+ '<c r="C2"><f>B2*2</f><v>24</v></c></row>'
|
|
+ '</sheetData><drawing r:id="rId1" xmlns:r="http://schemas.openxmlformats.org/'
|
|
+ 'officeDocument/2006/relationships"/></worksheet>',
|
|
"xl/drawings/drawing1.xml": _XML
|
|
+ '<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/'
|
|
+ 'spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">'
|
|
+ "<xdr:twoCellAnchor><xdr:pic><xdr:nvPicPr>"
|
|
+ '<xdr:cNvPr id="1" name="Diagram"/>'
|
|
+ "</xdr:nvPicPr></xdr:pic></xdr:twoCellAnchor></xdr:wsDr>",
|
|
"xl/worksheets/_rels/sheet1.xml.rels": _XML
|
|
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
|
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
|
|
+ 'relationships/drawing" Target="../drawings/drawing1.xml"/></Relationships>',
|
|
"xl/worksheets/sheet2.xml": _XML
|
|
+ f'<worksheet {_S}><dimension ref="A1:A1"/><sheetData>'
|
|
+ '<row r="1"><c r="A1" t="s"><v>5</v></c></row>'
|
|
+ "</sheetData></worksheet>",
|
|
}
|
|
|
|
|
|
# --- odt: a header, a list, an annotation and a picture ----------------------
|
|
|
|
_ODT_NS = (
|
|
'xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" '
|
|
'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" '
|
|
'xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" '
|
|
'xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" '
|
|
'xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" '
|
|
'xmlns:xlink="http://www.w3.org/1999/xlink"'
|
|
)
|
|
|
|
_ODT_PARTS: dict[str, str | bytes] = {
|
|
"mimetype": "application/vnd.oasis.opendocument.text",
|
|
"META-INF/manifest.xml": _XML
|
|
+ '<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">'
|
|
+ '<manifest:file-entry manifest:full-path="/" manifest:media-type="application/vnd.oasis.'
|
|
+ 'opendocument.text"/>'
|
|
+ '<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>'
|
|
+ "</manifest:manifest>",
|
|
"content.xml": _XML
|
|
+ f'<office:document-content {_ODT_NS} office:version="1.3">'
|
|
+ "<office:body><office:text>"
|
|
+ '<text:h text:outline-level="1">Stell av bakebrett</text:h>'
|
|
+ "<text:p>Bakebrett vaskes hver uke.</text:p>"
|
|
+ "<text:list><text:list-item><text:p>Kant</text:p></text:list-item>"
|
|
+ "<text:list-item><text:p>Flate</text:p></text:list-item></text:list>"
|
|
+ "<text:p>Se figuren under."
|
|
+ '<draw:frame><draw:image xlink:href="graphics/figur-84-1.png"/></draw:frame></text:p>'
|
|
+ "<office:annotation><text:p>Sjekk denne mot Q400 foer utsendelse.</text:p>"
|
|
+ "</office:annotation>"
|
|
+ "<table:table><table:table-row>"
|
|
+ "<table:table-cell><text:p>Type</text:p></table:table-cell>"
|
|
+ "<table:table-cell><text:p>Bakebrett</text:p></table:table-cell>"
|
|
+ "</table:table-row></table:table>"
|
|
+ "</office:text></office:body></office:document-content>",
|
|
"styles.xml": _XML
|
|
+ f'<office:document-styles {_ODT_NS} office:version="1.3">'
|
|
+ "<office:styles/><office:master-styles>"
|
|
+ '<style:master-page style:name="Standard">'
|
|
+ "<style:header><text:p>Intern arbeidsversjon</text:p></style:header>"
|
|
+ "<style:footer><text:p>Eksempelforlaget</text:p></style:footer>"
|
|
+ "</style:master-page></office:master-styles></office:document-styles>",
|
|
}
|
|
|
|
|
|
# --- rtf: a picture ----------------------------------------------------------
|
|
|
|
_RTF = (
|
|
r"{\rtf1\ansi\deff0{\fonttbl{\f0 Times New Roman;}}"
|
|
r"\pard Figur 84-1 viser prinsippet.\par"
|
|
r"\pard{\pict\pngblip\picw16\pich16 89504e470d0a1a0a}\par"
|
|
"}"
|
|
)
|
|
|
|
|
|
# --- html: a picture and a caption -------------------------------------------
|
|
|
|
_HTML = """<!DOCTYPE html>
|
|
<html lang="no">
|
|
<head><title>Figur 84-1</title></head>
|
|
<body>
|
|
<h1>Figur 84-1</h1>
|
|
<p>Prinsippet for hevetidsklasser.</p>
|
|
<img src="graphics/figur-84-1.png" alt="Prinsippskisse">
|
|
<table><tr><th>Klasse</th><th>Avvik</th></tr><tr><td>A</td><td>5 min</td></tr></table>
|
|
<ul><li>Klasse A</li><li>Klasse B</li></ul>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
|
|
# --- sts: a citation, a formula, a figure with a caption, a table, a footnote -
|
|
|
|
_STS = """<standard>
|
|
<front><std-ident><doc-number>P762</doc-number><year>2025</year></std-ident></front>
|
|
<body>
|
|
<sec><label>85</label><title>Bakeplater</title>
|
|
<p>Platen skal ha jevn varme etter <mixed-citation>EKS 1234-1:2030</mixed-citation>.</p>
|
|
<p>Kravet regnes som <mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>T</mml:mi><mml:mo><</mml:mo><mml:mn>2</mml:mn></mml:math>.</p>
|
|
<fig><label>Figur 85-1</label><caption><p>Maalepunkter langs bakeplaten.</p></caption>
|
|
<graphic xlink:href="figur-84-1.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></fig>
|
|
<table-wrap><label>Tabell 85-1</label>
|
|
<table><tr><th>Klasse</th><th>T</th></tr><tr><td>1</td><td>1,5</td></tr></table>
|
|
</table-wrap>
|
|
<list><list-item><p>Maales hver 20. centimeter.</p></list-item></list>
|
|
<fn><p>Gjelder ikke steinovner.</p></fn>
|
|
</sec>
|
|
</body>
|
|
</standard>
|
|
"""
|
|
|
|
|
|
def main() -> int:
|
|
written = {
|
|
"topptekst-og-kommentar.docx": build_zip(_DOCX_PARTS),
|
|
"notater-og-skjult.pptx": build_zip(_PPTX_PARTS),
|
|
"skjult-ark-og-formel.xlsx": build_zip(_XLSX_PARTS),
|
|
"liste-og-bilde.odt": build_zip(_ODT_PARTS),
|
|
"bilde.rtf": _RTF.encode("latin-1"),
|
|
"figur.html": _HTML.encode("utf-8"),
|
|
"sts-rikt.xml": _STS.encode("utf-8"),
|
|
}
|
|
for name, payload in written.items():
|
|
(CORPUS / name).write_bytes(payload)
|
|
print(f"wrote {name}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|