@stll/folio-core 0.54.2 → 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.js +22 -1
- package/dist/ai-edits/headless.js +1 -0
- 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/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/ensureParaIds.d.ts +7 -1
- package/dist/docx/ensureParaIds.js +163 -211
- 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/noteIds.d.ts +5 -0
- package/dist/docx/noteIds.js +6 -2
- package/dist/docx/noteReferenceMark.d.ts +3 -1
- package/dist/docx/noteReferenceMark.js +15 -14
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +17 -3
- 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/parser.js +2 -1
- 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 +107 -45
- 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 +4 -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 +2 -1
- package/dist/docx/serializer/runSerializer.js +3 -1
- 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 +22 -1
- package/dist/docx/streamingXmlParser.js +49 -3
- package/dist/docx/structuralXmlPatch.js +8 -1
- 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/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/toFlowBlocks.d.ts +2 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
- 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/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/pageBreak.js +15 -1
- 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/ParagraphExtension.js +50 -19
- 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/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/suggestionMode.js +50 -2
- 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/textBoxAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/textInput.js +5 -1
- 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/validation.js +4 -0
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/createDocument.js +2 -2
- 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,3 +1,4 @@
|
|
|
1
|
+
import { FOLIO_REVIEW_HISTORY_NAMESPACE } from "../reviewHistoryNamespace.js";
|
|
1
2
|
import { toTransitionalNamespaceUri } from "../transitionalSpelling.js";
|
|
2
3
|
import { TaggedError } from "better-result";
|
|
3
4
|
import { assertValidOoxmlNumericIds, escapeXmlAttribute } from "@stll/docx-core";
|
|
@@ -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: {
|
|
@@ -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";
|
|
@@ -51,7 +52,7 @@ function getUniqueId(id) {
|
|
|
51
52
|
}
|
|
52
53
|
function serializeRunPropertyChange(change) {
|
|
53
54
|
const previousRPrXml = serializeTextFormatting(change.previousFormatting) || "<w:rPr/>";
|
|
54
|
-
return `<w:rPrChange ${serializeTrackedChangeAttributes(change.info)}>${previousRPrXml}</w:rPrChange>`;
|
|
55
|
+
return `<w:rPrChange ${serializeTrackedChangeAttributes(change.info)}${serializeBoundaryJoins(change.boundaryJoins)}>${previousRPrXml}</w:rPrChange>`;
|
|
55
56
|
}
|
|
56
57
|
function serializeRunProperties(formatting, propertyChanges) {
|
|
57
58
|
const propertyChange = getSingularRunPropertyChange(propertyChanges);
|
|
@@ -537,6 +538,7 @@ function serializeRunContent(content) {
|
|
|
537
538
|
case "symbol": return serializeSymbolContent(content);
|
|
538
539
|
case "footnoteRef":
|
|
539
540
|
case "endnoteRef": return serializeNoteReference(content);
|
|
541
|
+
case "noteMarker": return content.kind === "footnote" ? "<w:footnoteRef/>" : "<w:endnoteRef/>";
|
|
540
542
|
case "fieldChar": return serializeFieldChar(content);
|
|
541
543
|
case "instrText": return serializeInstrText(content);
|
|
542
544
|
case "softHyphen": return serializeSoftHyphen(content);
|
|
@@ -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 };
|