@portone/docx-editor 0.3.0 → 0.5.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/CHANGELOG.md +205 -0
- package/assets/editor.png +0 -0
- package/dist/DocxEditor.d.ts +1 -1
- package/dist/DocxEditor.js +45 -25
- package/dist/core.d.ts +1 -1
- package/dist/docx/cloning.js +4 -9
- package/dist/docx/commentOnlyChange.d.ts +5 -3
- package/dist/docx/comments/grammar.d.ts +27 -10
- package/dist/docx/comments/grammar.js +18 -67
- package/dist/docx/comments/model.d.ts +5 -6
- package/dist/docx/comments/model.js +0 -9
- package/dist/docx/comments/parts.d.ts +16 -10
- package/dist/docx/comments/parts.js +65 -13
- package/dist/docx/comments/people.d.ts +11 -3
- package/dist/docx/comments/people.js +20 -6
- package/dist/docx/comments/policy.js +7 -1
- package/dist/docx/comments/reading.d.ts +4 -2
- package/dist/docx/comments/reading.js +1 -14
- package/dist/docx/comments/writing.js +78 -35
- package/dist/docx/exportDocx.js +30 -18
- package/dist/docx/exportRefs.d.ts +8 -3
- package/dist/docx/exportRefs.js +2 -1
- package/dist/docx/fidelity.js +24 -10
- package/dist/docx/fields.d.ts +42 -0
- package/dist/docx/fields.js +76 -0
- package/dist/docx/formatting/attrs.d.ts +20 -2
- package/dist/docx/formatting/attrs.js +57 -2
- package/dist/docx/formatting/context.d.ts +10 -2
- package/dist/docx/formatting/context.js +23 -5
- package/dist/docx/formatting/resolve.d.ts +10 -4
- package/dist/docx/formatting/resolve.js +31 -11
- package/dist/docx/formatting/styles.d.ts +25 -2
- package/dist/docx/formatting/styles.js +84 -3
- package/dist/docx/headersFooters.d.ts +89 -20
- package/dist/docx/headersFooters.js +163 -172
- package/dist/docx/hyperlink.d.ts +14 -4
- package/dist/docx/hyperlink.js +4 -1
- package/dist/docx/importDocx.d.ts +1 -1
- package/dist/docx/importDocx.js +135 -74
- package/dist/docx/importParagraph.d.ts +16 -4
- package/dist/docx/importParagraph.js +87 -93
- package/dist/docx/importPolicy.d.ts +70 -0
- package/dist/docx/importPolicy.js +190 -0
- package/dist/docx/importPreserved.d.ts +30 -0
- package/dist/docx/importPreserved.js +54 -0
- package/dist/docx/importTable.d.ts +2 -2
- package/dist/docx/importTable.js +107 -66
- package/dist/docx/invariants.js +42 -31
- package/dist/docx/newLists.d.ts +30 -0
- package/dist/docx/newLists.js +24 -1
- package/dist/docx/notes.d.ts +6 -1
- package/dist/docx/notes.js +6 -16
- package/dist/docx/numberingPlanner.d.ts +6 -3
- package/dist/docx/numberingPlanner.js +38 -7
- package/dist/docx/pageGeometry.d.ts +5 -14
- package/dist/docx/pageGeometry.js +0 -12
- package/dist/docx/protectionPolicy.d.ts +13 -5
- package/dist/docx/protectionPolicy.js +32 -22
- package/dist/docx/scan.d.ts +18 -8
- package/dist/docx/scan.js +17 -11
- package/dist/docx/sections.d.ts +126 -0
- package/dist/docx/sections.js +207 -0
- package/dist/docx/serializeBlock.d.ts +13 -4
- package/dist/docx/serializeBlock.js +16 -18
- package/dist/docx/serializeParagraph.d.ts +4 -0
- package/dist/docx/serializeParagraph.js +1 -0
- package/dist/docx/serializePreserved.d.ts +14 -0
- package/dist/docx/serializePreserved.js +24 -0
- package/dist/docx/serializeStory.d.ts +17 -0
- package/dist/docx/serializeStory.js +17 -0
- package/dist/docx/serializeTable.js +10 -13
- package/dist/docx/session.d.ts +24 -7
- package/dist/docx/session.js +37 -6
- package/dist/docx/story.d.ts +140 -0
- package/dist/docx/story.js +237 -0
- package/dist/docx/storyProjection.js +6 -1
- package/dist/docx/tableFormatting/conditions.d.ts +76 -0
- package/dist/docx/tableFormatting/conditions.js +196 -0
- package/dist/docx/tableFormatting/editing.d.ts +7 -3
- package/dist/docx/tableFormatting/editing.js +4 -5
- package/dist/docx/tableFormatting/reading.d.ts +49 -19
- package/dist/docx/tableFormatting/reading.js +109 -35
- package/dist/docx/tableFormatting.d.ts +1 -0
- package/dist/docx/tableFormatting.js +1 -0
- package/dist/docx/tableTemplate.js +12 -12
- package/dist/editor/clipboard/htmlReader.d.ts +30 -0
- package/dist/editor/clipboard/htmlReader.js +302 -0
- package/dist/editor/clipboard/internalChannel.d.ts +57 -0
- package/dist/editor/clipboard/internalChannel.js +58 -0
- package/dist/editor/clipboard/normalizers.d.ts +99 -0
- package/dist/editor/clipboard/normalizers.js +199 -0
- package/dist/editor/clipboard/parser.d.ts +34 -0
- package/dist/editor/clipboard/parser.js +58 -0
- package/dist/editor/clipboard/plugin.d.ts +21 -0
- package/dist/editor/clipboard/plugin.js +320 -0
- package/dist/editor/clipboard/readContext.d.ts +24 -0
- package/dist/editor/clipboard/readContext.js +19 -0
- package/dist/editor/clipboard/readers.d.ts +33 -0
- package/dist/editor/clipboard/readers.js +37 -0
- package/dist/editor/commands/comments/editing.d.ts +26 -6
- package/dist/editor/commands/comments/editing.js +175 -105
- package/dist/editor/commands/comments/model.d.ts +34 -17
- package/dist/editor/commands/comments/model.js +11 -0
- package/dist/editor/commands/comments/reading.d.ts +5 -3
- package/dist/editor/commands/comments/reading.js +8 -58
- package/dist/editor/commands/formatting/propertyCommands.js +6 -1
- package/dist/editor/commands/index.d.ts +2 -2
- package/dist/editor/commands/index.js +2 -0
- package/dist/editor/commands/listCommands.d.ts +12 -3
- package/dist/editor/commands/listCommands.js +76 -30
- package/dist/editor/commands/noteQueries.d.ts +22 -5
- package/dist/editor/commands/noteQueries.js +34 -6
- package/dist/editor/commands/paragraphCommands.js +6 -1
- package/dist/editor/createEditor.js +14 -4
- package/dist/editor/documentStyles.d.ts +26 -4
- package/dist/editor/documentStyles.js +9 -4
- package/dist/editor/editorDocument.d.ts +7 -6
- package/dist/editor/editorDocument.js +18 -6
- package/dist/editor/imageFiles.d.ts +2 -2
- package/dist/editor/imageFiles.js +2 -0
- package/dist/editor/insertTable.d.ts +1 -1
- package/dist/editor/insertTable.js +2 -2
- package/dist/editor/paragraphEdits.d.ts +16 -1
- package/dist/editor/paragraphEdits.js +13 -5
- package/dist/editor/paragraphPlacement.d.ts +11 -0
- package/dist/editor/paragraphPlacement.js +18 -0
- package/dist/editor/plainText.d.ts +12 -0
- package/dist/editor/plainText.js +2 -1
- package/dist/editor/plugins/columnResize.js +6 -3
- package/dist/editor/plugins/commentComposer.d.ts +28 -0
- package/dist/editor/plugins/commentComposer.js +46 -0
- package/dist/editor/plugins/commentDecorations.d.ts +29 -2
- package/dist/editor/plugins/commentDecorations.js +89 -15
- package/dist/editor/plugins/documentProjection.d.ts +31 -0
- package/dist/editor/plugins/documentProjection.js +22 -0
- package/dist/editor/plugins/imagePaste.js +20 -10
- package/dist/editor/plugins/linkPanel.d.ts +7 -3
- package/dist/editor/plugins/linkPanel.js +13 -27
- package/dist/editor/plugins/numberingDecorations.d.ts +10 -4
- package/dist/editor/plugins/numberingDecorations.js +43 -2
- package/dist/editor/plugins/panelState.d.ts +67 -0
- package/dist/editor/plugins/panelState.js +54 -0
- package/dist/editor/plugins/paragraphDisplay.js +9 -3
- package/dist/editor/plugins/tableContextMenu.d.ts +1 -1
- package/dist/editor/plugins/tableContextMenu.js +30 -47
- package/dist/editor/plugins/tableDisplay.js +19 -5
- package/dist/editor/plugins/textContextMenu.d.ts +1 -1
- package/dist/editor/plugins/textContextMenu.js +30 -47
- package/dist/model/format.d.ts +50 -0
- package/dist/model/format.js +65 -0
- package/dist/numbering/listRegistry.d.ts +37 -0
- package/dist/numbering/listRegistry.js +112 -0
- package/dist/numbering/listTemplate.d.ts +26 -17
- package/dist/numbering/listTemplate.js +66 -20
- package/dist/numbering/markers.d.ts +15 -6
- package/dist/numbering/markers.js +26 -59
- package/dist/numbering/parseNumbering.d.ts +70 -5
- package/dist/numbering/parseNumbering.js +100 -26
- package/dist/numbering/spellers.d.ts +15 -0
- package/dist/numbering/spellers.js +96 -0
- package/dist/numbering/writeNumbering.d.ts +5 -3
- package/dist/numbering/writeNumbering.js +15 -15
- package/dist/ooxml/conformance.d.ts +28 -0
- package/dist/ooxml/conformance.js +20 -0
- package/dist/ooxml/errors.d.ts +5 -5
- package/dist/ooxml/fragment.d.ts +11 -0
- package/dist/ooxml/fragment.js +14 -4
- package/dist/ooxml/image.d.ts +3 -4
- package/dist/ooxml/image.js +50 -5
- package/dist/ooxml/names.d.ts +15 -0
- package/dist/ooxml/names.js +10 -1
- package/dist/ooxml/partSplice.d.ts +1 -1
- package/dist/ooxml/partSplice.js +10 -3
- package/dist/ooxml/props.d.ts +8 -0
- package/dist/ooxml/props.js +14 -4
- package/dist/ooxml/rangeMarkers.d.ts +5 -0
- package/dist/ooxml/rangeMarkers.js +24 -0
- package/dist/ooxml/xml.d.ts +8 -9
- package/dist/ooxml/xml.js +6 -6
- package/dist/page/PageGuides.d.ts +8 -4
- package/dist/page/PageGuides.js +13 -37
- package/dist/page/pageLayout.d.ts +62 -13
- package/dist/page/pageLayout.js +91 -37
- package/dist/page/usePageLayout.d.ts +14 -11
- package/dist/page/usePageLayout.js +21 -29
- package/dist/schema/attrRoles.js +44 -19
- package/dist/schema/docxSchema.d.ts +9 -1
- package/dist/schema/docxSchema.js +220 -139
- package/dist/schema/editGuard.d.ts +1 -1
- package/dist/schema/guards.js +2 -2
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/preservedFragments.d.ts +12 -0
- package/dist/schema/preservedFragments.js +38 -0
- package/dist/schema/preservedGuards.d.ts +9 -7
- package/dist/schema/preservedGuards.js +112 -11
- package/dist/schema/protection.d.ts +34 -5
- package/dist/schema/protection.js +42 -14
- package/dist/schema/rendering.js +3 -1
- package/dist/schema/stories.d.ts +49 -0
- package/dist/schema/stories.js +78 -0
- package/dist/styles/classNames.d.ts +16 -7
- package/dist/styles/classNames.js +16 -7
- package/dist/styles.css +90 -30
- package/dist/table/cellFormatting.js +1 -2
- package/dist/table/gridBorders.d.ts +11 -15
- package/dist/table/gridBorders.js +32 -18
- package/dist/table/resize.d.ts +5 -3
- package/dist/ui/CommentsPanel.d.ts +1 -3
- package/dist/ui/CommentsPanel.js +24 -15
- package/dist/ui/NotesPanel.js +2 -2
- package/dist/ui/TextMenu.d.ts +1 -3
- package/dist/ui/TextMenu.js +10 -6
- package/dist/ui/comments/CommentComposer.d.ts +6 -1
- package/dist/ui/comments/CommentComposer.js +26 -3
- package/package.json +1 -1
- package/dist/editor/externalClipboard.d.ts +0 -11
- package/dist/editor/externalClipboard.js +0 -456
package/dist/docx/importDocx.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// src/docx/importDocx.ts
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
bindsWritingPrefix,
|
|
4
|
+
conformanceOf,
|
|
5
|
+
STRICT_OFFICE_DOCUMENT_REL
|
|
6
|
+
} from "../ooxml/conformance.js";
|
|
4
7
|
import { DocxImportError } from "../ooxml/errors.js";
|
|
5
8
|
import {
|
|
6
9
|
childByLocalName,
|
|
@@ -12,7 +15,10 @@ import {
|
|
|
12
15
|
withXmlParser
|
|
13
16
|
} from "../ooxml/xml.js";
|
|
14
17
|
import { docxSchema } from "../schema/index.js";
|
|
15
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
commentReferencesIn,
|
|
20
|
+
readComments
|
|
21
|
+
} from "./comments.js";
|
|
16
22
|
import { openParts } from "./container.js";
|
|
17
23
|
import {
|
|
18
24
|
DEFAULT_TAB_STOP_PT,
|
|
@@ -23,39 +29,53 @@ import { fidelityNotesOf } from "./fidelity.js";
|
|
|
23
29
|
import {
|
|
24
30
|
formattingContextOf,
|
|
25
31
|
NO_DOCUMENT_DEFAULTS,
|
|
26
|
-
paragraphAttrsOf,
|
|
27
32
|
readDocumentDefaults,
|
|
28
|
-
readParagraphStyles
|
|
29
|
-
resolveParagraph,
|
|
30
|
-
runMarkUnder
|
|
33
|
+
readParagraphStyles
|
|
31
34
|
} from "./formatting.js";
|
|
32
|
-
import {
|
|
35
|
+
import { readHeaderFooterStories } from "./headersFooters.js";
|
|
33
36
|
import { readLinkTargets } from "./hyperlink.js";
|
|
34
|
-
import {
|
|
35
|
-
import { buildTable } from "./importTable.js";
|
|
37
|
+
import { NO_IMPORT_SOURCES } from "./importParagraph.js";
|
|
36
38
|
import { readImageSources } from "./media.js";
|
|
39
|
+
import { NUMBERING_REL_TYPE } from "./newLists.js";
|
|
37
40
|
import { readNotes } from "./notes.js";
|
|
38
41
|
import { readPart, relatedPartPath } from "./packageParts.js";
|
|
39
|
-
import {
|
|
42
|
+
import { A4_PORTRAIT } from "./pageGeometry.js";
|
|
40
43
|
import { readRelationships } from "./relationships.js";
|
|
41
44
|
import { scanBody } from "./scan.js";
|
|
45
|
+
import {
|
|
46
|
+
firstSectPrElement,
|
|
47
|
+
readSectionProperties,
|
|
48
|
+
storyReferenceIds
|
|
49
|
+
} from "./sections.js";
|
|
42
50
|
import {
|
|
43
51
|
BODY_STORY_KEY,
|
|
44
52
|
blockKey,
|
|
45
53
|
newSessionId,
|
|
46
54
|
SessionStore
|
|
47
55
|
} from "./session.js";
|
|
56
|
+
import {
|
|
57
|
+
buildBlock,
|
|
58
|
+
readStories,
|
|
59
|
+
storiesByKey,
|
|
60
|
+
withStyleFormats
|
|
61
|
+
} from "./story.js";
|
|
48
62
|
import { NO_THEME_FONTS, readThemeFonts } from "./theme.js";
|
|
49
63
|
var OFFICE_DOCUMENT_REL = `${R_NS}/officeDocument`;
|
|
50
64
|
var STYLES_REL = `${R_NS}/styles`;
|
|
51
|
-
var NUMBERING_REL = `${R_NS}/numbering`;
|
|
52
65
|
var THEME_REL = `${R_NS}/theme`;
|
|
53
66
|
var SETTINGS_REL = `${R_NS}/settings`;
|
|
54
67
|
function findMainPartPath(parts) {
|
|
55
|
-
const
|
|
68
|
+
const relationships = readRelationships(parts, "_rels/.rels");
|
|
69
|
+
const target = relationships.find(
|
|
56
70
|
(rel) => rel.type === OFFICE_DOCUMENT_REL
|
|
57
71
|
)?.target;
|
|
58
72
|
if (!target) {
|
|
73
|
+
if (relationships.some((rel) => rel.type === STRICT_OFFICE_DOCUMENT_REL)) {
|
|
74
|
+
throw new DocxImportError(
|
|
75
|
+
"unsupported-conformance",
|
|
76
|
+
"the package relates its main document part as an ECMA-376 Strict one"
|
|
77
|
+
);
|
|
78
|
+
}
|
|
59
79
|
throw new DocxImportError(
|
|
60
80
|
"missing-part",
|
|
61
81
|
"no relationship pointing at the main document part"
|
|
@@ -63,60 +83,25 @@ function findMainPartPath(parts) {
|
|
|
63
83
|
}
|
|
64
84
|
return target.replace(/^\//, "");
|
|
65
85
|
}
|
|
66
|
-
function
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
if (el.localName === "p") {
|
|
74
|
-
const paragraph = buildParagraph(el, srcId, sources);
|
|
75
|
-
if (paragraph) return paragraph;
|
|
86
|
+
function assertWritableMainPart(root) {
|
|
87
|
+
if (conformanceOf(root) === "strict") {
|
|
88
|
+
throw new DocxImportError(
|
|
89
|
+
"unsupported-conformance",
|
|
90
|
+
"the main document part is written in the ECMA-376 Strict vocabulary"
|
|
91
|
+
);
|
|
76
92
|
}
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
sources,
|
|
82
|
-
context.styles,
|
|
83
|
-
context.defaultTableStyleId
|
|
93
|
+
if (conformanceOf(root) !== "transitional" || root.localName !== "document") {
|
|
94
|
+
throw new DocxImportError(
|
|
95
|
+
"unsupported-content",
|
|
96
|
+
"the main part is not a Transitional WordprocessingML document"
|
|
84
97
|
);
|
|
85
|
-
if (table) return table;
|
|
86
98
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const paragraph = resolveParagraph(
|
|
92
|
-
typeof pPr === "string" ? pPr : null,
|
|
93
|
-
context
|
|
94
|
-
);
|
|
95
|
-
const inline = node.children.map((child) => {
|
|
96
|
-
const mark = runMarkUnder(
|
|
97
|
-
child.marks.find((entry) => entry.type === docxSchema.marks.run) ?? null,
|
|
98
|
-
child.isText,
|
|
99
|
-
paragraph,
|
|
100
|
-
context
|
|
99
|
+
if (!bindsWritingPrefix(root)) {
|
|
100
|
+
throw new DocxImportError(
|
|
101
|
+
"unsupported-content",
|
|
102
|
+
"the main document part binds WordprocessingML to a prefix other than w"
|
|
101
103
|
);
|
|
102
|
-
return mark ? child.mark(mark.addToSet(child.marks)) : child;
|
|
103
|
-
});
|
|
104
|
-
return node.type.create(
|
|
105
|
-
{ ...node.attrs, ...paragraphAttrsOf(paragraph) },
|
|
106
|
-
Fragment.fromArray(inline),
|
|
107
|
-
node.marks
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
function withStyleFormats(node, context) {
|
|
111
|
-
if (node.type === docxSchema.nodes.paragraph) {
|
|
112
|
-
return styledParagraph(node, context);
|
|
113
104
|
}
|
|
114
|
-
if (node.childCount === 0) return node;
|
|
115
|
-
const children = node.children.map(
|
|
116
|
-
(child) => withStyleFormats(child, context)
|
|
117
|
-
);
|
|
118
|
-
if (children.every((child, i) => child === node.child(i))) return node;
|
|
119
|
-
return node.copy(Fragment.fromArray(children));
|
|
120
105
|
}
|
|
121
106
|
function assertScanMatchesDom(children, scan) {
|
|
122
107
|
if (children.length !== scan.blocks.length) {
|
|
@@ -134,16 +119,46 @@ function assertScanMatchesDom(children, scan) {
|
|
|
134
119
|
}
|
|
135
120
|
});
|
|
136
121
|
}
|
|
137
|
-
function
|
|
122
|
+
function splitTrailingSectPr(scan) {
|
|
138
123
|
const last = scan.blocks.at(-1);
|
|
139
|
-
if (
|
|
140
|
-
|
|
124
|
+
if (!last || localPart(last.name) !== "sectPr") {
|
|
125
|
+
return { ...scan, sectPr: null };
|
|
126
|
+
}
|
|
141
127
|
return {
|
|
142
128
|
prefix: scan.prefix,
|
|
143
129
|
blocks: scan.blocks.slice(0, -1),
|
|
144
|
-
suffix:
|
|
130
|
+
suffix: scan.suffix,
|
|
131
|
+
sectPr: last.xml
|
|
145
132
|
};
|
|
146
133
|
}
|
|
134
|
+
function storyDeps(parts, partPath, sessionId, formatting) {
|
|
135
|
+
return {
|
|
136
|
+
session: { sessionId },
|
|
137
|
+
sources: {
|
|
138
|
+
...NO_IMPORT_SOURCES,
|
|
139
|
+
images: readImageSources(parts, partPath),
|
|
140
|
+
links: readLinkTargets(parts, partPath),
|
|
141
|
+
themeFonts: formatting.themeFonts
|
|
142
|
+
},
|
|
143
|
+
formatting
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function readCommentStories(comments, parts, sessionId, formatting) {
|
|
147
|
+
const { partPath, xml } = comments;
|
|
148
|
+
if (partPath === null || xml === null) return [];
|
|
149
|
+
return readStories(
|
|
150
|
+
{ kind: "comment", partPath, xml, entryName: "comment", idAttr: "id" },
|
|
151
|
+
storyDeps(parts, partPath, sessionId, formatting)
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
function readNoteStories(part, kind, parts, sessionId, formatting) {
|
|
155
|
+
const { partPath, xml } = part;
|
|
156
|
+
if (partPath === null || xml === null) return [];
|
|
157
|
+
return readStories(
|
|
158
|
+
{ kind, partPath, xml, entryName: kind, idAttr: "id" },
|
|
159
|
+
storyDeps(parts, partPath, sessionId, formatting)
|
|
160
|
+
);
|
|
161
|
+
}
|
|
147
162
|
function importDocx(input, options) {
|
|
148
163
|
return withXmlParser(options?.xmlParser, () => readDocx(input));
|
|
149
164
|
}
|
|
@@ -158,14 +173,17 @@ function readDocx(input) {
|
|
|
158
173
|
const { text: source, hadBom } = decodeUtf8(mainPart);
|
|
159
174
|
const scanned = scanBody(source);
|
|
160
175
|
const dom = parseXml(source);
|
|
176
|
+
assertWritableMainPart(dom.documentElement);
|
|
161
177
|
const body = childByLocalName(dom.documentElement, "body");
|
|
162
178
|
if (!body) {
|
|
163
179
|
throw new DocxImportError("missing-body", "document has no w:body");
|
|
164
180
|
}
|
|
165
181
|
const children = elementChildren(body);
|
|
166
182
|
assertScanMatchesDom(children, scanned);
|
|
167
|
-
const
|
|
168
|
-
const
|
|
183
|
+
const firstSectPr = firstSectPrElement(body);
|
|
184
|
+
const firstSection = firstSectPr ? readSectionProperties(firstSectPr) : null;
|
|
185
|
+
const geometry = firstSection?.geometry ?? A4_PORTRAIT;
|
|
186
|
+
const scan = splitTrailingSectPr(scanned);
|
|
169
187
|
const blockElements = children.slice(0, scan.blocks.length);
|
|
170
188
|
const stylesXml = readPart(
|
|
171
189
|
parts,
|
|
@@ -178,7 +196,11 @@ function readDocx(input) {
|
|
|
178
196
|
);
|
|
179
197
|
const settingsDom = settingsXml === null ? null : parseXml(settingsXml);
|
|
180
198
|
const defaultTabStopPt = readDefaultTabStop(settingsDom) ?? DEFAULT_TAB_STOP_PT;
|
|
181
|
-
const numberingPartPath = relatedPartPath(
|
|
199
|
+
const numberingPartPath = relatedPartPath(
|
|
200
|
+
parts,
|
|
201
|
+
mainPartPath,
|
|
202
|
+
NUMBERING_REL_TYPE
|
|
203
|
+
);
|
|
182
204
|
const themeXml = readPart(
|
|
183
205
|
parts,
|
|
184
206
|
relatedPartPath(parts, mainPartPath, THEME_REL)
|
|
@@ -187,7 +209,7 @@ function readDocx(input) {
|
|
|
187
209
|
const numberingXml = readPart(parts, numberingPartPath);
|
|
188
210
|
const formatting = formattingContextOf(
|
|
189
211
|
stylesDom,
|
|
190
|
-
|
|
212
|
+
numberingXml,
|
|
191
213
|
themeFonts,
|
|
192
214
|
readCompatSettings(settingsDom)
|
|
193
215
|
);
|
|
@@ -205,7 +227,6 @@ function readDocx(input) {
|
|
|
205
227
|
labels.set(id, label);
|
|
206
228
|
return label;
|
|
207
229
|
};
|
|
208
|
-
const headersFooters = readHeadersFooters(parts, mainPartPath, body);
|
|
209
230
|
const sources = {
|
|
210
231
|
images: readImageSources(parts, mainPartPath),
|
|
211
232
|
themeFonts,
|
|
@@ -215,6 +236,24 @@ function readDocx(input) {
|
|
|
215
236
|
noteLabel
|
|
216
237
|
};
|
|
217
238
|
const sessionId = newSessionId();
|
|
239
|
+
const headerFooters = readHeaderFooterStories(
|
|
240
|
+
parts,
|
|
241
|
+
mainPartPath,
|
|
242
|
+
storyReferenceIds(body),
|
|
243
|
+
(partPath) => storyDeps(parts, partPath, sessionId, formatting)
|
|
244
|
+
);
|
|
245
|
+
const stories = storiesByKey([
|
|
246
|
+
...readCommentStories(comments, parts, sessionId, formatting),
|
|
247
|
+
...readNoteStories(
|
|
248
|
+
notes.footnotes,
|
|
249
|
+
"footnote",
|
|
250
|
+
parts,
|
|
251
|
+
sessionId,
|
|
252
|
+
formatting
|
|
253
|
+
),
|
|
254
|
+
...readNoteStories(notes.endnotes, "endnote", parts, sessionId, formatting),
|
|
255
|
+
...headerFooters.stories
|
|
256
|
+
]);
|
|
218
257
|
const blockNodes = blockElements.map(
|
|
219
258
|
(el, i) => withStyleFormats(
|
|
220
259
|
buildBlock(
|
|
@@ -226,7 +265,25 @@ function readDocx(input) {
|
|
|
226
265
|
formatting
|
|
227
266
|
)
|
|
228
267
|
);
|
|
229
|
-
|
|
268
|
+
if (blockNodes.length === 0 && scan.sectPr !== null) {
|
|
269
|
+
blockNodes.push(
|
|
270
|
+
withStyleFormats(
|
|
271
|
+
docxSchema.nodes.paragraph.create({
|
|
272
|
+
srcId: blockKey({ sessionId }, BODY_STORY_KEY, 0)
|
|
273
|
+
}),
|
|
274
|
+
formatting
|
|
275
|
+
)
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
const doc = docxSchema.nodes.doc.create(
|
|
279
|
+
{
|
|
280
|
+
sectPr: scan.sectPr,
|
|
281
|
+
stories: Object.fromEntries(
|
|
282
|
+
Array.from(stories, ([key, story]) => [key, story.doc.toJSON()])
|
|
283
|
+
)
|
|
284
|
+
},
|
|
285
|
+
blockNodes
|
|
286
|
+
);
|
|
230
287
|
return {
|
|
231
288
|
doc,
|
|
232
289
|
notes: fidelityNotesOf(doc, mainPartPath),
|
|
@@ -237,7 +294,10 @@ function readDocx(input) {
|
|
|
237
294
|
documentPrefix: scan.prefix,
|
|
238
295
|
documentSuffix: scan.suffix,
|
|
239
296
|
documentHadBom: hadBom,
|
|
240
|
-
blocks: blockNodes.map((node, i) => ({
|
|
297
|
+
blocks: blockNodes.map((node, i) => ({
|
|
298
|
+
xml: scan.blocks[i]?.xml ?? "",
|
|
299
|
+
node
|
|
300
|
+
})),
|
|
241
301
|
defaults: stylesDom ? readDocumentDefaults(stylesDom, themeFonts) : NO_DOCUMENT_DEFAULTS,
|
|
242
302
|
defaultTabStopPt,
|
|
243
303
|
geometry,
|
|
@@ -247,7 +307,8 @@ function readDocx(input) {
|
|
|
247
307
|
numberingPartPath,
|
|
248
308
|
comments,
|
|
249
309
|
commentReferenceIds: new Set(commentReferencesIn(doc).keys()),
|
|
250
|
-
|
|
310
|
+
headerFooterStories: headerFooters.refs,
|
|
311
|
+
stories
|
|
251
312
|
})
|
|
252
313
|
};
|
|
253
314
|
}
|
|
@@ -6,10 +6,16 @@
|
|
|
6
6
|
* A `w:sdt` content control and a `w:hyperlink` standing inside the paragraph are both unwrapped, so
|
|
7
7
|
* the text they hold stays editable, and the wrapper each came in rides along on a mark to go back
|
|
8
8
|
* out around the same text. A control may hold a link; a link holding a control is a nesting the
|
|
9
|
-
* marks cannot record in that order,
|
|
9
|
+
* marks cannot record in that order, and that control stays whole as one preserved fragment.
|
|
10
|
+
*
|
|
11
|
+
* Nothing here demotes a paragraph. What the editor has no model for - a field character, a
|
|
12
|
+
* tracked insertion, a symbol, a drawing nobody could read - is kept where it stood, inside its
|
|
13
|
+
* run or beside it, by the rule `docx/importPolicy` gives it for the level it stands at. The
|
|
14
|
+
* paragraph around it stays editable, which is what a document full of `w:lastRenderedPageBreak`
|
|
15
|
+
* needs.
|
|
10
16
|
*/
|
|
11
17
|
import type { Node as PMNode } from "prosemirror-model";
|
|
12
|
-
import { type ImportedComments } from "./comments";
|
|
18
|
+
import { type ImportedComments } from "./comments/reading";
|
|
13
19
|
import { type LinkTargets } from "./hyperlink";
|
|
14
20
|
import type { ImageSources } from "./media";
|
|
15
21
|
import { type ImportedNotes, type NoteKind } from "./notes";
|
|
@@ -28,5 +34,11 @@ export interface ImportSources {
|
|
|
28
34
|
noteLabel: (kind: NoteKind, id: string) => string;
|
|
29
35
|
}
|
|
30
36
|
export declare const NO_IMPORT_SOURCES: ImportSources;
|
|
31
|
-
/**
|
|
32
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Moves a paragraph into an editable node.
|
|
39
|
+
*
|
|
40
|
+
* Every paragraph opens editable. A child the reader has no model for, and a control or a link
|
|
41
|
+
* whose shape it could not put back together, is kept whole where it stood instead of standing
|
|
42
|
+
* the whole paragraph down.
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildParagraph(el: Element, srcId: string | null, sources?: ImportSources): PMNode;
|
|
@@ -9,16 +9,19 @@ import {
|
|
|
9
9
|
serializeXml
|
|
10
10
|
} from "../ooxml/xml.js";
|
|
11
11
|
import { docxSchema } from "../schema/index.js";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
importedCommentReplies,
|
|
15
|
-
NO_COMMENTS
|
|
16
|
-
} from "./comments.js";
|
|
12
|
+
import { commentParaId, importedCommentReplies } from "./comments/model.js";
|
|
13
|
+
import { NO_COMMENTS } from "./comments/reading.js";
|
|
17
14
|
import { readParagraphFormat, readRunFormat } from "./formatting.js";
|
|
18
15
|
import {
|
|
19
16
|
NO_LINK_TARGETS,
|
|
20
17
|
readHyperlinkWrapper
|
|
21
18
|
} from "./hyperlink.js";
|
|
19
|
+
import { policyFor } from "./importPolicy.js";
|
|
20
|
+
import {
|
|
21
|
+
buildPreservedInline,
|
|
22
|
+
buildPreservedRunContent,
|
|
23
|
+
preservationOf
|
|
24
|
+
} from "./importPreserved.js";
|
|
22
25
|
import { NO_IMAGES } from "./media.js";
|
|
23
26
|
import { NO_NOTES, noteById } from "./notes.js";
|
|
24
27
|
import { readSdtWrapper } from "./sdt.js";
|
|
@@ -47,7 +50,7 @@ function buildImage(el, marks, images) {
|
|
|
47
50
|
marks
|
|
48
51
|
);
|
|
49
52
|
}
|
|
50
|
-
function
|
|
53
|
+
function buildModelledRunChild(el, marks, images, comments, notes, noteLabel) {
|
|
51
54
|
switch (el.localName) {
|
|
52
55
|
case "t": {
|
|
53
56
|
const text = el.textContent ?? "";
|
|
@@ -86,9 +89,6 @@ function buildRunChild(el, marks, images, comments, notes, noteLabel) {
|
|
|
86
89
|
authorId: comment?.authorId ?? null,
|
|
87
90
|
initials: comment?.initials ?? null,
|
|
88
91
|
date: comment?.date ?? null,
|
|
89
|
-
text: comment?.text ?? "",
|
|
90
|
-
commentXml: comment?.xml ?? null,
|
|
91
|
-
imported: true,
|
|
92
92
|
paraId,
|
|
93
93
|
resolved: comment?.resolved ?? false,
|
|
94
94
|
extensionXml: comment?.extensionXml ?? null,
|
|
@@ -114,7 +114,6 @@ function buildRunChild(el, marks, images, comments, notes, noteLabel) {
|
|
|
114
114
|
kind,
|
|
115
115
|
id,
|
|
116
116
|
label: note ? noteLabel(kind, id) : "?",
|
|
117
|
-
text: note?.text ?? "",
|
|
118
117
|
customMarkFollows,
|
|
119
118
|
referenceXml: serializeXml(el)
|
|
120
119
|
},
|
|
@@ -135,22 +134,30 @@ function buildRunNodes(run, images, themeFonts, comments, notes, noteLabel, wrap
|
|
|
135
134
|
);
|
|
136
135
|
const nodes = [];
|
|
137
136
|
for (const child of elementChildren(run)) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
child
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
const policy = policyFor(child, "r");
|
|
138
|
+
if (policy.tier === "model") {
|
|
139
|
+
if (child.localName === "rPr") continue;
|
|
140
|
+
const built = buildModelledRunChild(
|
|
141
|
+
child,
|
|
142
|
+
marks,
|
|
143
|
+
images,
|
|
144
|
+
comments,
|
|
145
|
+
notes,
|
|
146
|
+
noteLabel
|
|
147
|
+
);
|
|
148
|
+
if (built !== null) {
|
|
149
|
+
nodes.push(...built);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
nodes.push(
|
|
154
|
+
buildPreservedRunContent(child, marks, preservationOf(policy, "r"))
|
|
146
155
|
);
|
|
147
|
-
if (built === null) return null;
|
|
148
|
-
nodes.push(...built);
|
|
149
156
|
}
|
|
150
157
|
if (nodes.length === 0) {
|
|
151
158
|
return [
|
|
152
159
|
docxSchema.nodes.rawInline.create(
|
|
153
|
-
{ xml: serializeXml(run) },
|
|
160
|
+
{ xml: serializeXml(run), element: run.localName },
|
|
154
161
|
null,
|
|
155
162
|
// The wrappers have to close again around this XML on export, so their marks ride along here too
|
|
156
163
|
wrappers
|
|
@@ -166,13 +173,6 @@ function nextKey(counts, el) {
|
|
|
166
173
|
counts.set(el.ownerDocument, key + 1);
|
|
167
174
|
return key;
|
|
168
175
|
}
|
|
169
|
-
var NOTHING_ON_SCREEN = [
|
|
170
|
-
"bookmarkStart",
|
|
171
|
-
"bookmarkEnd",
|
|
172
|
-
"proofErr",
|
|
173
|
-
"permStart",
|
|
174
|
-
"permEnd"
|
|
175
|
-
];
|
|
176
176
|
function annotationId(el) {
|
|
177
177
|
return Array.from(el.attributes).find((attribute) => attribute.localName === "id")?.value ?? null;
|
|
178
178
|
}
|
|
@@ -190,41 +190,42 @@ var NO_IMPORT_SOURCES = {
|
|
|
190
190
|
notes: NO_NOTES,
|
|
191
191
|
noteLabel: () => "?"
|
|
192
192
|
};
|
|
193
|
+
function buildModelledWrapperChild(child, sources, wrappers, linkAllowed) {
|
|
194
|
+
if (child.localName === "r") {
|
|
195
|
+
return buildRunNodes(
|
|
196
|
+
child,
|
|
197
|
+
sources.images,
|
|
198
|
+
sources.themeFonts,
|
|
199
|
+
sources.comments,
|
|
200
|
+
sources.notes,
|
|
201
|
+
sources.noteLabel,
|
|
202
|
+
wrappers
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (child.localName === "hyperlink") {
|
|
206
|
+
return linkAllowed ? buildHyperlinkNodes(child, sources, wrappers) : null;
|
|
207
|
+
}
|
|
208
|
+
const commentMarker = commentRangeNode(child, wrappers);
|
|
209
|
+
return commentMarker === null ? null : [commentMarker];
|
|
210
|
+
}
|
|
193
211
|
function buildWrappedNodes(content, sources, wrappers, linkAllowed) {
|
|
194
212
|
const nodes = [];
|
|
195
213
|
for (const child of elementChildren(content)) {
|
|
196
|
-
|
|
197
|
-
|
|
214
|
+
const policy = policyFor(child, "wrapper");
|
|
215
|
+
if (policy.tier === "model") {
|
|
216
|
+
const built = buildModelledWrapperChild(
|
|
198
217
|
child,
|
|
199
|
-
sources
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
sources.notes,
|
|
203
|
-
sources.noteLabel,
|
|
204
|
-
wrappers
|
|
218
|
+
sources,
|
|
219
|
+
wrappers,
|
|
220
|
+
linkAllowed
|
|
205
221
|
);
|
|
206
|
-
if (built
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (child.localName === "hyperlink" && linkAllowed) {
|
|
211
|
-
const built = buildHyperlinkNodes(child, sources, wrappers);
|
|
212
|
-
if (built === null) return null;
|
|
213
|
-
nodes.push(...built);
|
|
214
|
-
continue;
|
|
222
|
+
if (built !== null) {
|
|
223
|
+
nodes.push(...built);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
215
226
|
}
|
|
216
|
-
const commentMarker = commentRangeNode(child, wrappers);
|
|
217
|
-
if (commentMarker) {
|
|
218
|
-
nodes.push(commentMarker);
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
if (!NOTHING_ON_SCREEN.includes(child.localName)) return null;
|
|
222
227
|
nodes.push(
|
|
223
|
-
|
|
224
|
-
{ xml: serializeXml(child) },
|
|
225
|
-
null,
|
|
226
|
-
wrappers
|
|
227
|
-
)
|
|
228
|
+
buildPreservedInline(child, wrappers, preservationOf(policy, "wrapper"))
|
|
228
229
|
);
|
|
229
230
|
}
|
|
230
231
|
if (nodes.length === 0) return null;
|
|
@@ -251,48 +252,41 @@ function buildSdtNodes(el, sources) {
|
|
|
251
252
|
});
|
|
252
253
|
return buildWrappedNodes(wrapper.content, sources, [mark], true);
|
|
253
254
|
}
|
|
255
|
+
function buildModelledParagraphChild(child, sources) {
|
|
256
|
+
if (child.localName === "r") {
|
|
257
|
+
return buildRunNodes(
|
|
258
|
+
child,
|
|
259
|
+
sources.images,
|
|
260
|
+
sources.themeFonts,
|
|
261
|
+
sources.comments,
|
|
262
|
+
sources.notes,
|
|
263
|
+
sources.noteLabel
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
if (child.localName === "sdt") return buildSdtNodes(child, sources);
|
|
267
|
+
if (child.localName === "hyperlink") {
|
|
268
|
+
return buildHyperlinkNodes(child, sources, []);
|
|
269
|
+
}
|
|
270
|
+
const commentMarker = commentRangeNode(child);
|
|
271
|
+
return commentMarker === null ? null : [commentMarker];
|
|
272
|
+
}
|
|
254
273
|
function buildParagraph(el, srcId, sources = NO_IMPORT_SOURCES) {
|
|
255
|
-
const { images, themeFonts } = sources;
|
|
256
274
|
const inline = [];
|
|
257
275
|
let pPrElement = null;
|
|
258
276
|
for (const child of elementChildren(el)) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
277
|
+
const policy = policyFor(child, "p");
|
|
278
|
+
if (policy.tier === "model") {
|
|
279
|
+
if (child.localName === "pPr") {
|
|
280
|
+
pPrElement = child;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const built = buildModelledParagraphChild(child, sources);
|
|
284
|
+
if (built !== null) {
|
|
285
|
+
inline.push(...built);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
262
288
|
}
|
|
263
|
-
|
|
264
|
-
const runNodes = buildRunNodes(
|
|
265
|
-
child,
|
|
266
|
-
images,
|
|
267
|
-
themeFonts,
|
|
268
|
-
sources.comments,
|
|
269
|
-
sources.notes,
|
|
270
|
-
sources.noteLabel
|
|
271
|
-
);
|
|
272
|
-
if (runNodes === null) return null;
|
|
273
|
-
inline.push(...runNodes);
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
if (child.localName === "sdt") {
|
|
277
|
-
const sdtNodes = buildSdtNodes(child, sources);
|
|
278
|
-
if (sdtNodes === null) return null;
|
|
279
|
-
inline.push(...sdtNodes);
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
if (child.localName === "hyperlink") {
|
|
283
|
-
const linkNodes = buildHyperlinkNodes(child, sources, []);
|
|
284
|
-
if (linkNodes === null) return null;
|
|
285
|
-
inline.push(...linkNodes);
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
const commentMarker = commentRangeNode(child);
|
|
289
|
-
if (commentMarker) {
|
|
290
|
-
inline.push(commentMarker);
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
inline.push(
|
|
294
|
-
docxSchema.nodes.rawInline.create({ xml: serializeXml(child) })
|
|
295
|
-
);
|
|
289
|
+
inline.push(buildPreservedInline(child, [], preservationOf(policy, "p")));
|
|
296
290
|
}
|
|
297
291
|
return docxSchema.nodes.paragraph.create(
|
|
298
292
|
{
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What every WordprocessingML element the readers may meet is worth keeping as, one sub-table per
|
|
3
|
+
* level of the document.
|
|
4
|
+
*
|
|
5
|
+
* A reader used to know a handful of elements and answer `null` for the rest, and that `null`
|
|
6
|
+
* travelled up through the run and the wrapper until a whole paragraph stood as a placeholder. The
|
|
7
|
+
* table below turns that around: every level has a narrowest preservation of its own - a run child
|
|
8
|
+
* stays inside its run, a paragraph child inside its paragraph, a block stays a block - so an
|
|
9
|
+
* element nobody modelled costs the element and nothing around it.
|
|
10
|
+
*
|
|
11
|
+
* Only `tbl` and `tr` have no node to hold a stranger (`table` holds rows, `tableRow` holds
|
|
12
|
+
* cells), so those two levels demote the table instead, and that is the whole of what demotion is
|
|
13
|
+
* now: this default and a structure a reader could not take apart.
|
|
14
|
+
*
|
|
15
|
+
* A level is a content model of `wml.xsd` rather than an element name, because the same name means
|
|
16
|
+
* different things in different places: `sdt` is a control the paragraph reader unwraps, a cell
|
|
17
|
+
* wrapper under `tr`, a block placeholder under the body, and a row wrapper nothing reads. Keys are
|
|
18
|
+
* Clark names (`{namespace}localName`) so that `m:oMath` and `w:sdt` sit in one map.
|
|
19
|
+
*/
|
|
20
|
+
import type { PreservedDisplay } from "../schema";
|
|
21
|
+
export type { PreservedDisplay };
|
|
22
|
+
export type PreservationTier =
|
|
23
|
+
/** A reader turns it into an editable node */
|
|
24
|
+
"model"
|
|
25
|
+
/** A range marker: invisible, and its pair and order must survive every edit */
|
|
26
|
+
| "marker"
|
|
27
|
+
/** A trace the producer regenerates: invisible, and an edit may drop it */
|
|
28
|
+
| "ignorable"
|
|
29
|
+
/** A `CT_R` child: kept verbatim inside its run, wearing the run mark */
|
|
30
|
+
| "runContent"
|
|
31
|
+
/** A paragraph child: kept verbatim inside the paragraph */
|
|
32
|
+
| "inline"
|
|
33
|
+
/** A body or cell child: kept verbatim as a block placeholder */
|
|
34
|
+
| "block";
|
|
35
|
+
export interface PreservationRule {
|
|
36
|
+
readonly tier: Exclude<PreservationTier, "model">;
|
|
37
|
+
readonly display: PreservedDisplay;
|
|
38
|
+
/** The character a `text` display puts on screen */
|
|
39
|
+
readonly text?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the deletion guard answers for this element: a range marker whose pair must survive,
|
|
42
|
+
* and a field piece whose begin/separate/end order must survive.
|
|
43
|
+
*/
|
|
44
|
+
readonly guarded: boolean;
|
|
45
|
+
}
|
|
46
|
+
export type ElementPolicy = {
|
|
47
|
+
readonly tier: "model";
|
|
48
|
+
} | PreservationRule;
|
|
49
|
+
/** What a level with no node to hold a stranger answers: the container around it is demoted */
|
|
50
|
+
export type DemotionPolicy = {
|
|
51
|
+
readonly tier: "demote";
|
|
52
|
+
};
|
|
53
|
+
/** The levels a reader walks. Each is a content model of its own in `wml.xsd` */
|
|
54
|
+
export type ContentLevel = "body" | "tbl" | "tr" | "tc" | "p" | "wrapper" | "r";
|
|
55
|
+
export declare function clarkName(el: Element): string;
|
|
56
|
+
export declare const WML_POLICY: Readonly<Record<ContentLevel, ReadonlyMap<string, ElementPolicy>>>;
|
|
57
|
+
/** The levels that have a node of their own to keep a stranger in */
|
|
58
|
+
export type PreservingLevel = Exclude<ContentLevel, "tbl" | "tr">;
|
|
59
|
+
export declare function defaultPreservation(level: PreservingLevel): PreservationRule;
|
|
60
|
+
export declare function policyFor(el: Element, level: ContentLevel): ElementPolicy | DemotionPolicy;
|
|
61
|
+
/**
|
|
62
|
+
* The text one run child puts on screen, or null for a child that puts nothing there.
|
|
63
|
+
*
|
|
64
|
+
* This is where the table's answer becomes text, and a preserved fragment carries it along as the
|
|
65
|
+
* `text` a reader wrote onto it. Everything reading a story as plain text afterwards - a footnote
|
|
66
|
+
* body, a comment body, a header - asks `docx/story`'s `storyLeafText` for that same answer rather
|
|
67
|
+
* than keeping a vocabulary of its own, so the three of them cannot disagree about what a `w:cr`
|
|
68
|
+
* or a `w:noBreakHyphen` reads as.
|
|
69
|
+
*/
|
|
70
|
+
export declare function runContentText(el: Element): string | null;
|