@usejunior/docx-core 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -21
- package/NOTICE +2 -0
- package/README.md +2 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/atomizer.d.ts +13 -7
- package/dist/atomizer.d.ts.map +1 -1
- package/dist/atomizer.js +59 -24
- package/dist/atomizer.js.map +1 -1
- package/dist/baselines/atomizer/auxiliaryIdCollision.d.ts +99 -0
- package/dist/baselines/atomizer/auxiliaryIdCollision.d.ts.map +1 -0
- package/dist/baselines/atomizer/auxiliaryIdCollision.js +415 -0
- package/dist/baselines/atomizer/auxiliaryIdCollision.js.map +1 -0
- package/dist/baselines/atomizer/documentReconstructor.d.ts.map +1 -1
- package/dist/baselines/atomizer/documentReconstructor.js +120 -27
- package/dist/baselines/atomizer/documentReconstructor.js.map +1 -1
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.d.ts +9 -0
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.d.ts.map +1 -1
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.js +52 -4
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.js.map +1 -1
- package/dist/baselines/atomizer/pipeline.d.ts +12 -53
- package/dist/baselines/atomizer/pipeline.d.ts.map +1 -1
- package/dist/baselines/atomizer/pipeline.js +126 -231
- package/dist/baselines/atomizer/pipeline.js.map +1 -1
- package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts.map +1 -1
- package/dist/baselines/atomizer/trackChangesAcceptorAst.js +153 -23
- package/dist/baselines/atomizer/trackChangesAcceptorAst.js.map +1 -1
- package/dist/baselines/wmlcomparer/DotnetCli.d.ts.map +1 -1
- package/dist/baselines/wmlcomparer/DotnetCli.js +7 -0
- package/dist/baselines/wmlcomparer/DotnetCli.js.map +1 -1
- package/dist/cli/compare-two.d.ts.map +1 -1
- package/dist/cli/compare-two.js +3 -1
- package/dist/cli/compare-two.js.map +1 -1
- package/dist/cli/conformance-adapter.d.ts +3 -0
- package/dist/cli/conformance-adapter.d.ts.map +1 -0
- package/dist/cli/conformance-adapter.js +93 -0
- package/dist/cli/conformance-adapter.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/compare-types.d.ts +46 -0
- package/dist/compare-types.d.ts.map +1 -1
- package/dist/generation/compile.d.ts +22 -0
- package/dist/generation/compile.d.ts.map +1 -0
- package/dist/generation/compile.js +58 -0
- package/dist/generation/compile.js.map +1 -0
- package/dist/generation/context.d.ts +42 -0
- package/dist/generation/context.d.ts.map +1 -0
- package/dist/generation/context.js +65 -0
- package/dist/generation/context.js.map +1 -0
- package/dist/generation/emit/comments-part.d.ts +36 -0
- package/dist/generation/emit/comments-part.d.ts.map +1 -0
- package/dist/generation/emit/comments-part.js +116 -0
- package/dist/generation/emit/comments-part.js.map +1 -0
- package/dist/generation/emit/document-part.d.ts +24 -0
- package/dist/generation/emit/document-part.d.ts.map +1 -0
- package/dist/generation/emit/document-part.js +60 -0
- package/dist/generation/emit/document-part.js.map +1 -0
- package/dist/generation/emit/emit-context.d.ts +28 -0
- package/dist/generation/emit/emit-context.d.ts.map +1 -0
- package/dist/generation/emit/emit-context.js +19 -0
- package/dist/generation/emit/emit-context.js.map +1 -0
- package/dist/generation/emit/font-table-part.d.ts +16 -0
- package/dist/generation/emit/font-table-part.d.ts.map +1 -0
- package/dist/generation/emit/font-table-part.js +74 -0
- package/dist/generation/emit/font-table-part.js.map +1 -0
- package/dist/generation/emit/header-footer-part.d.ts +23 -0
- package/dist/generation/emit/header-footer-part.d.ts.map +1 -0
- package/dist/generation/emit/header-footer-part.js +57 -0
- package/dist/generation/emit/header-footer-part.js.map +1 -0
- package/dist/generation/emit/numbering-part.d.ts +29 -0
- package/dist/generation/emit/numbering-part.d.ts.map +1 -0
- package/dist/generation/emit/numbering-part.js +102 -0
- package/dist/generation/emit/numbering-part.js.map +1 -0
- package/dist/generation/emit/package-parts.d.ts +24 -0
- package/dist/generation/emit/package-parts.d.ts.map +1 -0
- package/dist/generation/emit/package-parts.js +121 -0
- package/dist/generation/emit/package-parts.js.map +1 -0
- package/dist/generation/emit/paragraph.d.ts +24 -0
- package/dist/generation/emit/paragraph.d.ts.map +1 -0
- package/dist/generation/emit/paragraph.js +63 -0
- package/dist/generation/emit/paragraph.js.map +1 -0
- package/dist/generation/emit/properties.d.ts +36 -0
- package/dist/generation/emit/properties.d.ts.map +1 -0
- package/dist/generation/emit/properties.js +154 -0
- package/dist/generation/emit/properties.js.map +1 -0
- package/dist/generation/emit/run.d.ts +16 -0
- package/dist/generation/emit/run.d.ts.map +1 -0
- package/dist/generation/emit/run.js +71 -0
- package/dist/generation/emit/run.js.map +1 -0
- package/dist/generation/emit/section.d.ts +29 -0
- package/dist/generation/emit/section.d.ts.map +1 -0
- package/dist/generation/emit/section.js +117 -0
- package/dist/generation/emit/section.js.map +1 -0
- package/dist/generation/emit/settings-part.d.ts +13 -0
- package/dist/generation/emit/settings-part.d.ts.map +1 -0
- package/dist/generation/emit/settings-part.js +68 -0
- package/dist/generation/emit/settings-part.js.map +1 -0
- package/dist/generation/emit/styles-part.d.ts +16 -0
- package/dist/generation/emit/styles-part.d.ts.map +1 -0
- package/dist/generation/emit/styles-part.js +82 -0
- package/dist/generation/emit/styles-part.js.map +1 -0
- package/dist/generation/emit/table.d.ts +26 -0
- package/dist/generation/emit/table.d.ts.map +1 -0
- package/dist/generation/emit/table.js +209 -0
- package/dist/generation/emit/table.js.map +1 -0
- package/dist/generation/emit/theme-part.d.ts +21 -0
- package/dist/generation/emit/theme-part.d.ts.map +1 -0
- package/dist/generation/emit/theme-part.js +151 -0
- package/dist/generation/emit/theme-part.js.map +1 -0
- package/dist/generation/emit/web-settings-part.d.ts +12 -0
- package/dist/generation/emit/web-settings-part.d.ts.map +1 -0
- package/dist/generation/emit/web-settings-part.js +19 -0
- package/dist/generation/emit/web-settings-part.js.map +1 -0
- package/dist/generation/errors.d.ts +22 -0
- package/dist/generation/errors.d.ts.map +1 -0
- package/dist/generation/errors.js +29 -0
- package/dist/generation/errors.js.map +1 -0
- package/dist/generation/index.d.ts +13 -0
- package/dist/generation/index.d.ts.map +1 -0
- package/dist/generation/index.js +12 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/generation/ordering.d.ts +46 -0
- package/dist/generation/ordering.d.ts.map +1 -0
- package/dist/generation/ordering.js +119 -0
- package/dist/generation/ordering.js.map +1 -0
- package/dist/generation/recipes.d.ts +70 -0
- package/dist/generation/recipes.d.ts.map +1 -0
- package/dist/generation/recipes.js +149 -0
- package/dist/generation/recipes.js.map +1 -0
- package/dist/generation/structural-checks.d.ts +24 -0
- package/dist/generation/structural-checks.d.ts.map +1 -0
- package/dist/generation/structural-checks.js +318 -0
- package/dist/generation/structural-checks.js.map +1 -0
- package/dist/generation/theme-colors.d.ts +4 -0
- package/dist/generation/theme-colors.d.ts.map +1 -0
- package/dist/generation/theme-colors.js +18 -0
- package/dist/generation/theme-colors.js.map +1 -0
- package/dist/generation/types.d.ts +249 -0
- package/dist/generation/types.d.ts.map +1 -0
- package/dist/generation/types.js +54 -0
- package/dist/generation/types.js.map +1 -0
- package/dist/generation/validate-spec.d.ts +27 -0
- package/dist/generation/validate-spec.d.ts.map +1 -0
- package/dist/generation/validate-spec.js +359 -0
- package/dist/generation/validate-spec.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/integration/generation-probes.d.ts +15 -0
- package/dist/integration/generation-probes.d.ts.map +1 -0
- package/dist/integration/generation-probes.js +84 -0
- package/dist/integration/generation-probes.js.map +1 -0
- package/dist/integration/libreoffice-oracle.d.ts +8 -0
- package/dist/integration/libreoffice-oracle.d.ts.map +1 -1
- package/dist/integration/libreoffice-oracle.js +14 -6
- package/dist/integration/libreoffice-oracle.js.map +1 -1
- package/dist/integration/synthetic-docx-fixture.d.ts +72 -0
- package/dist/integration/synthetic-docx-fixture.d.ts.map +1 -1
- package/dist/integration/synthetic-docx-fixture.js +131 -4
- package/dist/integration/synthetic-docx-fixture.js.map +1 -1
- package/dist/primitives/accept_changes.d.ts +2 -1
- package/dist/primitives/accept_changes.d.ts.map +1 -1
- package/dist/primitives/accept_changes.js +153 -12
- package/dist/primitives/accept_changes.js.map +1 -1
- package/dist/primitives/document.d.ts +38 -0
- package/dist/primitives/document.d.ts.map +1 -1
- package/dist/primitives/document.js +75 -9
- package/dist/primitives/document.js.map +1 -1
- package/dist/primitives/document_view-comments.d.ts.map +1 -1
- package/dist/primitives/document_view-comments.js +4 -3
- package/dist/primitives/document_view-comments.js.map +1 -1
- package/dist/primitives/document_view-types.d.ts +15 -0
- package/dist/primitives/document_view-types.d.ts.map +1 -1
- package/dist/primitives/document_view.d.ts.map +1 -1
- package/dist/primitives/document_view.js +21 -13
- package/dist/primitives/document_view.js.map +1 -1
- package/dist/primitives/formatting_tags.d.ts +1 -0
- package/dist/primitives/formatting_tags.d.ts.map +1 -1
- package/dist/primitives/formatting_tags.js +16 -10
- package/dist/primitives/formatting_tags.js.map +1 -1
- package/dist/primitives/index.d.ts +4 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +4 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/layout.d.ts.map +1 -1
- package/dist/primitives/layout.js +13 -0
- package/dist/primitives/layout.js.map +1 -1
- package/dist/primitives/minimal_save.d.ts +38 -0
- package/dist/primitives/minimal_save.d.ts.map +1 -0
- package/dist/primitives/minimal_save.js +323 -0
- package/dist/primitives/minimal_save.js.map +1 -0
- package/dist/primitives/namespaces.d.ts +46 -0
- package/dist/primitives/namespaces.d.ts.map +1 -1
- package/dist/primitives/namespaces.js +49 -0
- package/dist/primitives/namespaces.js.map +1 -1
- package/dist/primitives/reject_changes.d.ts +4 -2
- package/dist/primitives/reject_changes.d.ts.map +1 -1
- package/dist/primitives/reject_changes.js +177 -24
- package/dist/primitives/reject_changes.js.map +1 -1
- package/dist/primitives/revision-parts.d.ts +7 -0
- package/dist/primitives/revision-parts.d.ts.map +1 -0
- package/dist/primitives/revision-parts.js +27 -0
- package/dist/primitives/revision-parts.js.map +1 -0
- package/dist/primitives/revision-vocabulary.d.ts +7 -0
- package/dist/primitives/revision-vocabulary.d.ts.map +1 -0
- package/dist/primitives/revision-vocabulary.js +39 -0
- package/dist/primitives/revision-vocabulary.js.map +1 -0
- package/dist/primitives/schema-corpus-capture.d.ts +19 -0
- package/dist/primitives/schema-corpus-capture.d.ts.map +1 -0
- package/dist/primitives/schema-corpus-capture.js +29 -0
- package/dist/primitives/schema-corpus-capture.js.map +1 -0
- package/dist/primitives/sectPrAudit.d.ts +19 -0
- package/dist/primitives/sectPrAudit.d.ts.map +1 -0
- package/dist/primitives/sectPrAudit.js +165 -0
- package/dist/primitives/sectPrAudit.js.map +1 -0
- package/dist/primitives/semantic_tags.d.ts.map +1 -1
- package/dist/primitives/semantic_tags.js +2 -1
- package/dist/primitives/semantic_tags.js.map +1 -1
- package/dist/primitives/serialize_html.d.ts +1 -0
- package/dist/primitives/serialize_html.d.ts.map +1 -1
- package/dist/primitives/serialize_html.js +4 -2
- package/dist/primitives/serialize_html.js.map +1 -1
- package/dist/primitives/styles.d.ts +15 -0
- package/dist/primitives/styles.d.ts.map +1 -1
- package/dist/primitives/styles.js +11 -0
- package/dist/primitives/styles.js.map +1 -1
- package/dist/primitives/track-changes-emitter.d.ts +9 -0
- package/dist/primitives/track-changes-emitter.d.ts.map +1 -1
- package/dist/primitives/track-changes-emitter.js +54 -4
- package/dist/primitives/track-changes-emitter.js.map +1 -1
- package/dist/primitives/validate_ai_revisions.d.ts +35 -0
- package/dist/primitives/validate_ai_revisions.d.ts.map +1 -0
- package/dist/primitives/validate_ai_revisions.js +323 -0
- package/dist/primitives/validate_ai_revisions.js.map +1 -0
- package/dist/primitives/xml.d.ts +5 -0
- package/dist/primitives/xml.d.ts.map +1 -1
- package/dist/primitives/xml.js +5 -0
- package/dist/primitives/xml.js.map +1 -1
- package/dist/primitives/zip.d.ts +1 -0
- package/dist/primitives/zip.d.ts.map +1 -1
- package/dist/primitives/zip.js +21 -3
- package/dist/primitives/zip.js.map +1 -1
- package/dist/shared/field-structure.d.ts +14 -0
- package/dist/shared/field-structure.d.ts.map +1 -0
- package/dist/shared/field-structure.js +166 -0
- package/dist/shared/field-structure.js.map +1 -0
- package/package.json +7 -4
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-build structural validation of a generated package — the
|
|
3
|
+
* "no recovery dialog" gate. Each check targets a concrete repair trigger in
|
|
4
|
+
* reading applications: missing content types, dangling relationship targets,
|
|
5
|
+
* unresolvable r:id references, malformed section properties, and unbalanced
|
|
6
|
+
* field characters.
|
|
7
|
+
*
|
|
8
|
+
* `auditSectPr` is reused as one component: it flags duplicated or misplaced
|
|
9
|
+
* body-level sectPr and dangling header/footer references, but tolerates the
|
|
10
|
+
* zero-sectPr case (legal for parsed third-party documents), so the
|
|
11
|
+
* required-final-sectPr check lives here.
|
|
12
|
+
*/
|
|
13
|
+
import { auditSectPr } from '../primitives/sectPrAudit.js';
|
|
14
|
+
import { NODE_TYPE } from '../primitives/dom-helpers.js';
|
|
15
|
+
import { OOXML } from '../primitives/namespaces.js';
|
|
16
|
+
import { parseXml } from '../primitives/xml.js';
|
|
17
|
+
import { DocxZip } from '../primitives/zip.js';
|
|
18
|
+
/** Run every structural check against a generated package buffer. */
|
|
19
|
+
export async function checkGeneratedPackage(buffer) {
|
|
20
|
+
const zip = await DocxZip.load(buffer);
|
|
21
|
+
const files = zip.listFiles().filter((name) => !name.endsWith('/'));
|
|
22
|
+
const contents = new Map();
|
|
23
|
+
for (const name of files) {
|
|
24
|
+
contents.set(name, await zip.readText(name));
|
|
25
|
+
}
|
|
26
|
+
const issues = [
|
|
27
|
+
...checkXmlDeclarations(contents),
|
|
28
|
+
...checkContentTypeCoverage(contents),
|
|
29
|
+
...checkRelationshipTargets(contents),
|
|
30
|
+
...checkRidResolution(contents),
|
|
31
|
+
...checkSectPr(contents),
|
|
32
|
+
...checkFieldPairing(contents),
|
|
33
|
+
...checkTables(contents),
|
|
34
|
+
];
|
|
35
|
+
return { ok: issues.length === 0, issues };
|
|
36
|
+
}
|
|
37
|
+
function isXmlPart(name) {
|
|
38
|
+
return name.endsWith('.xml') || name.endsWith('.rels');
|
|
39
|
+
}
|
|
40
|
+
function checkXmlDeclarations(contents) {
|
|
41
|
+
const issues = [];
|
|
42
|
+
for (const [name, text] of contents) {
|
|
43
|
+
if (!isXmlPart(name))
|
|
44
|
+
continue;
|
|
45
|
+
if (!text.startsWith('<?xml')) {
|
|
46
|
+
issues.push({
|
|
47
|
+
check: 'xml_declaration',
|
|
48
|
+
part: name,
|
|
49
|
+
message: 'XML part does not begin with an <?xml declaration',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return issues;
|
|
54
|
+
}
|
|
55
|
+
function checkContentTypeCoverage(contents) {
|
|
56
|
+
const issues = [];
|
|
57
|
+
const contentTypes = contents.get('[Content_Types].xml');
|
|
58
|
+
if (!contentTypes) {
|
|
59
|
+
return [{ check: 'content_type_coverage', part: '[Content_Types].xml', message: 'Part is missing' }];
|
|
60
|
+
}
|
|
61
|
+
const doc = parseXml(contentTypes);
|
|
62
|
+
const defaults = new Set();
|
|
63
|
+
const overrides = new Set();
|
|
64
|
+
for (const el of Array.from(doc.getElementsByTagName('Default'))) {
|
|
65
|
+
const ext = el.getAttribute('Extension');
|
|
66
|
+
if (ext)
|
|
67
|
+
defaults.add(ext.toLowerCase());
|
|
68
|
+
}
|
|
69
|
+
for (const el of Array.from(doc.getElementsByTagName('Override'))) {
|
|
70
|
+
const part = el.getAttribute('PartName');
|
|
71
|
+
if (part)
|
|
72
|
+
overrides.add(part);
|
|
73
|
+
}
|
|
74
|
+
for (const name of contents.keys()) {
|
|
75
|
+
if (name === '[Content_Types].xml')
|
|
76
|
+
continue;
|
|
77
|
+
const extension = name.split('.').pop()?.toLowerCase() ?? '';
|
|
78
|
+
if (!overrides.has(`/${name}`) && !defaults.has(extension)) {
|
|
79
|
+
issues.push({
|
|
80
|
+
check: 'content_type_coverage',
|
|
81
|
+
part: name,
|
|
82
|
+
message: 'Part is covered by neither a content-type Default nor an Override',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return issues;
|
|
87
|
+
}
|
|
88
|
+
/** Directory ('word/' or '') whose relationships a .rels part declares. */
|
|
89
|
+
function relsOwnerDir(relsName) {
|
|
90
|
+
const marker = '_rels/';
|
|
91
|
+
const idx = relsName.lastIndexOf(marker);
|
|
92
|
+
return idx <= 0 ? '' : relsName.slice(0, idx);
|
|
93
|
+
}
|
|
94
|
+
function resolveTarget(ownerDir, target) {
|
|
95
|
+
const joined = target.startsWith('/') ? target.slice(1) : ownerDir + target;
|
|
96
|
+
const segments = [];
|
|
97
|
+
for (const segment of joined.split('/')) {
|
|
98
|
+
if (segment === '' || segment === '.')
|
|
99
|
+
continue;
|
|
100
|
+
if (segment === '..')
|
|
101
|
+
segments.pop();
|
|
102
|
+
else
|
|
103
|
+
segments.push(segment);
|
|
104
|
+
}
|
|
105
|
+
return segments.join('/');
|
|
106
|
+
}
|
|
107
|
+
function checkRelationshipTargets(contents) {
|
|
108
|
+
const issues = [];
|
|
109
|
+
for (const [name, text] of contents) {
|
|
110
|
+
if (!name.endsWith('.rels'))
|
|
111
|
+
continue;
|
|
112
|
+
const ownerDir = relsOwnerDir(name);
|
|
113
|
+
const doc = parseXml(text);
|
|
114
|
+
for (const rel of Array.from(doc.getElementsByTagName('Relationship'))) {
|
|
115
|
+
if (rel.getAttribute('TargetMode') === 'External')
|
|
116
|
+
continue;
|
|
117
|
+
const target = rel.getAttribute('Target');
|
|
118
|
+
if (!target) {
|
|
119
|
+
issues.push({ check: 'relationship_target', part: name, message: 'Relationship without Target' });
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const resolved = resolveTarget(ownerDir, target);
|
|
123
|
+
if (!contents.has(resolved)) {
|
|
124
|
+
issues.push({
|
|
125
|
+
check: 'relationship_target',
|
|
126
|
+
part: name,
|
|
127
|
+
message: `Relationship target '${target}' resolves to missing part '${resolved}'`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return issues;
|
|
133
|
+
}
|
|
134
|
+
function relsIdsFor(contents, partName) {
|
|
135
|
+
const dir = partName.includes('/') ? partName.slice(0, partName.lastIndexOf('/') + 1) : '';
|
|
136
|
+
const base = partName.slice(dir.length);
|
|
137
|
+
const relsName = `${dir}_rels/${base}.rels`;
|
|
138
|
+
const ids = new Set();
|
|
139
|
+
const text = contents.get(relsName);
|
|
140
|
+
if (!text)
|
|
141
|
+
return ids;
|
|
142
|
+
const doc = parseXml(text);
|
|
143
|
+
for (const rel of Array.from(doc.getElementsByTagName('Relationship'))) {
|
|
144
|
+
const id = rel.getAttribute('Id');
|
|
145
|
+
if (id)
|
|
146
|
+
ids.add(id);
|
|
147
|
+
}
|
|
148
|
+
return ids;
|
|
149
|
+
}
|
|
150
|
+
function checkRidResolution(contents) {
|
|
151
|
+
const issues = [];
|
|
152
|
+
for (const [name, text] of contents) {
|
|
153
|
+
if (!name.startsWith('word/') || !name.endsWith('.xml'))
|
|
154
|
+
continue;
|
|
155
|
+
const ids = relsIdsFor(contents, name);
|
|
156
|
+
const doc = parseXml(text);
|
|
157
|
+
const visit = (el) => {
|
|
158
|
+
for (let i = 0; i < el.attributes.length; i++) {
|
|
159
|
+
const attr = el.attributes[i];
|
|
160
|
+
const isRid = attr.namespaceURI === OOXML.R_NS || attr.name === 'r:id' || attr.name === 'r:embed';
|
|
161
|
+
if (!isRid)
|
|
162
|
+
continue;
|
|
163
|
+
if (!ids.has(attr.value)) {
|
|
164
|
+
issues.push({
|
|
165
|
+
check: 'rid_resolution',
|
|
166
|
+
part: name,
|
|
167
|
+
message: `<${el.tagName}> references relationship '${attr.value}' missing from this part's rels`,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
for (let i = 0; i < el.childNodes.length; i++) {
|
|
172
|
+
const child = el.childNodes[i];
|
|
173
|
+
if (child.nodeType === NODE_TYPE.ELEMENT)
|
|
174
|
+
visit(child);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
if (doc.documentElement)
|
|
178
|
+
visit(doc.documentElement);
|
|
179
|
+
}
|
|
180
|
+
return issues;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Generated documents must bind their final section explicitly: exactly one
|
|
184
|
+
* body-level w:sectPr, positioned last. auditSectPr supplies the placement
|
|
185
|
+
* and reference checks but allows the zero-sectPr case, hence the count
|
|
186
|
+
* assertion here.
|
|
187
|
+
*
|
|
188
|
+
* @conformance ECMA-376 edition 5, Part 1 § 17.6.17
|
|
189
|
+
*/
|
|
190
|
+
function checkSectPr(contents) {
|
|
191
|
+
const issues = [];
|
|
192
|
+
const documentXml = contents.get('word/document.xml');
|
|
193
|
+
if (!documentXml) {
|
|
194
|
+
return [{ check: 'sectpr', part: 'word/document.xml', message: 'Part is missing' }];
|
|
195
|
+
}
|
|
196
|
+
const audit = auditSectPr(documentXml, contents.get('word/_rels/document.xml.rels') ?? null);
|
|
197
|
+
for (const issue of audit.issues) {
|
|
198
|
+
issues.push({ check: 'sectpr', part: 'word/document.xml', message: `${issue.type}: ${issue.message}` });
|
|
199
|
+
}
|
|
200
|
+
if (audit.stats.bodyLevelSectPrCount !== 1) {
|
|
201
|
+
issues.push({
|
|
202
|
+
check: 'sectpr',
|
|
203
|
+
part: 'word/document.xml',
|
|
204
|
+
message: `Expected exactly one body-level w:sectPr, found ${audit.stats.bodyLevelSectPrCount}`,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return issues;
|
|
208
|
+
}
|
|
209
|
+
function isStoryPart(name) {
|
|
210
|
+
return (name === 'word/document.xml' ||
|
|
211
|
+
/^word\/header\d+\.xml$/.test(name) ||
|
|
212
|
+
/^word\/footer\d+\.xml$/.test(name) ||
|
|
213
|
+
name === 'word/footnotes.xml' ||
|
|
214
|
+
name === 'word/endnotes.xml' ||
|
|
215
|
+
name === 'word/comments.xml');
|
|
216
|
+
}
|
|
217
|
+
function checkFieldPairing(contents) {
|
|
218
|
+
const issues = [];
|
|
219
|
+
for (const [name, text] of contents) {
|
|
220
|
+
if (!isStoryPart(name))
|
|
221
|
+
continue;
|
|
222
|
+
const doc = parseXml(text);
|
|
223
|
+
// Document-order walk over field-relevant leaves; fldChar transitions
|
|
224
|
+
// drive a begin → separate → end state machine per story part.
|
|
225
|
+
let state = 'idle';
|
|
226
|
+
const visit = (el) => {
|
|
227
|
+
if (el.tagName === 'w:fldChar') {
|
|
228
|
+
const type = el.getAttribute('w:fldCharType');
|
|
229
|
+
if (type === 'begin') {
|
|
230
|
+
if (state !== 'idle') {
|
|
231
|
+
issues.push({ check: 'field_pairing', part: name, message: 'fldChar begin while a field is already open' });
|
|
232
|
+
}
|
|
233
|
+
state = 'instr';
|
|
234
|
+
}
|
|
235
|
+
else if (type === 'separate') {
|
|
236
|
+
if (state !== 'instr') {
|
|
237
|
+
issues.push({ check: 'field_pairing', part: name, message: 'fldChar separate without a matching begin' });
|
|
238
|
+
}
|
|
239
|
+
state = 'result';
|
|
240
|
+
}
|
|
241
|
+
else if (type === 'end') {
|
|
242
|
+
if (state === 'idle') {
|
|
243
|
+
issues.push({ check: 'field_pairing', part: name, message: 'fldChar end without a matching begin' });
|
|
244
|
+
}
|
|
245
|
+
state = 'idle';
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (el.tagName === 'w:instrText') {
|
|
249
|
+
if (state !== 'instr') {
|
|
250
|
+
issues.push({
|
|
251
|
+
check: 'field_pairing',
|
|
252
|
+
part: name,
|
|
253
|
+
message: 'w:instrText outside a begin→separate range',
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
for (let i = 0; i < el.childNodes.length; i++) {
|
|
258
|
+
const child = el.childNodes[i];
|
|
259
|
+
if (child.nodeType === NODE_TYPE.ELEMENT)
|
|
260
|
+
visit(child);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
if (doc.documentElement)
|
|
264
|
+
visit(doc.documentElement);
|
|
265
|
+
if (state !== 'idle') {
|
|
266
|
+
issues.push({ check: 'field_pairing', part: name, message: 'Unclosed field at end of story part' });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return issues;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Table invariants readers actually enforce: every cell ends with a w:p,
|
|
273
|
+
* and the document body never ends with a table (the element preceding the
|
|
274
|
+
* body-level sectPr, or the last body child, must not be w:tbl).
|
|
275
|
+
*
|
|
276
|
+
* @conformance ECMA-376 edition 5, Part 1 § 17.4.65
|
|
277
|
+
*/
|
|
278
|
+
function checkTables(contents) {
|
|
279
|
+
const issues = [];
|
|
280
|
+
for (const [name, text] of contents) {
|
|
281
|
+
if (!isStoryPart(name))
|
|
282
|
+
continue;
|
|
283
|
+
const doc = parseXml(text);
|
|
284
|
+
for (const tc of Array.from(doc.getElementsByTagName('w:tc'))) {
|
|
285
|
+
let last = null;
|
|
286
|
+
for (let child = tc.firstChild; child; child = child.nextSibling) {
|
|
287
|
+
if (child.nodeType === NODE_TYPE.ELEMENT)
|
|
288
|
+
last = child;
|
|
289
|
+
}
|
|
290
|
+
if (!last || last.tagName !== 'w:p') {
|
|
291
|
+
issues.push({
|
|
292
|
+
check: 'table',
|
|
293
|
+
part: name,
|
|
294
|
+
message: `Table cell ends with <${last?.tagName ?? 'nothing'}> instead of a w:p`,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (name !== 'word/document.xml')
|
|
299
|
+
continue;
|
|
300
|
+
const body = doc.getElementsByTagName('w:body').item(0);
|
|
301
|
+
if (!body)
|
|
302
|
+
continue;
|
|
303
|
+
let lastContent = null;
|
|
304
|
+
for (let child = body.firstChild; child; child = child.nextSibling) {
|
|
305
|
+
if (child.nodeType !== NODE_TYPE.ELEMENT)
|
|
306
|
+
continue;
|
|
307
|
+
const el = child;
|
|
308
|
+
if (el.tagName === 'w:sectPr')
|
|
309
|
+
continue;
|
|
310
|
+
lastContent = el;
|
|
311
|
+
}
|
|
312
|
+
if (lastContent && lastContent.tagName === 'w:tbl') {
|
|
313
|
+
issues.push({ check: 'table', part: name, message: 'Document body ends with a w:tbl' });
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return issues;
|
|
317
|
+
}
|
|
318
|
+
//# sourceMappingURL=structural-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-checks.js","sourceRoot":"","sources":["../../src/generation/structural-checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DocumentThemeSpec, ThemeColorSlot } from './types.js';
|
|
2
|
+
export declare const CANONICAL_THEME_COLORS: Record<ThemeColorSlot, string>;
|
|
3
|
+
export declare function resolveThemeColorValues(theme?: DocumentThemeSpec): ReadonlyMap<ThemeColorSlot, string>;
|
|
4
|
+
//# sourceMappingURL=theme-colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-colors.d.ts","sourceRoot":"","sources":["../../src/generation/theme-colors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEpE,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAajE,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,CAEtG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const CANONICAL_THEME_COLORS = {
|
|
2
|
+
text1: '000000',
|
|
3
|
+
background1: 'FFFFFF',
|
|
4
|
+
text2: '44546A',
|
|
5
|
+
background2: 'E7E6E6',
|
|
6
|
+
accent1: '4472C4',
|
|
7
|
+
accent2: 'ED7D31',
|
|
8
|
+
accent3: 'A5A5A5',
|
|
9
|
+
accent4: 'FFC000',
|
|
10
|
+
accent5: '5B9BD5',
|
|
11
|
+
accent6: '70AD47',
|
|
12
|
+
hyperlink: '0563C1',
|
|
13
|
+
followedHyperlink: '954F72',
|
|
14
|
+
};
|
|
15
|
+
export function resolveThemeColorValues(theme) {
|
|
16
|
+
return new Map(Object.entries({ ...CANONICAL_THEME_COLORS, ...(theme?.colors ?? {}) }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=theme-colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-colors.js","sourceRoot":"","sources":["../../src/generation/theme-colors.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAmC;IACpE,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,QAAQ;IACrB,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,QAAQ;IACrB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,SAAS,EAAE,QAAQ;IACnB,iBAAiB,EAAE,QAAQ;CAC5B,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,KAAyB;IAC/D,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,sBAAsB,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,CAAoC,CAAC,CAAC;AAC7H,CAAC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarative document specification for from-scratch DOCX generation.
|
|
3
|
+
*
|
|
4
|
+
* The entire surface is plain data: discriminated unions on `kind`, no Map /
|
|
5
|
+
* Date / class instances, explicit unit suffixes (`...Twips`, `...Pt`) instead
|
|
6
|
+
* of bare numbers. `JSON.parse(JSON.stringify(spec))` is identity over any
|
|
7
|
+
* valid spec, which is what lets a stored recipe (or, later, an MCP payload)
|
|
8
|
+
* compile without translation.
|
|
9
|
+
*
|
|
10
|
+
* The type surface intentionally covers the full feature set of the
|
|
11
|
+
* add-docx-generation change even though emitters land in phases; the
|
|
12
|
+
* compiler rejects any spec feature whose emitter has not shipped yet
|
|
13
|
+
* (see validate-spec.ts) rather than silently ignoring it.
|
|
14
|
+
*/
|
|
15
|
+
export type DocumentSpec = {
|
|
16
|
+
meta?: DocumentMetaSpec;
|
|
17
|
+
/** Optional partial override for the emitted package theme. */
|
|
18
|
+
theme?: DocumentThemeSpec;
|
|
19
|
+
/** Emitted to word/styles.xml. Document defaults + Normal are always emitted. */
|
|
20
|
+
styles?: StyleSpec[];
|
|
21
|
+
/** Emitted to word/numbering.xml when non-empty. */
|
|
22
|
+
numbering?: NumberingSpec[];
|
|
23
|
+
/** At least one section. The final section's properties bind at body level. */
|
|
24
|
+
sections: SectionSpec[];
|
|
25
|
+
options?: {
|
|
26
|
+
/** Default true. When false, drafting notes compile to nothing. */
|
|
27
|
+
includeDraftingNotes?: boolean;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export type DocumentMetaSpec = {
|
|
31
|
+
title?: string;
|
|
32
|
+
author?: string;
|
|
33
|
+
/** ISO-8601 timestamp used for docProps dates. Generation never reads the clock. */
|
|
34
|
+
createdIso?: string;
|
|
35
|
+
};
|
|
36
|
+
export declare const THEME_COLOR_SLOTS: readonly ["text1", "background1", "text2", "background2", "accent1", "accent2", "accent3", "accent4", "accent5", "accent6", "hyperlink", "followedHyperlink"];
|
|
37
|
+
export type ThemeColorSlot = (typeof THEME_COLOR_SLOTS)[number];
|
|
38
|
+
export type DocumentThemeSpec = {
|
|
39
|
+
/** Partial slot overrides; values are six-digit hex without '#'. */
|
|
40
|
+
colors?: Partial<Record<ThemeColorSlot, string>>;
|
|
41
|
+
/** Optional major (headings) and minor (body) latin typefaces. */
|
|
42
|
+
fonts?: {
|
|
43
|
+
major?: string;
|
|
44
|
+
minor?: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export type SectionSpec = {
|
|
48
|
+
page?: {
|
|
49
|
+
/** Defaults to US Letter (12240 × 15840). */
|
|
50
|
+
sizeTwips?: {
|
|
51
|
+
w: number;
|
|
52
|
+
h: number;
|
|
53
|
+
};
|
|
54
|
+
orientation?: 'portrait' | 'landscape';
|
|
55
|
+
marginsTwips?: {
|
|
56
|
+
top?: number;
|
|
57
|
+
right?: number;
|
|
58
|
+
bottom?: number;
|
|
59
|
+
left?: number;
|
|
60
|
+
header?: number;
|
|
61
|
+
footer?: number;
|
|
62
|
+
gutter?: number;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/** Section-break type for non-final sections (w:type). */
|
|
66
|
+
breakType?: 'nextPage' | 'continuous' | 'oddPage' | 'evenPage';
|
|
67
|
+
pageNumbering?: {
|
|
68
|
+
start?: number;
|
|
69
|
+
format?: 'decimal' | 'lowerRoman' | 'upperRoman' | 'lowerLetter' | 'upperLetter';
|
|
70
|
+
};
|
|
71
|
+
/** Auto-implied when headers.first or footers.first is present. */
|
|
72
|
+
titlePg?: boolean;
|
|
73
|
+
headers?: HeaderFooterSet;
|
|
74
|
+
footers?: HeaderFooterSet;
|
|
75
|
+
blocks: BlockSpec[];
|
|
76
|
+
};
|
|
77
|
+
export type HeaderFooterSet = {
|
|
78
|
+
default?: HeaderFooterSpec;
|
|
79
|
+
first?: HeaderFooterSpec;
|
|
80
|
+
even?: HeaderFooterSpec;
|
|
81
|
+
};
|
|
82
|
+
export type HeaderFooterSpec = {
|
|
83
|
+
blocks: BlockSpec[];
|
|
84
|
+
};
|
|
85
|
+
export type BlockSpec = ParagraphSpec | TableSpec;
|
|
86
|
+
export type ParagraphSpec = {
|
|
87
|
+
kind: 'paragraph';
|
|
88
|
+
/** Must resolve to a declared style (or the implicit Normal). */
|
|
89
|
+
styleId?: string;
|
|
90
|
+
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
91
|
+
spacing?: {
|
|
92
|
+
beforeTwips?: number;
|
|
93
|
+
afterTwips?: number;
|
|
94
|
+
lineTwips?: number;
|
|
95
|
+
lineRule?: 'auto' | 'exact' | 'atLeast';
|
|
96
|
+
};
|
|
97
|
+
indent?: {
|
|
98
|
+
leftTwips?: number;
|
|
99
|
+
rightTwips?: number;
|
|
100
|
+
firstLineTwips?: number;
|
|
101
|
+
hangingTwips?: number;
|
|
102
|
+
};
|
|
103
|
+
/** Must resolve to a declared numbering definition. */
|
|
104
|
+
list?: {
|
|
105
|
+
numId: string;
|
|
106
|
+
ilvl: number;
|
|
107
|
+
};
|
|
108
|
+
pageBreakBefore?: boolean;
|
|
109
|
+
keepNext?: boolean;
|
|
110
|
+
tabs?: Array<{
|
|
111
|
+
posTwips: number;
|
|
112
|
+
align: 'left' | 'center' | 'right';
|
|
113
|
+
leader?: 'none' | 'dot' | 'underscore';
|
|
114
|
+
}>;
|
|
115
|
+
runs: InlineSpec[];
|
|
116
|
+
/** Drafting-note annotation anchored to this paragraph (separable layer). */
|
|
117
|
+
note?: DraftingNoteSpec;
|
|
118
|
+
};
|
|
119
|
+
export type InlineSpec = RunSpec | FieldSpec | TabSpec | BreakSpec;
|
|
120
|
+
/**
|
|
121
|
+
* The fixed set of text-highlight values (CT_HighlightColor). Single source of
|
|
122
|
+
* truth: the {@link HighlightColor} union is derived from this array, and
|
|
123
|
+
* validation reuses it as a runtime whitelist so JSON/JS callers cannot author
|
|
124
|
+
* an out-of-enum `w:highlight`.
|
|
125
|
+
*/
|
|
126
|
+
export declare const HIGHLIGHT_COLORS: readonly ["yellow", "green", "cyan", "magenta", "blue", "red", "darkBlue", "darkCyan", "darkGreen", "darkMagenta", "darkRed", "darkYellow", "darkGray", "lightGray", "black", "white", "none"];
|
|
127
|
+
export type HighlightColor = (typeof HIGHLIGHT_COLORS)[number];
|
|
128
|
+
/** Run-level formatting shared by text runs, fields, and style definitions. */
|
|
129
|
+
export type RunProps = {
|
|
130
|
+
bold?: boolean;
|
|
131
|
+
italic?: boolean;
|
|
132
|
+
underline?: 'single' | 'double' | 'none';
|
|
133
|
+
/** Six-digit hex without '#', e.g. 'FF0000'. */
|
|
134
|
+
colorHex?: string;
|
|
135
|
+
/** Theme color slot emitted as w:color/@w:themeColor. */
|
|
136
|
+
themeColor?: ThemeColorSlot;
|
|
137
|
+
/** Two-digit hex tint emitted as w:color/@w:themeTint. */
|
|
138
|
+
themeTint?: string;
|
|
139
|
+
/** Two-digit hex shade emitted as w:color/@w:themeShade. */
|
|
140
|
+
themeShade?: string;
|
|
141
|
+
/** Fixed text highlight color; arbitrary run fill belongs to run shading. */
|
|
142
|
+
highlight?: HighlightColor;
|
|
143
|
+
/** Applied to ascii + hAnsi + cs so all script ranges agree. */
|
|
144
|
+
font?: string;
|
|
145
|
+
sizePt?: number;
|
|
146
|
+
caps?: boolean;
|
|
147
|
+
smallCaps?: boolean;
|
|
148
|
+
};
|
|
149
|
+
export type RunSpec = {
|
|
150
|
+
kind: 'text';
|
|
151
|
+
text: string;
|
|
152
|
+
} & RunProps;
|
|
153
|
+
export type FieldSpec = {
|
|
154
|
+
kind: 'field';
|
|
155
|
+
field: 'PAGE' | 'NUMPAGES';
|
|
156
|
+
/**
|
|
157
|
+
* Cached field result text, required so readers display a value without
|
|
158
|
+
* recomputation prompts. The no-recovery-dialog guarantee is
|
|
159
|
+
* unrepresentable-by-omission.
|
|
160
|
+
*/
|
|
161
|
+
cachedResult: string;
|
|
162
|
+
} & RunProps;
|
|
163
|
+
export type TabSpec = {
|
|
164
|
+
kind: 'tab';
|
|
165
|
+
};
|
|
166
|
+
export type BreakSpec = {
|
|
167
|
+
kind: 'break';
|
|
168
|
+
breakType?: 'line' | 'page';
|
|
169
|
+
};
|
|
170
|
+
export type TableSpec = {
|
|
171
|
+
kind: 'table';
|
|
172
|
+
/** Defaults to 'fixed'. */
|
|
173
|
+
layout?: 'fixed' | 'autofit';
|
|
174
|
+
/** Defines w:tblGrid; the sum drives w:tblW. */
|
|
175
|
+
columnWidthsTwips: number[];
|
|
176
|
+
borders?: TableBorders;
|
|
177
|
+
rows: TableRowSpec[];
|
|
178
|
+
};
|
|
179
|
+
export type BorderSpec = {
|
|
180
|
+
style: 'single' | 'double' | 'none';
|
|
181
|
+
sizeEighthPt?: number;
|
|
182
|
+
colorHex?: string;
|
|
183
|
+
};
|
|
184
|
+
export type TableBorders = {
|
|
185
|
+
top?: BorderSpec;
|
|
186
|
+
bottom?: BorderSpec;
|
|
187
|
+
left?: BorderSpec;
|
|
188
|
+
right?: BorderSpec;
|
|
189
|
+
insideH?: BorderSpec;
|
|
190
|
+
insideV?: BorderSpec;
|
|
191
|
+
};
|
|
192
|
+
export type TableRowSpec = {
|
|
193
|
+
heightTwips?: number;
|
|
194
|
+
heightRule?: 'atLeast' | 'exact';
|
|
195
|
+
/** Marks the row as a repeating header row (w:tblHeader). */
|
|
196
|
+
header?: boolean;
|
|
197
|
+
cells: TableCellSpec[];
|
|
198
|
+
};
|
|
199
|
+
export type TableCellSpec = {
|
|
200
|
+
widthTwips?: number;
|
|
201
|
+
gridSpan?: number;
|
|
202
|
+
vMerge?: 'restart' | 'continue';
|
|
203
|
+
borders?: TableBorders;
|
|
204
|
+
shadingHex?: string;
|
|
205
|
+
themeFill?: ThemeColorSlot;
|
|
206
|
+
themeFillTint?: string;
|
|
207
|
+
themeFillShade?: string;
|
|
208
|
+
vAlign?: 'top' | 'center' | 'bottom';
|
|
209
|
+
marginsTwips?: {
|
|
210
|
+
top?: number;
|
|
211
|
+
right?: number;
|
|
212
|
+
bottom?: number;
|
|
213
|
+
left?: number;
|
|
214
|
+
};
|
|
215
|
+
blocks: BlockSpec[];
|
|
216
|
+
};
|
|
217
|
+
export type StyleSpec = {
|
|
218
|
+
styleId: string;
|
|
219
|
+
name: string;
|
|
220
|
+
type: 'paragraph' | 'character';
|
|
221
|
+
basedOn?: string;
|
|
222
|
+
next?: string;
|
|
223
|
+
paragraph?: Omit<ParagraphSpec, 'kind' | 'runs' | 'list' | 'note' | 'styleId'>;
|
|
224
|
+
run?: RunProps;
|
|
225
|
+
};
|
|
226
|
+
export type NumberingSpec = {
|
|
227
|
+
/** Spec-level handle; the compiler assigns numeric w:numId / abstractNumId. */
|
|
228
|
+
numId: string;
|
|
229
|
+
levels: Array<{
|
|
230
|
+
ilvl: number;
|
|
231
|
+
start?: number;
|
|
232
|
+
numFmt: 'decimal' | 'lowerLetter' | 'upperLetter' | 'lowerRoman' | 'upperRoman' | 'bullet' | 'none';
|
|
233
|
+
/** Level text pattern, e.g. '%1.' or '%1.%2' or a bullet glyph. */
|
|
234
|
+
lvlText: string;
|
|
235
|
+
suff?: 'tab' | 'space' | 'nothing';
|
|
236
|
+
indentTwips?: {
|
|
237
|
+
left?: number;
|
|
238
|
+
hanging?: number;
|
|
239
|
+
};
|
|
240
|
+
runProps?: RunProps;
|
|
241
|
+
}>;
|
|
242
|
+
};
|
|
243
|
+
export type DraftingNoteSpec = {
|
|
244
|
+
text: string;
|
|
245
|
+
author?: string;
|
|
246
|
+
/** ISO-8601; comment metadata is deterministic, never wall-clock. */
|
|
247
|
+
dateIso?: string;
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/generation/types.ts"],"names":[],"mappings":"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"}
|