@stll/folio-core 0.54.1 → 0.55.0
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/dist/ai-edits/apply.d.ts +1 -1
- package/dist/ai-edits/apply.js +40 -32
- package/dist/ai-edits/headless.d.ts +1 -2
- package/dist/ai-edits/headless.js +13 -27
- package/dist/ai-edits/read.d.ts +1 -0
- package/dist/ai-edits/read.js +7 -2
- package/dist/ai-edits/table-mutation-plan.d.ts +2 -1
- package/dist/ai-edits/table-mutation-plan.js +39 -1
- package/dist/ai-suggestions/apply.d.ts +1 -1
- package/dist/ai-suggestions/apply.js +3 -2
- package/dist/compare/compare.js +2 -1
- package/dist/compare/content-types.d.ts +3 -15
- package/dist/controller/canonicalComposition.d.ts +36 -0
- package/dist/controller/canonicalComposition.js +168 -0
- package/dist/controller/canonicalInput.d.ts +45 -0
- package/dist/controller/canonicalInput.js +338 -0
- package/dist/controller/canonicalOperations.d.ts +22 -0
- package/dist/controller/canonicalOperations.js +85 -0
- package/dist/controller/canonicalReview.d.ts +12 -0
- package/dist/controller/canonicalReview.js +19 -0
- package/dist/controller/canonicalSession.d.ts +149 -0
- package/dist/controller/canonicalSession.js +1038 -0
- package/dist/controller/canonicalStoryEditor.d.ts +34 -0
- package/dist/controller/canonicalStoryEditor.js +82 -0
- package/dist/controller/canonicalStructure.d.ts +16 -0
- package/dist/controller/canonicalStructure.js +269 -0
- package/dist/controller/folioEditor.d.ts +1 -1
- package/dist/controller/folioEditor.js +9 -0
- package/dist/controller/headerFooterEditorManager.d.ts +4 -0
- package/dist/controller/headerFooterEditorManager.js +71 -3
- package/dist/controller/hiddenEditorApi.d.ts +35 -0
- package/dist/controller/hiddenEditorApi.js +25 -8
- package/dist/controller/hiddenEditorManager.d.ts +11 -2
- package/dist/controller/hiddenEditorManager.js +456 -30
- package/dist/controller/layoutPipeline.d.ts +1 -1
- package/dist/controller/layoutPipeline.js +2 -0
- package/dist/controller/noteEditorManager.d.ts +4 -0
- package/dist/controller/noteEditorManager.js +113 -15
- package/dist/docx/attributeRemainder.js +1 -0
- package/dist/docx/bookmarkIds.d.ts +11 -0
- package/dist/docx/bookmarkIds.js +33 -0
- package/dist/docx/canonicalSessionInput.d.ts +11 -0
- package/dist/docx/canonicalSessionInput.js +27 -0
- package/dist/docx/canonicalStoryRepack.d.ts +10 -0
- package/dist/docx/canonicalStoryRepack.js +41 -0
- package/dist/docx/contentTypeRegistry.d.ts +8 -0
- package/dist/docx/contentTypeRegistry.js +64 -0
- package/dist/docx/documentParser.d.ts +14 -1
- package/dist/docx/documentParser.js +17 -4
- package/dist/docx/drawingIdNormalization.js +23 -8
- package/dist/docx/ensureParaIds.d.ts +12 -1
- package/dist/docx/ensureParaIds.js +173 -213
- package/dist/docx/foldedListNumberFields.d.ts +85 -0
- package/dist/docx/foldedListNumberFields.js +267 -0
- package/dist/docx/headerFooterVerbatim.d.ts +14 -1
- package/dist/docx/headerFooterVerbatim.js +95 -2
- package/dist/docx/listNumberingInstances.js +11 -9
- package/dist/docx/noteIds.d.ts +9 -0
- package/dist/docx/noteIds.js +17 -0
- package/dist/docx/noteReferenceMark.d.ts +3 -1
- package/dist/docx/noteReferenceMark.js +15 -14
- package/dist/docx/numberingIds.d.ts +14 -0
- package/dist/docx/numberingIds.js +16 -0
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +17 -3
- package/dist/docx/numericIdAllocator.d.ts +12 -0
- package/dist/docx/numericIdAllocator.js +33 -0
- package/dist/docx/numericIdNormalization.d.ts +16 -0
- package/dist/docx/numericIdNormalization.js +174 -0
- package/dist/docx/packageParts.d.ts +3 -1
- package/dist/docx/packageParts.js +65 -16
- package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
- package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
- package/dist/docx/paragraphParser.js +101 -53
- package/dist/docx/paragraphPropertySource.d.ts +15 -1
- package/dist/docx/paragraphPropertySource.js +76 -22
- package/dist/docx/paragraphTextBoxEnrichment.js +2 -1
- package/dist/docx/parser.js +19 -6
- package/dist/docx/rasterMime.d.ts +64 -0
- package/dist/docx/rasterMime.js +116 -0
- package/dist/docx/replyToComment.js +13 -6
- package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
- package/dist/docx/reviewHistoryNamespace.js +4 -0
- package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
- package/dist/docx/reviewResolutionProvenance.js +153 -0
- package/dist/docx/rezip.d.ts +7 -3
- package/dist/docx/rezip.js +121 -52
- package/dist/docx/runConsolidator.d.ts +2 -58
- package/dist/docx/runConsolidator.js +3 -175
- package/dist/docx/runParser.d.ts +2 -1
- package/dist/docx/runParser.js +156 -116
- package/dist/docx/saveDiagnostics.d.ts +11 -0
- package/dist/docx/saveDiagnostics.js +0 -0
- package/dist/docx/selectiveSave.d.ts +2 -1
- package/dist/docx/selectiveSave.js +14 -1
- package/dist/docx/selectiveXmlPatch.d.ts +16 -8
- package/dist/docx/selectiveXmlPatch.js +74 -2
- package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
- package/dist/docx/serializer/headerFooterSerializer.js +19 -11
- package/dist/docx/serializer/noteSerializer.d.ts +2 -2
- package/dist/docx/serializer/noteSerializer.js +24 -8
- package/dist/docx/serializer/paragraphSerializer.js +41 -4
- package/dist/docx/serializer/partNamespaces.js +6 -3
- package/dist/docx/serializer/runSerializer.js +8 -5
- package/dist/docx/serializer/trackedChangeAttributes.js +7 -1
- package/dist/docx/server/build.js +14 -3
- package/dist/docx/server/createBilingualDocument.js +10 -9
- package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
- package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
- package/dist/docx/settingsParser.d.ts +1 -2
- package/dist/docx/settingsParser.js +5 -6
- package/dist/docx/storyBlockReplay.d.ts +11 -0
- package/dist/docx/storyBlockReplay.js +367 -0
- package/dist/docx/streamingXmlParser.d.ts +31 -1
- package/dist/docx/streamingXmlParser.js +136 -21
- package/dist/docx/structuralXmlPatch.js +8 -1
- package/dist/docx/unzip.d.ts +3 -1
- package/dist/docx/unzip.js +36 -16
- package/dist/docx/verbatimCapture.d.ts +3 -1
- package/dist/docx/verbatimCapture.js +49 -6
- package/dist/i18n/messages/ar.gen.d.ts +5 -0
- package/dist/i18n/messages/ar.gen.js +656 -0
- package/dist/i18n/messages/cs.gen.d.ts +5 -0
- package/dist/i18n/messages/cs.gen.js +656 -0
- package/dist/i18n/messages/de.gen.d.ts +5 -0
- package/dist/i18n/messages/de.gen.js +656 -0
- package/dist/i18n/messages/en.gen.d.ts +5 -0
- package/dist/i18n/messages/en.gen.js +656 -0
- package/dist/i18n/messages/es.gen.d.ts +5 -0
- package/dist/i18n/messages/es.gen.js +656 -0
- package/dist/i18n/messages/et.gen.d.ts +5 -0
- package/dist/i18n/messages/et.gen.js +656 -0
- package/dist/i18n/messages/fr.gen.d.ts +5 -0
- package/dist/i18n/messages/fr.gen.js +656 -0
- package/dist/i18n/messages/he.gen.d.ts +5 -0
- package/dist/i18n/messages/he.gen.js +656 -0
- package/dist/i18n/messages/hi.gen.d.ts +5 -0
- package/dist/i18n/messages/hi.gen.js +656 -0
- package/dist/i18n/messages/hu.gen.d.ts +5 -0
- package/dist/i18n/messages/hu.gen.js +656 -0
- package/dist/i18n/messages/locales.d.ts +5 -0
- package/dist/i18n/messages/locales.js +22 -0
- package/dist/i18n/messages/lt.gen.d.ts +5 -0
- package/dist/i18n/messages/lt.gen.js +656 -0
- package/dist/i18n/messages/lv.gen.d.ts +5 -0
- package/dist/i18n/messages/lv.gen.js +656 -0
- package/dist/i18n/messages/pl.gen.d.ts +5 -0
- package/dist/i18n/messages/pl.gen.js +656 -0
- package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
- package/dist/i18n/messages/pt-BR.gen.js +656 -0
- package/dist/i18n/messages/sk.gen.d.ts +5 -0
- package/dist/i18n/messages/sk.gen.js +656 -0
- package/dist/i18n/messages/tr.gen.d.ts +5 -0
- package/dist/i18n/messages/tr.gen.js +656 -0
- package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
- package/dist/i18n/messages/zh-CN.gen.js +656 -0
- package/dist/i18n/messages.d.ts +2 -3
- package/dist/i18n/messages.js +1 -19
- package/dist/internal/noteMarkerAttrs.d.ts +8 -0
- package/dist/internal/noteMarkerAttrs.js +16 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
- package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
- package/dist/internal/prosemirrorAttrBoundary.js +50 -0
- package/dist/layout-bridge/convert/fixedTableColumnWidths.d.ts +6 -0
- package/dist/layout-bridge/convert/fixedTableColumnWidths.js +23 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
- package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
- package/dist/layout-bridge/convert/noteReferences.js +1 -6
- package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
- package/dist/layout-bridge/convert/tableConversion.js +4 -1
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
- package/dist/layout-painter/index.js +2 -5
- package/dist/managers/DocumentLoaderManager.d.ts +1 -0
- package/dist/managers/DocumentLoaderManager.js +8 -1
- package/dist/markdown/renderBlock.js +15 -1
- package/dist/markdown/renderParagraph.js +9 -13
- package/dist/markdown/renderRuns.js +3 -2
- package/dist/markdown/renderTable.js +2 -0
- package/dist/markdown/types.d.ts +3 -9
- package/dist/paged-layout/editorScrollRoot.d.ts +15 -0
- package/dist/paged-layout/editorScrollRoot.js +72 -0
- package/dist/paged-layout/scrollToPmPosition.js +8 -22
- package/dist/prosemirror/attrs/index.d.ts +2 -12
- package/dist/prosemirror/attrs/index.js +22 -48
- package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
- package/dist/prosemirror/canonicalCommands.d.ts +97 -0
- package/dist/prosemirror/canonicalCommands.js +28 -0
- package/dist/prosemirror/commands/clearParagraphIndent.d.ts +6 -0
- package/dist/prosemirror/commands/clearParagraphIndent.js +25 -0
- package/dist/prosemirror/commands/pageBreak.js +15 -1
- package/dist/prosemirror/commentIdAllocator.d.ts +15 -22
- package/dist/prosemirror/commentIdAllocator.js +50 -25
- package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
- package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
- package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -3
- package/dist/prosemirror/conversion/toProseDoc.js +51 -11
- package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
- package/dist/prosemirror/executeEditorCommand.js +26 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/HistoryExtension.js +97 -5
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +53 -20
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +22 -28
- package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
- package/dist/prosemirror/extensions/marks/markUtils.js +70 -8
- package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +8 -6
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +16 -7
- package/dist/prosemirror/listNumbering.js +26 -5
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/markupViewNotes.js +3 -2
- package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
- package/dist/prosemirror/noteReferenceReview.js +5 -3
- package/dist/prosemirror/plugins/revisionIds.d.ts +23 -19
- package/dist/prosemirror/plugins/revisionIds.js +110 -29
- package/dist/prosemirror/plugins/suggestionMode.d.ts +2 -2
- package/dist/prosemirror/plugins/suggestionMode.js +246 -42
- package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
- package/dist/prosemirror/runFormattingFromMarks.js +15 -1
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
- package/dist/prosemirror/schema/marks.d.ts +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +10 -2
- package/dist/prosemirror/storyListNumbering.js +11 -9
- package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/textInput.d.ts +6 -1
- package/dist/prosemirror/textInput.js +14 -3
- package/dist/prosemirror/trackedRevisionPath.js +2 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
- package/dist/prosemirror/utils/visualLineNavigation.js +6 -8
- package/dist/prosemirror/validation.js +4 -0
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/createDocument.js +2 -2
- package/dist/utils/mergeDocumentContent.d.ts +2 -2
- package/dist/utils/mergeDocumentContent.js +11 -8
- package/package.json +14 -2
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { hasNoteReferenceMark } from "../noteReferenceMark.js";
|
|
1
2
|
import { serializeBlockCustomXml } from "./blockCustomXmlSerializer.js";
|
|
2
3
|
import { serializeBlockSdt } from "./blockSdtSerializer.js";
|
|
3
4
|
import { serializeBookmarkMarker } from "./markupRangeAttributes.js";
|
|
4
5
|
import { serializeParagraph } from "./paragraphSerializer.js";
|
|
5
6
|
import { serializePartElement } from "./partNamespaces.js";
|
|
6
7
|
import { serializeTable } from "./tableSerializer.js";
|
|
8
|
+
import { noteUsesCustomMark } from "@stll/docx-core/ops";
|
|
7
9
|
//#region src/docx/serializer/noteSerializer.ts
|
|
8
10
|
const NOTE_BASELINE_PREFIXES = [
|
|
9
11
|
"wpc",
|
|
@@ -66,8 +68,9 @@ const NOTE_SEPARATOR_BODY = "<w:p><w:pPr><w:spacing w:after=\"0\" w:line=\"240\"
|
|
|
66
68
|
function serializeRequiredNoteSeparators(elementName) {
|
|
67
69
|
return `<w:${elementName} w:type="separator" w:id="-1">${NOTE_SEPARATOR_BODY}<w:r><w:separator/></w:r></w:p></w:${elementName}><w:${elementName} w:type="continuationSeparator" w:id="0">${NOTE_SEPARATOR_BODY}<w:r><w:continuationSeparator/></w:r></w:p></w:${elementName}>`;
|
|
68
70
|
}
|
|
69
|
-
function insertNoteReferenceMark(xml, elementName) {
|
|
70
|
-
if (
|
|
71
|
+
function insertNoteReferenceMark({ xml, elementName, note, customMark }) {
|
|
72
|
+
if (customMark) return xml;
|
|
73
|
+
if (hasNoteReferenceMark(elementName, note.content)) return xml;
|
|
71
74
|
const paragraphOpen = /<w:p(?=[\s>])[^>]*>/u.exec(xml);
|
|
72
75
|
if (!paragraphOpen) return `${`<w:p><w:r><w:rPr><w:rStyle w:val="${elementName === "footnote" ? "FootnoteReference" : "EndnoteReference"}"/></w:rPr><w:${elementName}Ref/></w:r></w:p>`}${xml}`;
|
|
73
76
|
const paragraphStart = paragraphOpen.index + paragraphOpen[0].length;
|
|
@@ -77,8 +80,13 @@ function insertNoteReferenceMark(xml, elementName) {
|
|
|
77
80
|
const referenceRun = `<w:r><w:rPr><w:rStyle w:val="${elementName === "footnote" ? "FootnoteReference" : "EndnoteReference"}"/></w:rPr><w:${elementName}Ref/></w:r>`;
|
|
78
81
|
return `${xml.slice(0, insertAt)}${referenceRun}${xml.slice(insertAt)}`;
|
|
79
82
|
}
|
|
80
|
-
function serializeNewNotePart(elementName, notes) {
|
|
81
|
-
const serializedNotes = notes.map((note) => insertNoteReferenceMark(
|
|
83
|
+
function serializeNewNotePart({ elementName, notes, document }) {
|
|
84
|
+
const serializedNotes = notes.map((note) => insertNoteReferenceMark({
|
|
85
|
+
xml: serializeNote(elementName, note),
|
|
86
|
+
elementName,
|
|
87
|
+
note,
|
|
88
|
+
customMark: document ? noteUsesCustomMark(document, note) : false
|
|
89
|
+
})).join("");
|
|
82
90
|
return serializeNotePart(elementName, serializeRequiredNoteSeparators(elementName) + serializedNotes);
|
|
83
91
|
}
|
|
84
92
|
/**
|
|
@@ -101,13 +109,21 @@ function serializeEndnotes(endnotes) {
|
|
|
101
109
|
}
|
|
102
110
|
/** Serialize a brand-new footnote part, including Word's required separators
|
|
103
111
|
* and the automatic reference mark at the start of every normal note. */
|
|
104
|
-
function serializeNewFootnotesPart(footnotes) {
|
|
105
|
-
return serializeNewNotePart(
|
|
112
|
+
function serializeNewFootnotesPart(footnotes, document) {
|
|
113
|
+
return serializeNewNotePart({
|
|
114
|
+
elementName: "footnote",
|
|
115
|
+
notes: footnotes,
|
|
116
|
+
...document ? { document } : {}
|
|
117
|
+
});
|
|
106
118
|
}
|
|
107
119
|
/** Serialize a brand-new endnote part, including Word's required separators
|
|
108
120
|
* and the automatic reference mark at the start of every normal note. */
|
|
109
|
-
function serializeNewEndnotesPart(endnotes) {
|
|
110
|
-
return serializeNewNotePart(
|
|
121
|
+
function serializeNewEndnotesPart(endnotes, document) {
|
|
122
|
+
return serializeNewNotePart({
|
|
123
|
+
elementName: "endnote",
|
|
124
|
+
notes: endnotes,
|
|
125
|
+
...document ? { document } : {}
|
|
126
|
+
});
|
|
111
127
|
}
|
|
112
128
|
//#endregion
|
|
113
129
|
export { serializeEndnotes, serializeFootnotes, serializeNewEndnotesPart, serializeNewFootnotesPart };
|
|
@@ -2,7 +2,9 @@ import { modelParagraphFormattingEmission, serializeParagraphPropertySet } from
|
|
|
2
2
|
import { serializePreservedAttributes } from "../attributeRemainder.js";
|
|
3
3
|
import { CONTAINER_CHILDREN } from "../containerChildren.gen.js";
|
|
4
4
|
import { fieldStateAttributes } from "../fieldState.js";
|
|
5
|
+
import { serializeEmptyMarkProperties } from "../paragraphMarkPropertyPresence.js";
|
|
5
6
|
import { getParagraphPropertySource, paragraphPropertySourceMatchesEmission } from "../paragraphPropertySource.js";
|
|
7
|
+
import { ReviewResolutionProvenanceError, paragraphMarkResolutionJoinAttributes, serializeParagraphMarkResolutionJoin, serializeResolutionJoins } from "../reviewResolutionProvenance.js";
|
|
6
8
|
import { DATE_UTC_ATTRIBUTE } from "../trackedChangeInfo.js";
|
|
7
9
|
import { toTransitionalNamespaceUri } from "../transitionalSpelling.js";
|
|
8
10
|
import { captureVerbatimXml, createCapturedXmlSanitizer } from "../verbatimCapture.js";
|
|
@@ -20,11 +22,22 @@ import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
|
|
|
20
22
|
import { SEQUENCE_CHILDREN } from "@stll/docx-core/schema";
|
|
21
23
|
//#region src/docx/serializer/paragraphSerializer.ts
|
|
22
24
|
/**
|
|
25
|
+
* Paragraph Serializer - Serialize paragraphs to OOXML XML
|
|
26
|
+
*
|
|
27
|
+
* Converts Paragraph objects back to <w:p> XML format for DOCX files.
|
|
28
|
+
* Handles all paragraph properties and child content (runs, hyperlinks, fields, bookmarks).
|
|
29
|
+
*
|
|
30
|
+
* OOXML Reference:
|
|
31
|
+
* - Paragraph: w:p
|
|
32
|
+
* - Paragraph properties: w:pPr
|
|
33
|
+
* - Runs, hyperlinks, bookmarks, fields as child elements
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
23
36
|
* Serialize paragraph formatting properties to w:pPr XML
|
|
24
37
|
*/
|
|
25
38
|
function serializeParagraphMarkChange(mark) {
|
|
26
39
|
const attrs = serializeTrackedChangeAttributes(mark.info);
|
|
27
|
-
return `<w:${mark.kind} ${attrs}/>`;
|
|
40
|
+
return `<w:${mark.kind} ${attrs}${serializeParagraphMarkResolutionJoin(mark)}/>`;
|
|
28
41
|
}
|
|
29
42
|
const RESERVED_PARAGRAPH_PROPERTY_CHILDREN = /* @__PURE__ */ new Set(["pPrChange", "sectPr"]);
|
|
30
43
|
/**
|
|
@@ -212,7 +225,10 @@ const withTrailingParagraphPropertyChildren = (sourceXml, children) => {
|
|
|
212
225
|
const withParagraphMarkChange = (sourceXml, mark) => {
|
|
213
226
|
const root = parseXml(sourceXml, OOXML_NAMESPACE_SCOPE).elements?.at(0);
|
|
214
227
|
if (!root || root.type !== "element") panic("A validated paragraph-property capture could not be parsed for composition");
|
|
215
|
-
const attributes =
|
|
228
|
+
const attributes = {
|
|
229
|
+
...trackedChangeAttributeRecord(mark.info),
|
|
230
|
+
...paragraphMarkResolutionJoinAttributes(mark)
|
|
231
|
+
};
|
|
216
232
|
const markElement = cloneElement(root, {
|
|
217
233
|
name: `w:${mark.kind}`,
|
|
218
234
|
attributes,
|
|
@@ -339,6 +355,20 @@ function serializeComplexField(field) {
|
|
|
339
355
|
parts.push(`<w:r>${rPrXml}<w:fldChar w:fldCharType="end"/></w:r>`);
|
|
340
356
|
return parts.join("");
|
|
341
357
|
}
|
|
358
|
+
var UnrepresentableTrackedCaptureError = class extends TaggedError("UnrepresentableTrackedCaptureError") {};
|
|
359
|
+
/**
|
|
360
|
+
* Preserved markup inside a removal. Markup captured from a removal already
|
|
361
|
+
* spells its text as deleted text. Markup captured outside one and put under
|
|
362
|
+
* a removal afterwards does not: plain runs are respelled here, as a deleted
|
|
363
|
+
* run is. A folded list-number capture that cannot be respelled is refused,
|
|
364
|
+
* rather than written as live text inside the removal.
|
|
365
|
+
*/
|
|
366
|
+
function serializeRemovedPreservedInline(item) {
|
|
367
|
+
if (!/<w:(?:t|instrText)[\s>]/u.test(item.xml)) return item.xml;
|
|
368
|
+
if (/^<w:r[\s>]/u.test(item.xml) && !/<w:(?:drawing|pict|object)\b|<mc:AlternateContent\b/u.test(item.xml)) return rewriteRunTextAsDeleted(item.xml);
|
|
369
|
+
if (item.foldedListNumber) throw new UnrepresentableTrackedCaptureError({ message: "A folded list-number field holds markup that cannot be written as deleted content." });
|
|
370
|
+
return item.xml;
|
|
371
|
+
}
|
|
342
372
|
var UnrepresentableTrackedSimpleFieldError = class extends TaggedError("UnrepresentableTrackedSimpleFieldError") {};
|
|
343
373
|
/** A revision can contain run-level field characters, but not `w:fldSimple`. */
|
|
344
374
|
function serializeTrackedSimpleField(field) {
|
|
@@ -429,7 +459,12 @@ function trackedChangeTag(change) {
|
|
|
429
459
|
}
|
|
430
460
|
}
|
|
431
461
|
function serializeTrackedChange(tag, change) {
|
|
432
|
-
|
|
462
|
+
if (change.resolutionJoins !== void 0 && change.content.some((item) => item.type === "hyperlink")) throw new ReviewResolutionProvenanceError({
|
|
463
|
+
attribute: "resolutionJoins",
|
|
464
|
+
reason: "unrepresentable",
|
|
465
|
+
message: "Tracked-resolution provenance cannot be repartitioned across serialized hyperlinks."
|
|
466
|
+
});
|
|
467
|
+
const attrs = serializeTrackedChangeAttributes(change.info) + serializeResolutionJoins(change.resolutionJoins);
|
|
433
468
|
const disposition = tag === "del" || tag === "moveFrom" ? "removed" : "kept";
|
|
434
469
|
const serializeContentRun = (run) => serializeInlineRun(run, disposition);
|
|
435
470
|
const serializeWrappedItem = (item) => {
|
|
@@ -451,7 +486,7 @@ function serializeTrackedChange(tag, change) {
|
|
|
451
486
|
case "moveFromRangeEnd": return `<w:moveFromRangeEnd ${markupRangeAttributes(item).join(" ")}/>`;
|
|
452
487
|
case "moveToRangeStart": return serializeMoveRangeStart("moveToRangeStart", item);
|
|
453
488
|
case "moveToRangeEnd": return `<w:moveToRangeEnd ${markupRangeAttributes(item).join(" ")}/>`;
|
|
454
|
-
case "preservedInline": return item.xml;
|
|
489
|
+
case "preservedInline": return disposition === "removed" ? serializeRemovedPreservedInline(item) : item.xml;
|
|
455
490
|
case "inlineWrapper":
|
|
456
491
|
case "inlineSdt": return serializeParagraphContent(item, disposition);
|
|
457
492
|
default: return item;
|
|
@@ -574,6 +609,8 @@ function serializeParagraph(paragraph) {
|
|
|
574
609
|
if (paragraph.paraId) attrs.push(`w14:paraId="${escapeXmlAttribute(paragraph.paraId)}"`);
|
|
575
610
|
if (paragraph.textId) attrs.push(`w14:textId="${escapeXmlAttribute(paragraph.textId)}"`);
|
|
576
611
|
if (paragraph.reviewCarrier) attrs.push(`folio:reviewCarrier="${paragraph.reviewCarrier}"`);
|
|
612
|
+
const emptyMarkProperties = serializeEmptyMarkProperties(paragraph);
|
|
613
|
+
if (emptyMarkProperties !== void 0) attrs.push(emptyMarkProperties);
|
|
577
614
|
const written = serializePreservedAttributes(attrs, paragraph.preservedAttributes);
|
|
578
615
|
const attrsStr = written.length > 0 ? ` ${written.join(" ")}` : "";
|
|
579
616
|
parts.push(serializeParagraphFormattingWithOptions(paragraph.formatting, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { FOLIO_REVIEW_HISTORY_NAMESPACE } from "../reviewHistoryNamespace.js";
|
|
1
2
|
import { toTransitionalNamespaceUri } from "../transitionalSpelling.js";
|
|
2
3
|
import { TaggedError } from "better-result";
|
|
3
|
-
import { escapeXmlAttribute } from "@stll/docx-core";
|
|
4
|
+
import { assertValidOoxmlNumericIds, escapeXmlAttribute } from "@stll/docx-core";
|
|
4
5
|
import { OOXML_NS } from "@stll/docx-utils";
|
|
5
6
|
//#region src/docx/serializer/partNamespaces.ts
|
|
6
7
|
/**
|
|
@@ -144,7 +145,7 @@ const OOXML_NAMESPACES = {
|
|
|
144
145
|
ignorable: true
|
|
145
146
|
},
|
|
146
147
|
folio: {
|
|
147
|
-
uri:
|
|
148
|
+
uri: FOLIO_REVIEW_HISTORY_NAMESPACE,
|
|
148
149
|
ignorable: true
|
|
149
150
|
},
|
|
150
151
|
wpg: {
|
|
@@ -322,7 +323,9 @@ const serializePartElement = ({ partPath, rootName, rootAttributes, baselinePref
|
|
|
322
323
|
const attributes = orderedPrefixes.map((prefix) => `xmlns:${prefix}="${escapeXmlAttribute(bindings.get(prefix))}"`);
|
|
323
324
|
const ignorable = orderedPrefixes.filter((prefix) => NAMESPACE_TABLE.get(prefix)?.ignorable === true);
|
|
324
325
|
if (ignorable.length > 0) attributes.push(`mc:Ignorable="${ignorable.join(" ")}"`);
|
|
325
|
-
|
|
326
|
+
const xml = `${openingTag} ${attributes.join(" ")}>${body}</${rootName}>`;
|
|
327
|
+
assertValidOoxmlNumericIds(xml, partPath);
|
|
328
|
+
return xml;
|
|
326
329
|
};
|
|
327
330
|
//#endregion
|
|
328
331
|
export { OOXML_NAMESPACES, UnboundNamespacePrefixError, readRootNamespaceBindings, serializePartElement };
|
|
@@ -7,6 +7,7 @@ import { serializeGraphicFrameLocks } from "../graphicFrameLocks.js";
|
|
|
7
7
|
import { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE } from "../imageParser.js";
|
|
8
8
|
import { canReplayEditableImageRawXml } from "../imageRawXml.js";
|
|
9
9
|
import { serializeNonVisualDrawingNames } from "../nonVisualDrawingProps.js";
|
|
10
|
+
import { serializeBoundaryJoins } from "../reviewResolutionProvenance.js";
|
|
10
11
|
import { runHoldsPayload } from "../runPayload.js";
|
|
11
12
|
import { replayableShapeAlternateContent } from "../shapeAlternateContent.js";
|
|
12
13
|
import { requiredWrapPolygon, serializeWrapPolygon } from "../wrapPolygon.js";
|
|
@@ -16,7 +17,7 @@ import { serializeTextFormatting } from "./textFormattingSerializer.js";
|
|
|
16
17
|
import { getSingularRunPropertyChange, serializeTrackedChangeAttributes } from "./trackedChangeAttributes.js";
|
|
17
18
|
import { intAttr } from "./xmlUtils.js";
|
|
18
19
|
import { panic } from "better-result";
|
|
19
|
-
import { escapeXmlAttribute, escapeXmlText, requiresXmlSpacePreserve } from "@stll/docx-core";
|
|
20
|
+
import { escapeXmlAttribute, escapeXmlText, isValidOoxmlNumericId, requiresXmlSpacePreserve } from "@stll/docx-core";
|
|
20
21
|
import { SCHEME_COLOR_VALUE_BY_THEME_COLOR, knownThemeColor, presetLineDashToken } from "@stll/docx-core/model";
|
|
21
22
|
//#region src/docx/serializer/runSerializer.ts
|
|
22
23
|
/**
|
|
@@ -32,7 +33,7 @@ import { SCHEME_COLOR_VALUE_BY_THEME_COLOR, knownThemeColor, presetLineDashToken
|
|
|
32
33
|
*/
|
|
33
34
|
/**
|
|
34
35
|
* Auto-incrementing counter for generating unique image/shape IDs.
|
|
35
|
-
* Used
|
|
36
|
+
* Used when a model id cannot identify a DrawingML object (e.g., a VML lexical id).
|
|
36
37
|
* Starts high (100000) to avoid collisions with IDs parsed from existing DOCX content.
|
|
37
38
|
*/
|
|
38
39
|
let nextAutoId = 1e5;
|
|
@@ -43,14 +44,15 @@ let nextAutoId = 1e5;
|
|
|
43
44
|
function resetAutoIdCounter() {
|
|
44
45
|
nextAutoId = 1e5;
|
|
45
46
|
}
|
|
46
|
-
/** Get
|
|
47
|
+
/** Get an unsigned integer ID, using the provided value or generating one */
|
|
47
48
|
function getUniqueId(id) {
|
|
48
|
-
if (id !== void 0 && id
|
|
49
|
+
if (id !== void 0 && isValidOoxmlNumericId(id, "unsigned32")) return String(id);
|
|
50
|
+
if (!isValidOoxmlNumericId(nextAutoId, "unsigned32")) panic("DrawingML generated id space is exhausted.");
|
|
49
51
|
return String(nextAutoId++);
|
|
50
52
|
}
|
|
51
53
|
function serializeRunPropertyChange(change) {
|
|
52
54
|
const previousRPrXml = serializeTextFormatting(change.previousFormatting) || "<w:rPr/>";
|
|
53
|
-
return `<w:rPrChange ${serializeTrackedChangeAttributes(change.info)}>${previousRPrXml}</w:rPrChange>`;
|
|
55
|
+
return `<w:rPrChange ${serializeTrackedChangeAttributes(change.info)}${serializeBoundaryJoins(change.boundaryJoins)}>${previousRPrXml}</w:rPrChange>`;
|
|
54
56
|
}
|
|
55
57
|
function serializeRunProperties(formatting, propertyChanges) {
|
|
56
58
|
const propertyChange = getSingularRunPropertyChange(propertyChanges);
|
|
@@ -536,6 +538,7 @@ function serializeRunContent(content) {
|
|
|
536
538
|
case "symbol": return serializeSymbolContent(content);
|
|
537
539
|
case "footnoteRef":
|
|
538
540
|
case "endnoteRef": return serializeNoteReference(content);
|
|
541
|
+
case "noteMarker": return content.kind === "footnote" ? "<w:footnoteRef/>" : "<w:endnoteRef/>";
|
|
539
542
|
case "fieldChar": return serializeFieldChar(content);
|
|
540
543
|
case "instrText": return serializeInstrText(content);
|
|
541
544
|
case "softHyphen": return serializeSoftHyphen(content);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DATE_UTC_ATTRIBUTE } from "../trackedChangeInfo.js";
|
|
2
2
|
import { panic } from "better-result";
|
|
3
|
-
import { escapeXmlAttribute } from "@stll/docx-core";
|
|
3
|
+
import { assertValidOoxmlNumericId, escapeXmlAttribute } from "@stll/docx-core";
|
|
4
4
|
import { normalizeRevisionId } from "@stll/docx-core/model";
|
|
5
5
|
//#region src/docx/serializer/trackedChangeAttributes.ts
|
|
6
6
|
/** Enforces the singular `w:rPrChange` child in a run-property container. */
|
|
@@ -14,6 +14,12 @@ const getSingularRunPropertyChange = (propertyChanges) => {
|
|
|
14
14
|
};
|
|
15
15
|
/** Normalized, unescaped attributes in schema order for an XML element or string serializer. */
|
|
16
16
|
const trackedChangeAttributeEntries = (info) => {
|
|
17
|
+
assertValidOoxmlNumericId({
|
|
18
|
+
value: info.id,
|
|
19
|
+
partPath: "word/*.xml",
|
|
20
|
+
elementName: "tracked change",
|
|
21
|
+
attributeName: "w:id"
|
|
22
|
+
});
|
|
17
23
|
const author = typeof info.author === "string" ? info.author.trim() : "";
|
|
18
24
|
const date = typeof info.date === "string" ? info.date.trim() : "";
|
|
19
25
|
const rawUtcDate = info.utcDate;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { mintBookmarkId, reserveBookmarkIds } from "../bookmarkIds.js";
|
|
2
|
+
import { mintEndnoteId } from "../noteIds.js";
|
|
1
3
|
import { TaggedError } from "better-result";
|
|
4
|
+
import { assertValidOoxmlNumericId } from "@stll/docx-core";
|
|
2
5
|
//#region src/docx/server/build.ts
|
|
3
6
|
/**
|
|
4
7
|
* Headless document builders.
|
|
@@ -103,10 +106,18 @@ const hyperlink = ({ text, formatting, tooltip, href, anchor }) => ({
|
|
|
103
106
|
...formatting
|
|
104
107
|
})]
|
|
105
108
|
});
|
|
106
|
-
let nextBookmarkId = 0;
|
|
107
109
|
/** `content` wrapped in a named bookmark, the target of `hyperlink({ anchor })`. */
|
|
108
110
|
const bookmark = ({ name, content, id }) => {
|
|
109
|
-
|
|
111
|
+
if (id !== void 0) {
|
|
112
|
+
assertValidOoxmlNumericId({
|
|
113
|
+
value: id,
|
|
114
|
+
partPath: "word/document.xml",
|
|
115
|
+
elementName: "w:bookmarkStart",
|
|
116
|
+
attributeName: "w:id"
|
|
117
|
+
});
|
|
118
|
+
reserveBookmarkIds([id]);
|
|
119
|
+
}
|
|
120
|
+
const bookmarkId = id ?? mintBookmarkId();
|
|
110
121
|
const start = {
|
|
111
122
|
type: "bookmarkStart",
|
|
112
123
|
id: bookmarkId,
|
|
@@ -225,7 +236,7 @@ const table = ({ header, rows, columnWidths, headerShading, repeatHeader = true
|
|
|
225
236
|
const endnote = (doc, content) => {
|
|
226
237
|
const endnotes = doc.package.endnotes ?? [];
|
|
227
238
|
doc.package.endnotes = endnotes;
|
|
228
|
-
const id =
|
|
239
|
+
const id = mintEndnoteId(endnotes.map((note) => note.id));
|
|
229
240
|
const note = {
|
|
230
241
|
type: "endnote",
|
|
231
242
|
id,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { deterministicHexId } from "../../utils/hexId.js";
|
|
2
|
+
import { createBookmarkIdAllocator } from "../bookmarkIds.js";
|
|
2
3
|
import { createBuiltInStyleIndex, resolveHeadingLevel } from "../builtInStyles.js";
|
|
4
|
+
import { createNumberingIdAllocator } from "../numberingIds.js";
|
|
3
5
|
import { mergeParagraphNumbering, paragraphNumberingReference, paragraphNumberingReferenceId } from "../numberingReference.js";
|
|
4
6
|
import { getParagraphText } from "../paragraphParser.js";
|
|
5
7
|
import { cloneParagraphWithoutPropertySource } from "../paragraphPropertySource.js";
|
|
@@ -271,8 +273,8 @@ const createNumberingCloner = ({ numbering, styleById, warnings }) => {
|
|
|
271
273
|
const nums = numbering?.nums ?? [];
|
|
272
274
|
const abstractById = new Map(abstractNums.map((item) => [item.abstractNumId, item]));
|
|
273
275
|
const numById = new Map(nums.map((item) => [item.numId, item]));
|
|
274
|
-
|
|
275
|
-
|
|
276
|
+
const abstractIds = createNumberingIdAllocator("abstract", abstractById.keys());
|
|
277
|
+
const instanceIds = createNumberingIdAllocator("num", numById.keys());
|
|
276
278
|
const clonedAbstract = /* @__PURE__ */ new Map();
|
|
277
279
|
const clonedNum = /* @__PURE__ */ new Map();
|
|
278
280
|
/**
|
|
@@ -291,10 +293,9 @@ const createNumberingCloner = ({ numbering, styleById, warnings }) => {
|
|
|
291
293
|
const { numStyleLink: _numStyleLink, styleLink: _styleLink, ...rest } = resolved;
|
|
292
294
|
const clone = {
|
|
293
295
|
...rest,
|
|
294
|
-
abstractNumId:
|
|
296
|
+
abstractNumId: abstractIds.next(),
|
|
295
297
|
levels: structuredClone(resolved.levels)
|
|
296
298
|
};
|
|
297
|
-
nextAbstractNumId += 1;
|
|
298
299
|
clonedAbstract.set(sourceId, clone);
|
|
299
300
|
return clone;
|
|
300
301
|
};
|
|
@@ -326,10 +327,9 @@ const createNumberingCloner = ({ numbering, styleById, warnings }) => {
|
|
|
326
327
|
if (!abstract) warnings.push(`Numbering instance ${numId} references abstractNum ${source.abstractNumId}, which is not defined; its copy shares the source counters.`);
|
|
327
328
|
const clone = {
|
|
328
329
|
...source,
|
|
329
|
-
numId:
|
|
330
|
+
numId: instanceIds.next(),
|
|
330
331
|
abstractNumId: abstract ? abstract.abstractNumId : source.abstractNumId
|
|
331
332
|
};
|
|
332
|
-
nextNumId += 1;
|
|
333
333
|
clonedNum.set(numId, clone);
|
|
334
334
|
return clone.numId;
|
|
335
335
|
};
|
|
@@ -411,7 +411,7 @@ const cloneParagraphForTarget = (paragraph, targetParaId, styleCloner, cloner, b
|
|
|
411
411
|
return cloned;
|
|
412
412
|
};
|
|
413
413
|
const createBookmarkIdMinter = (source) => {
|
|
414
|
-
|
|
414
|
+
const reservedIds = [];
|
|
415
415
|
const remapped = /* @__PURE__ */ new Map();
|
|
416
416
|
const visit = (value, seen) => {
|
|
417
417
|
if (typeof value !== "object" || value === null || seen.has(value)) return;
|
|
@@ -423,15 +423,16 @@ const createBookmarkIdMinter = (source) => {
|
|
|
423
423
|
const record = value;
|
|
424
424
|
if (record["type"] === "bookmarkStart" || record["type"] === "bookmarkEnd") {
|
|
425
425
|
const id = record["id"];
|
|
426
|
-
if (typeof id === "number")
|
|
426
|
+
if (typeof id === "number") reservedIds.push(id);
|
|
427
427
|
}
|
|
428
428
|
Object.values(record).forEach((item) => visit(item, seen));
|
|
429
429
|
};
|
|
430
430
|
visit(source, /* @__PURE__ */ new Set());
|
|
431
|
+
const allocator = createBookmarkIdAllocator(reservedIds);
|
|
431
432
|
return { mint: (sourceId) => {
|
|
432
433
|
const existing = remapped.get(sourceId);
|
|
433
434
|
if (existing !== void 0) return existing;
|
|
434
|
-
const id =
|
|
435
|
+
const id = allocator.next();
|
|
435
436
|
remapped.set(sourceId, id);
|
|
436
437
|
return id;
|
|
437
438
|
} };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/docx/settingsHeaderFooterUpdate.d.ts
|
|
2
|
+
/** Null means the source is malformed or outside the supported namespace profiles. */
|
|
3
|
+
declare const updateEvenAndOddHeaders: (xml: string, enabled: boolean | undefined) => string | null;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { updateEvenAndOddHeaders };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { spliceXml } from "./selectiveXmlPatch.js";
|
|
2
|
+
import { WORDPROCESSINGML_NAMESPACE_URIS, getChildElements, getLocalName, getNamespaceUri, parseXmlDocument } from "./xmlParser.js";
|
|
3
|
+
import { panic } from "better-result";
|
|
4
|
+
import { SETTINGS_CHILDREN } from "@stll/docx-core/schema";
|
|
5
|
+
//#region src/docx/settingsHeaderFooterUpdate.ts
|
|
6
|
+
/** Preserve producer settings while updating the document-wide header/footer switch. */
|
|
7
|
+
const XML_TOKEN = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(?:"[^"]*"|'[^']*'|[^'">])*>/gu;
|
|
8
|
+
const SETTINGS_CHILD_ORDINALS = new Map(SETTINGS_CHILDREN.map((name, index) => [name, index]));
|
|
9
|
+
const EVEN_AND_ODD_HEADERS_ORDER = SETTINGS_CHILD_ORDINALS.get("evenAndOddHeaders");
|
|
10
|
+
/** Null means the source is malformed or outside the supported namespace profiles. */
|
|
11
|
+
const updateEvenAndOddHeaders = (xml, enabled) => {
|
|
12
|
+
const root = parseXmlDocument(xml);
|
|
13
|
+
if (!root || getLocalName(root.name) !== "settings" || !WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(root) ?? "")) return null;
|
|
14
|
+
const children = getChildElements(root);
|
|
15
|
+
const spans = [];
|
|
16
|
+
const stack = [];
|
|
17
|
+
let childIndex = 0;
|
|
18
|
+
let childStart = -1;
|
|
19
|
+
let rootEnd = -1;
|
|
20
|
+
let rootOpenEnd = -1;
|
|
21
|
+
let selfClosingRootStart = -1;
|
|
22
|
+
let firstFollowingChildStart = -1;
|
|
23
|
+
if (EVEN_AND_ODD_HEADERS_ORDER === void 0) panic("Generated CT_Settings schema does not define evenAndOddHeaders");
|
|
24
|
+
for (const token of xml.matchAll(XML_TOKEN)) {
|
|
25
|
+
const tag = token[0];
|
|
26
|
+
if (tag.startsWith("<!") || tag.startsWith("<?")) continue;
|
|
27
|
+
const closing = tag.startsWith("</");
|
|
28
|
+
const name = tag.slice(closing ? 2 : 1).split(/[\s/>]/u).at(0);
|
|
29
|
+
if (!name) return null;
|
|
30
|
+
if (closing) {
|
|
31
|
+
if (stack.pop() !== name) return null;
|
|
32
|
+
if (stack.length === 1) {
|
|
33
|
+
const child = children[childIndex++];
|
|
34
|
+
if (!child || childStart < 0) return null;
|
|
35
|
+
if (getLocalName(child.name) === "evenAndOddHeaders" && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(child) ?? "")) spans.push({
|
|
36
|
+
start: childStart,
|
|
37
|
+
end: token.index + tag.length,
|
|
38
|
+
newXml: ""
|
|
39
|
+
});
|
|
40
|
+
childStart = -1;
|
|
41
|
+
}
|
|
42
|
+
if (stack.length === 0) rootEnd = token.index;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (stack.length === 0) {
|
|
46
|
+
rootOpenEnd = token.index + tag.length;
|
|
47
|
+
if (tag.endsWith("/>")) selfClosingRootStart = token.index;
|
|
48
|
+
}
|
|
49
|
+
if (stack.length === 1) {
|
|
50
|
+
const child = children[childIndex];
|
|
51
|
+
if (child?.name !== name) return null;
|
|
52
|
+
if (firstFollowingChildStart < 0 && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(child) ?? "") && (SETTINGS_CHILD_ORDINALS.get(getLocalName(child.name)) ?? -1) > EVEN_AND_ODD_HEADERS_ORDER) firstFollowingChildStart = token.index;
|
|
53
|
+
childStart = token.index;
|
|
54
|
+
if (tag.endsWith("/>")) {
|
|
55
|
+
childIndex += 1;
|
|
56
|
+
if (getLocalName(child.name) === "evenAndOddHeaders" && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(child) ?? "")) spans.push({
|
|
57
|
+
start: token.index,
|
|
58
|
+
end: token.index + tag.length,
|
|
59
|
+
newXml: ""
|
|
60
|
+
});
|
|
61
|
+
childStart = -1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!tag.endsWith("/>")) stack.push(name);
|
|
65
|
+
}
|
|
66
|
+
if (stack.length !== 0 || childIndex !== children.length) return null;
|
|
67
|
+
const flag = enabled === void 0 ? "" : `<folioW:evenAndOddHeaders xmlns:folioW="${getNamespaceUri(root)}"${enabled ? "" : " folioW:val=\"0\""}/>`;
|
|
68
|
+
if (selfClosingRootStart >= 0) {
|
|
69
|
+
if (!flag) return xml;
|
|
70
|
+
return spliceXml(xml, [{
|
|
71
|
+
start: rootOpenEnd - 2,
|
|
72
|
+
end: rootOpenEnd,
|
|
73
|
+
newXml: `>${flag}</${root.name}>`
|
|
74
|
+
}]);
|
|
75
|
+
}
|
|
76
|
+
if (rootEnd < 0) return null;
|
|
77
|
+
const existingFlag = spans.at(0);
|
|
78
|
+
if (flag && existingFlag) existingFlag.newXml = flag;
|
|
79
|
+
else if (flag) {
|
|
80
|
+
const insertAt = firstFollowingChildStart >= 0 ? firstFollowingChildStart : rootEnd;
|
|
81
|
+
spans.push({
|
|
82
|
+
start: insertAt,
|
|
83
|
+
end: insertAt,
|
|
84
|
+
newXml: flag
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return spliceXml(xml, spans);
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
export { updateEvenAndOddHeaders };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { DEFAULT_TAB_STOP_TWIPS } from "@stll/docx-core/model";
|
|
2
3
|
//#region src/docx/settingsParser.d.ts
|
|
3
|
-
/** OOXML default per §17.6.13 when `w:defaultTabStop` is absent. */
|
|
4
|
-
declare const DEFAULT_TAB_STOP_TWIPS = 720;
|
|
5
4
|
declare function parseSettings(xml: string | null): document_d_exports.DocumentSettings;
|
|
6
5
|
//#endregion
|
|
7
6
|
export { DEFAULT_TAB_STOP_TWIPS, parseSettings };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { parseEndnoteProperties } from "./notePropertiesParser.js";
|
|
2
2
|
import { WORDPROCESSINGML_NAMESPACE_URIS, findChild, findChildByNamespaceUri, findChildren, getAttribute, parseBooleanElement, parseXmlDocument } from "./xmlParser.js";
|
|
3
|
+
import { DEFAULT_TAB_STOP_TWIPS, DEFAULT_TAB_STOP_TWIPS as DEFAULT_TAB_STOP_TWIPS$1 } from "@stll/docx-core/model";
|
|
3
4
|
//#region src/docx/settingsParser.ts
|
|
4
|
-
/** OOXML default per §17.6.13 when `w:defaultTabStop` is absent. */
|
|
5
|
-
const DEFAULT_TAB_STOP_TWIPS = 720;
|
|
6
5
|
/**
|
|
7
6
|
* Sanity cap on `w:defaultTabStop`. Word's maximum margin is ~22 inches
|
|
8
7
|
* (31 680 twips); anything past that is corruption or a hostile input and
|
|
@@ -111,13 +110,13 @@ function parseKinsokuOverride(root, name) {
|
|
|
111
110
|
};
|
|
112
111
|
}
|
|
113
112
|
function parseDefaultTabStop(root) {
|
|
114
|
-
if (!root) return
|
|
113
|
+
if (!root) return DEFAULT_TAB_STOP_TWIPS$1;
|
|
115
114
|
const el = findChild(root, "w", "defaultTabStop");
|
|
116
|
-
if (!el) return
|
|
115
|
+
if (!el) return DEFAULT_TAB_STOP_TWIPS$1;
|
|
117
116
|
const raw = getAttribute(el, "w", "val");
|
|
118
|
-
if (raw === null) return
|
|
117
|
+
if (raw === null) return DEFAULT_TAB_STOP_TWIPS$1;
|
|
119
118
|
const parsed = Number.parseInt(raw, 10);
|
|
120
|
-
if (!Number.isFinite(parsed) || parsed < MIN_TAB_STOP_TWIPS || parsed > MAX_TAB_STOP_TWIPS) return
|
|
119
|
+
if (!Number.isFinite(parsed) || parsed < MIN_TAB_STOP_TWIPS || parsed > MAX_TAB_STOP_TWIPS) return DEFAULT_TAB_STOP_TWIPS$1;
|
|
121
120
|
return parsed;
|
|
122
121
|
}
|
|
123
122
|
//#endregion
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/docx/storyBlockReplay.d.ts
|
|
3
|
+
type StoryBlockReplayOptions = {
|
|
4
|
+
sourceXml: string;
|
|
5
|
+
baselineContent: readonly document_d_exports.BlockContent[];
|
|
6
|
+
currentContent: readonly document_d_exports.BlockContent[];
|
|
7
|
+
serializedXml: string;
|
|
8
|
+
};
|
|
9
|
+
declare const buildStoryBlockReplay: (options: StoryBlockReplayOptions) => string | null;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { buildStoryBlockReplay };
|