@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/docx/comments/writing.ts
|
|
2
|
-
import {
|
|
2
|
+
import { attrsText } from "../../ooxml/element.js";
|
|
3
3
|
import { NAMESPACES, wName, xmlnsDecl } from "../../ooxml/names.js";
|
|
4
4
|
import {
|
|
5
5
|
ensureRootDeclarations,
|
|
@@ -7,10 +7,18 @@ import {
|
|
|
7
7
|
splicePart
|
|
8
8
|
} from "../../ooxml/partSplice.js";
|
|
9
9
|
import { encodeUtf8 } from "../../ooxml/xml.js";
|
|
10
|
+
import { sameSource } from "../../schema/sourceEquality.js";
|
|
11
|
+
import { NO_EXPORT_REFS } from "../exportRefs.js";
|
|
10
12
|
import { directoryOf } from "../relationships.js";
|
|
13
|
+
import { serializeStory } from "../serializeStory.js";
|
|
14
|
+
import {
|
|
15
|
+
storyFromText,
|
|
16
|
+
storyKey,
|
|
17
|
+
storyOf,
|
|
18
|
+
withThreadKeyOn
|
|
19
|
+
} from "../story.js";
|
|
11
20
|
import {
|
|
12
21
|
arrivedEntries,
|
|
13
|
-
renderCommentBody,
|
|
14
22
|
renderCommentExtension,
|
|
15
23
|
withThreadKey
|
|
16
24
|
} from "./grammar.js";
|
|
@@ -20,7 +28,26 @@ import {
|
|
|
20
28
|
import { commentsExtendedPart, commentsPart, peoplePart } from "./parts.js";
|
|
21
29
|
import { planPeoplePart } from "./people.js";
|
|
22
30
|
function needsThreadKey(id, comment, session) {
|
|
23
|
-
return
|
|
31
|
+
return session.comments.byId.has(id) && carriesThreadMetadata(comment) && (session.comments.byId.get(id)?.paraId ?? null) === null;
|
|
32
|
+
}
|
|
33
|
+
function bodyStory(doc, id) {
|
|
34
|
+
return storyOf(doc, storyKey("comment", id));
|
|
35
|
+
}
|
|
36
|
+
function importedBody(session, id) {
|
|
37
|
+
return session.stories.get(storyKey("comment", id)) ?? null;
|
|
38
|
+
}
|
|
39
|
+
function importedEntry(comment, session) {
|
|
40
|
+
const arrived = session.comments.byId.get(comment.id);
|
|
41
|
+
if (arrived === void 0 || arrived.author !== comment.author || arrived.date !== comment.date || arrived.initials !== comment.initials) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return importedBody(session, comment.id);
|
|
45
|
+
}
|
|
46
|
+
function bodyKept(doc, comment, session) {
|
|
47
|
+
const imported = importedEntry(comment, session);
|
|
48
|
+
if (imported === null) return null;
|
|
49
|
+
const current = bodyStory(doc, comment.id);
|
|
50
|
+
return current === null || sameSource(current, imported.doc) ? imported : null;
|
|
24
51
|
}
|
|
25
52
|
function commentsChanged(doc, session) {
|
|
26
53
|
const current = commentReferencesIn(doc);
|
|
@@ -34,12 +61,8 @@ function commentsChanged(doc, session) {
|
|
|
34
61
|
for (const id of originalBodies) {
|
|
35
62
|
if (!currentBodies.has(id)) return true;
|
|
36
63
|
}
|
|
37
|
-
for (const
|
|
38
|
-
|
|
39
|
-
if (!comment?.imported) return true;
|
|
40
|
-
}
|
|
41
|
-
for (const comment of current.values()) {
|
|
42
|
-
if (comment.replies.some((reply) => !reply.imported)) return true;
|
|
64
|
+
for (const comment of currentBodies.values()) {
|
|
65
|
+
if (bodyKept(doc, comment, session) === null) return true;
|
|
43
66
|
}
|
|
44
67
|
for (const [id, comment] of current) {
|
|
45
68
|
if (needsThreadKey(id, comment, session)) return true;
|
|
@@ -74,10 +97,13 @@ function extensionsXml(references, comments, originallyReferenced) {
|
|
|
74
97
|
if (comments.extendedXml === null) {
|
|
75
98
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w15:commentsEx ${xmlnsDecl("w15")}>${pieces.join("")}</w15:commentsEx>`;
|
|
76
99
|
}
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
100
|
+
return ensureRootDeclarations(
|
|
101
|
+
splicePart(comments.extendedXml, {
|
|
102
|
+
root: EXTENSIONS_ROOT,
|
|
103
|
+
replaceChildren: pieces.join("")
|
|
104
|
+
}),
|
|
105
|
+
{ namespaces: { w15: NAMESPACES.w15 } }
|
|
106
|
+
);
|
|
81
107
|
}
|
|
82
108
|
var COMMENTS_ROOT = "comments";
|
|
83
109
|
var EXTENSIONS_ROOT = "commentsEx";
|
|
@@ -108,31 +134,38 @@ function carriesThreadMetadata(comment) {
|
|
|
108
134
|
function keyedEntry(comment, arrivedKeyed) {
|
|
109
135
|
return carriesThreadMetadata(comment) || arrivedKeyed.has(comment.id);
|
|
110
136
|
}
|
|
111
|
-
function
|
|
112
|
-
if (comment.imported && comment.commentXml !== null) {
|
|
113
|
-
return carriesThreadMetadata(comment) ? withThreadKey(
|
|
114
|
-
comment.commentXml,
|
|
115
|
-
comment.paraId,
|
|
116
|
-
arrived.get(comment.id) ?? null
|
|
117
|
-
) : comment.commentXml;
|
|
118
|
-
}
|
|
137
|
+
function writtenContainer(comment) {
|
|
119
138
|
const attrs = [
|
|
120
|
-
xmlnsAttr("w"),
|
|
121
139
|
[wName("id"), comment.id],
|
|
122
140
|
comment.author === null ? null : [wName("author"), comment.author],
|
|
123
141
|
comment.date === null ? null : [wName("date"), comment.date],
|
|
124
142
|
comment.initials === null ? null : [wName("initials"), comment.initials]
|
|
125
143
|
];
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
return elementXml(
|
|
129
|
-
wName("comment"),
|
|
130
|
-
attrs.filter((attr) => attr !== null),
|
|
131
|
-
[body]
|
|
144
|
+
const text = attrsText(
|
|
145
|
+
attrs.filter((attr) => attr !== null)
|
|
132
146
|
);
|
|
147
|
+
return {
|
|
148
|
+
open: text === "" ? `<${wName("comment")}>` : `<${wName("comment")} ${text}>`,
|
|
149
|
+
close: `</${wName("comment")}>`
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function renderedComment(comment, arrivedKeyed, arrived, doc, session) {
|
|
153
|
+
const kept = bodyKept(doc, comment, session);
|
|
154
|
+
if (kept !== null) {
|
|
155
|
+
return carriesThreadMetadata(comment) ? withThreadKey(kept.xml, comment.paraId, arrived.get(comment.id) ?? null) : kept.xml;
|
|
156
|
+
}
|
|
157
|
+
const paraId = keyedEntry(comment, arrivedKeyed) ? comment.paraId : null;
|
|
158
|
+
const entry = importedEntry(comment, session);
|
|
159
|
+
const said = bodyStory(doc, comment.id) ?? storyFromText("");
|
|
160
|
+
const body = paraId === null ? said : withThreadKeyOn(said, paraId);
|
|
161
|
+
return serializeStory(body, null, entry ?? writtenContainer(comment), {
|
|
162
|
+
...NO_EXPORT_REFS,
|
|
163
|
+
session
|
|
164
|
+
});
|
|
133
165
|
}
|
|
166
|
+
var COMMENT_MARKUP = { namespaces: { w: NAMESPACES.w } };
|
|
134
167
|
var THREAD_MARKUP = {
|
|
135
|
-
namespaces: { w14: NAMESPACES.w14, mc: NAMESPACES.mc },
|
|
168
|
+
namespaces: { w: NAMESPACES.w, w14: NAMESPACES.w14, mc: NAMESPACES.mc },
|
|
136
169
|
ignorable: ["w14"]
|
|
137
170
|
};
|
|
138
171
|
function currentCommentBodies(references) {
|
|
@@ -157,7 +190,8 @@ function originalThreadIds(comments, rootIds) {
|
|
|
157
190
|
}
|
|
158
191
|
return ids;
|
|
159
192
|
}
|
|
160
|
-
function commentsXml(
|
|
193
|
+
function commentsXml(doc, session, references, originallyReferenced) {
|
|
194
|
+
const comments = session.comments;
|
|
161
195
|
const currentBodies = currentCommentBodies(references);
|
|
162
196
|
const arrivedKeyed = new Set(
|
|
163
197
|
Array.from(comments.byId.values()).flatMap(
|
|
@@ -172,20 +206,26 @@ function commentsXml(references, comments, originallyReferenced) {
|
|
|
172
206
|
const pieces = [];
|
|
173
207
|
const written = /* @__PURE__ */ new Set();
|
|
174
208
|
for (const original of comments.ordered) {
|
|
209
|
+
if (written.has(original.id)) continue;
|
|
175
210
|
const current = currentBodies.get(original.id);
|
|
176
211
|
if (current) {
|
|
177
|
-
pieces.push(
|
|
212
|
+
pieces.push(
|
|
213
|
+
renderedComment(current, arrivedKeyed, arrived, doc, session)
|
|
214
|
+
);
|
|
178
215
|
written.add(original.id);
|
|
179
216
|
continue;
|
|
180
217
|
}
|
|
181
218
|
if (!originalThreads.has(original.id)) {
|
|
182
|
-
|
|
219
|
+
const story = importedBody(session, original.id);
|
|
220
|
+
if (story !== null) pieces.push(story.xml);
|
|
183
221
|
written.add(original.id);
|
|
184
222
|
}
|
|
185
223
|
}
|
|
186
224
|
for (const [id, comment] of currentBodies) {
|
|
187
225
|
if (!written.has(id)) {
|
|
188
|
-
pieces.push(
|
|
226
|
+
pieces.push(
|
|
227
|
+
renderedComment(comment, arrivedKeyed, arrived, doc, session)
|
|
228
|
+
);
|
|
189
229
|
}
|
|
190
230
|
}
|
|
191
231
|
if (comments.xml === null) {
|
|
@@ -196,7 +236,10 @@ function commentsXml(references, comments, originallyReferenced) {
|
|
|
196
236
|
root: COMMENTS_ROOT,
|
|
197
237
|
replaceChildren: pieces.join("")
|
|
198
238
|
});
|
|
199
|
-
return
|
|
239
|
+
return ensureRootDeclarations(
|
|
240
|
+
rewritten,
|
|
241
|
+
hasThreadMetadata ? THREAD_MARKUP : COMMENT_MARKUP
|
|
242
|
+
);
|
|
200
243
|
}
|
|
201
244
|
function planCommentParts(doc, session, context) {
|
|
202
245
|
const bodyChanged = commentsChanged(doc, session);
|
|
@@ -215,7 +258,7 @@ function planCommentParts(doc, session, context) {
|
|
|
215
258
|
parts.set(
|
|
216
259
|
partPath,
|
|
217
260
|
encodeUtf8(
|
|
218
|
-
commentsXml(
|
|
261
|
+
commentsXml(doc, session, references, session.commentReferenceIds),
|
|
219
262
|
session.comments.hadBom
|
|
220
263
|
)
|
|
221
264
|
);
|
package/dist/docx/exportDocx.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
// src/docx/exportDocx.ts
|
|
2
2
|
import { DocxExportError } from "../ooxml/errors.js";
|
|
3
|
+
import {
|
|
4
|
+
ensureRootDeclarations
|
|
5
|
+
} from "../ooxml/partSplice.js";
|
|
3
6
|
import {
|
|
4
7
|
encodeUtf8,
|
|
5
8
|
parseXml,
|
|
9
|
+
R_NS,
|
|
6
10
|
W_NS,
|
|
7
11
|
withXmlParser
|
|
8
12
|
} from "../ooxml/xml.js";
|
|
9
|
-
import { sameSource } from "../schema/sourceEquality.js";
|
|
10
13
|
import { commentsPlanner } from "./comments.js";
|
|
11
14
|
import { repackParts } from "./container.js";
|
|
12
15
|
import {
|
|
13
16
|
fidelityNotesOf
|
|
14
17
|
} from "./fidelity.js";
|
|
18
|
+
import { headerFooterPlanner } from "./headersFooters.js";
|
|
15
19
|
import { hyperlinkRefs } from "./hyperlink.js";
|
|
16
20
|
import { withUniqueIdentities } from "./identities.js";
|
|
17
21
|
import { problemsOf } from "./invariants.js";
|
|
@@ -27,28 +31,22 @@ import {
|
|
|
27
31
|
relationshipWriter,
|
|
28
32
|
relsPathOf
|
|
29
33
|
} from "./relationships.js";
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
originalBlock,
|
|
33
|
-
sessionOf
|
|
34
|
-
} from "./session.js";
|
|
35
|
-
function blockXml(node, session, refs) {
|
|
36
|
-
const imported = originalBlock(node, session);
|
|
37
|
-
if (imported && sameSource(node, imported.node)) return imported.xml;
|
|
38
|
-
return serializeBlock(node, session, refs);
|
|
39
|
-
}
|
|
34
|
+
import { blockXml } from "./serializeBlock.js";
|
|
35
|
+
import { sessionOf } from "./session.js";
|
|
40
36
|
function buildDocumentXml(doc, session, refs) {
|
|
41
37
|
const pieces = [session.documentPrefix];
|
|
42
38
|
withUniqueIdentities(doc).forEach((child) => {
|
|
43
|
-
pieces.push(blockXml(child,
|
|
39
|
+
pieces.push(blockXml(child, refs, doc.childCount === 1));
|
|
44
40
|
});
|
|
41
|
+
const sectPr = doc.attrs.sectPr;
|
|
42
|
+
if (typeof sectPr === "string") pieces.push(sectPr);
|
|
45
43
|
pieces.push(session.documentSuffix);
|
|
46
44
|
return pieces.join("");
|
|
47
45
|
}
|
|
48
46
|
function localAttribute(el, name) {
|
|
49
47
|
return Array.from(el.attributes).find((attribute) => attribute.localName === name)?.value ?? null;
|
|
50
48
|
}
|
|
51
|
-
function
|
|
49
|
+
function assertMainPart(documentXml, wroteLinks) {
|
|
52
50
|
let root;
|
|
53
51
|
try {
|
|
54
52
|
root = parseXml(documentXml).documentElement;
|
|
@@ -63,6 +61,15 @@ function assertBookmarkPairs(documentXml) {
|
|
|
63
61
|
const used = /* @__PURE__ */ new Set();
|
|
64
62
|
for (const element of root.getElementsByTagName("*")) {
|
|
65
63
|
if (element.namespaceURI !== W_NS) continue;
|
|
64
|
+
if (wroteLinks && element.localName === "hyperlink") {
|
|
65
|
+
const id2 = element.getAttributeNode("r:id");
|
|
66
|
+
if (id2 && id2.namespaceURI !== R_NS) {
|
|
67
|
+
throw new DocxExportError(
|
|
68
|
+
"unsupported-content",
|
|
69
|
+
"a hyperlink's r:id is shadowed by a different relationship namespace"
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
66
73
|
if (element.localName !== "bookmarkStart" && element.localName !== "bookmarkEnd") {
|
|
67
74
|
continue;
|
|
68
75
|
}
|
|
@@ -97,9 +104,11 @@ function assertBookmarkPairs(documentXml) {
|
|
|
97
104
|
);
|
|
98
105
|
}
|
|
99
106
|
}
|
|
107
|
+
var LINK_MARKUP = { namespaces: { r: R_NS } };
|
|
100
108
|
var PART_PLANNERS = [
|
|
101
109
|
numberingPlanner,
|
|
102
|
-
commentsPlanner
|
|
110
|
+
commentsPlanner,
|
|
111
|
+
headerFooterPlanner
|
|
103
112
|
];
|
|
104
113
|
function exportDocx(doc, session, options) {
|
|
105
114
|
return exportDocxReport(doc, session, options).bytes;
|
|
@@ -135,12 +144,15 @@ function writeDocx(doc, store, notes, planners) {
|
|
|
135
144
|
contentTypes: contentTypeWriter(store.parts)
|
|
136
145
|
};
|
|
137
146
|
const media = planImageMedia(doc, store, context);
|
|
138
|
-
const
|
|
147
|
+
const links = hyperlinkRefs(context.relationships);
|
|
148
|
+
const body = buildDocumentXml(doc, store, {
|
|
139
149
|
images: media?.refs ?? NO_IMAGE_REFS,
|
|
140
|
-
links
|
|
141
|
-
notes
|
|
150
|
+
links,
|
|
151
|
+
notes,
|
|
152
|
+
session: store
|
|
142
153
|
});
|
|
143
|
-
|
|
154
|
+
const documentXml = links.addedRelId() ? ensureRootDeclarations(body, LINK_MARKUP) : body;
|
|
155
|
+
assertMainPart(documentXml, links.addedRelId());
|
|
144
156
|
const parts = runPartPlanners(planners, doc, store, context, media?.parts);
|
|
145
157
|
const rels = context.relationships.part(store.parts.get(relsPath));
|
|
146
158
|
if (rels) parts.set(relsPath, rels);
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What the serializers need from the rest of the package while a body is being written: which
|
|
3
3
|
* relationship an inserted image ended up on (`docx/media`), which one each link's address lives
|
|
4
|
-
* on (`docx/hyperlink`),
|
|
5
|
-
* (`docx/
|
|
4
|
+
* on (`docx/hyperlink`), where to record an approximation a writer had to make (`docx/fidelity`),
|
|
5
|
+
* and the fragments the document was opened from (`docx/session`).
|
|
6
6
|
*
|
|
7
7
|
* They travel as one value so that a serializer taking a body apart passes on everything the
|
|
8
|
-
* pieces of it may need, whatever a later kind of content turns out to require.
|
|
8
|
+
* pieces of it may need, whatever a later kind of content turns out to require. The session is
|
|
9
|
+
* among them because a preserved block names the fragment it stands for wherever it ends up: an
|
|
10
|
+
* edit may move one into a table cell, and the cell writer has no other way to reach the original.
|
|
9
11
|
*/
|
|
10
12
|
import { type FidelityCollector } from "./fidelity";
|
|
11
13
|
import { type LinkRefs } from "./hyperlink";
|
|
12
14
|
import { type ImageRefs } from "./media";
|
|
15
|
+
import type { SessionStore } from "./session";
|
|
13
16
|
export interface ExportRefs {
|
|
14
17
|
images: ImageRefs;
|
|
15
18
|
links: LinkRefs;
|
|
16
19
|
notes: FidelityCollector;
|
|
20
|
+
/** null for a serializer called on a document nobody opened */
|
|
21
|
+
session: SessionStore | null;
|
|
17
22
|
}
|
|
18
23
|
/** What a serializer called on its own, outside an export, has to work with */
|
|
19
24
|
export declare const NO_EXPORT_REFS: ExportRefs;
|
package/dist/docx/exportRefs.js
CHANGED
package/dist/docx/fidelity.js
CHANGED
|
@@ -13,31 +13,45 @@ function elementOf(node) {
|
|
|
13
13
|
return stringAttr(node.attrs.name) ?? elementNameOf(stringAttr(node.attrs.xml) ?? "");
|
|
14
14
|
}
|
|
15
15
|
function demotedBlock(element) {
|
|
16
|
-
const name =
|
|
16
|
+
const name = localNameOf(element);
|
|
17
17
|
if (name === "tbl") return { severity: "placeholder", code: "table-demoted" };
|
|
18
18
|
if (name === "p") {
|
|
19
19
|
return { severity: "placeholder", code: "paragraph-demoted" };
|
|
20
20
|
}
|
|
21
21
|
return { severity: "placeholder", code: "preserved-block" };
|
|
22
22
|
}
|
|
23
|
+
function severityOf(display) {
|
|
24
|
+
return display === "chip" ? "placeholder" : "hidden";
|
|
25
|
+
}
|
|
23
26
|
function preservedBy(node, element) {
|
|
24
27
|
switch (node.type.name) {
|
|
25
|
-
case "docxRaw":
|
|
26
|
-
return demotedBlock(element);
|
|
27
28
|
case "rawBlock":
|
|
28
|
-
return
|
|
29
|
-
case "
|
|
30
|
-
return {
|
|
29
|
+
return preservedBlockNote(node, element);
|
|
30
|
+
case "rawRunContent":
|
|
31
|
+
return {
|
|
32
|
+
severity: severityOf(node.attrs.display),
|
|
33
|
+
code: "preserved-run-content"
|
|
34
|
+
};
|
|
31
35
|
case "rawInline":
|
|
32
|
-
return preservedInline(element);
|
|
36
|
+
return preservedInline(node, element);
|
|
33
37
|
default:
|
|
34
38
|
return null;
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
41
|
+
function preservedBlockNote(node, element) {
|
|
42
|
+
if (severityOf(node.attrs.display) === "placeholder") {
|
|
43
|
+
return demotedBlock(element);
|
|
44
|
+
}
|
|
45
|
+
return node.attrs.guarded === true ? { severity: "hidden", code: "range-marker" } : { severity: "hidden", code: "preserved-block" };
|
|
46
|
+
}
|
|
47
|
+
function preservedInline(node, element) {
|
|
48
|
+
const name = stringAttr(node.attrs.element) ?? localNameOf(element);
|
|
39
49
|
if (name === "r") return null;
|
|
40
|
-
|
|
50
|
+
const severity = severityOf(node.attrs.display);
|
|
51
|
+
return severity === "hidden" && node.attrs.guarded === true ? { severity, code: "range-marker" } : { severity, code: "preserved-inline" };
|
|
52
|
+
}
|
|
53
|
+
function localNameOf(element) {
|
|
54
|
+
return element === null ? null : localPart(element);
|
|
41
55
|
}
|
|
42
56
|
function blockNumberOf(node) {
|
|
43
57
|
const srcId = stringAttr(node.attrs.srcId);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the fields of a paragraph stand, read back off the fragments the editor keeps as they came.
|
|
3
|
+
*
|
|
4
|
+
* A complex field is not one element. It is a begin character, the instruction text, an optional
|
|
5
|
+
* separate character, the result its producer cached, and an end character, all standing loose
|
|
6
|
+
* among the runs of the paragraph in that order (§17.16.18). Nothing in the model pairs them up, so
|
|
7
|
+
* anything that wants to know what a field was told to print has to read the characters back. A
|
|
8
|
+
* simple field says the same in one element and carries its instruction as an attribute (§17.16.19).
|
|
9
|
+
*
|
|
10
|
+
* What a field means, and how to work it out again, belongs to the fields feature. This answers the
|
|
11
|
+
* one question a projection has: where each field stands and what its instruction says.
|
|
12
|
+
*/
|
|
13
|
+
import type { Node as PMNode } from "prosemirror-model";
|
|
14
|
+
export interface FieldSpan {
|
|
15
|
+
/** The instruction text between begin and separate (or end), whitespace-trimmed */
|
|
16
|
+
instr: string;
|
|
17
|
+
/** Where the begin character stands, and the simple field itself for one written as a single element */
|
|
18
|
+
begin: number;
|
|
19
|
+
/** Where the separate character stands, and null for a field that cached no result */
|
|
20
|
+
separate: number | null;
|
|
21
|
+
/** Where the end character stands, which is `begin` again for a simple field */
|
|
22
|
+
end: number;
|
|
23
|
+
/** The half-open range of positions the cached result covers, and null for a field carrying none */
|
|
24
|
+
result: [number, number] | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether the node is one of the pieces a complex field is written out of rather than something
|
|
28
|
+
* the field prints. A projection drops these whether or not they pair up into a field.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isFieldCharacter(node: PMNode): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The fields this paragraph holds, in the order they begin, each position offset by `offset`.
|
|
33
|
+
*
|
|
34
|
+
* Positions are counted inside the paragraph's content, so `offset` is where that content starts:
|
|
35
|
+
* a caller reading a paragraph standing on its own passes 0, and one reading a paragraph of a
|
|
36
|
+
* document passes the position just inside it.
|
|
37
|
+
*
|
|
38
|
+
* A begin character with no end is no field: the file says a field starts there and never says
|
|
39
|
+
* what it prints, so there is nothing to pair it with and it is passed over. `documentFidelity`
|
|
40
|
+
* still reports the characters themselves as content kept rather than modelled.
|
|
41
|
+
*/
|
|
42
|
+
export declare function fieldSpans(paragraph: PMNode, offset: number): FieldSpan[];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// src/docx/fields.ts
|
|
2
|
+
import { parsePropsXml } from "../ooxml/props.js";
|
|
3
|
+
import { attributeByLocalName } from "../ooxml/xml.js";
|
|
4
|
+
var FIELD_CHARACTER = "fldChar";
|
|
5
|
+
var INSTRUCTION = "instrText";
|
|
6
|
+
var SIMPLE_FIELD = "fldSimple";
|
|
7
|
+
function attributeOf(node, name) {
|
|
8
|
+
const xml = node.attrs.xml;
|
|
9
|
+
if (typeof xml !== "string") return null;
|
|
10
|
+
const el = parsePropsXml(xml);
|
|
11
|
+
return el === null ? null : attributeByLocalName(el, name);
|
|
12
|
+
}
|
|
13
|
+
function chipText(node) {
|
|
14
|
+
const text = node.attrs.text;
|
|
15
|
+
return typeof text === "string" ? text : "";
|
|
16
|
+
}
|
|
17
|
+
var DELETED_INSTRUCTION = "delInstrText";
|
|
18
|
+
var FIELD_PLUMBING = /* @__PURE__ */ new Set([
|
|
19
|
+
FIELD_CHARACTER,
|
|
20
|
+
INSTRUCTION,
|
|
21
|
+
DELETED_INSTRUCTION
|
|
22
|
+
]);
|
|
23
|
+
function isFieldCharacter(node) {
|
|
24
|
+
const element = node.attrs.element;
|
|
25
|
+
return node.type.name === "rawRunContent" && typeof element === "string" && FIELD_PLUMBING.has(element);
|
|
26
|
+
}
|
|
27
|
+
function fieldSpans(paragraph, offset) {
|
|
28
|
+
const spans = [];
|
|
29
|
+
const open = [];
|
|
30
|
+
paragraph.forEach((child, at) => {
|
|
31
|
+
const pos = offset + at;
|
|
32
|
+
const element = child.attrs.element;
|
|
33
|
+
if (child.type.name === "rawInline" && element === SIMPLE_FIELD) {
|
|
34
|
+
spans.push({
|
|
35
|
+
instr: (attributeOf(child, "instr") ?? "").trim(),
|
|
36
|
+
begin: pos,
|
|
37
|
+
separate: null,
|
|
38
|
+
end: pos,
|
|
39
|
+
result: null
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (child.type.name !== "rawRunContent") return;
|
|
44
|
+
if (element === INSTRUCTION) {
|
|
45
|
+
const active2 = open.at(-1);
|
|
46
|
+
if (active2 && active2.separate === null) active2.instr += chipText(child);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (element !== FIELD_CHARACTER) return;
|
|
50
|
+
const kind = attributeOf(child, "fldCharType");
|
|
51
|
+
if (kind === "begin") {
|
|
52
|
+
open.push({ instr: "", begin: pos, separate: null });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const active = open.at(-1);
|
|
56
|
+
if (active === void 0) return;
|
|
57
|
+
if (kind === "separate") {
|
|
58
|
+
if (active.separate === null) active.separate = pos;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (kind !== "end") return;
|
|
62
|
+
open.pop();
|
|
63
|
+
spans.push({
|
|
64
|
+
instr: active.instr.trim(),
|
|
65
|
+
begin: active.begin,
|
|
66
|
+
separate: active.separate,
|
|
67
|
+
end: pos,
|
|
68
|
+
result: active.separate === null ? null : [active.separate + 1, pos]
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
return spans.sort((a, b) => a.begin - b.begin);
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
fieldSpans,
|
|
75
|
+
isFieldCharacter
|
|
76
|
+
};
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* and the clipboard reader all take them from here, so a paragraph is drawn the same whichever of
|
|
5
5
|
* them last touched it.
|
|
6
6
|
*/
|
|
7
|
-
import type
|
|
8
|
-
import type
|
|
7
|
+
import { type Mark, type Node as PMNode } from "prosemirror-model";
|
|
8
|
+
import { type ParagraphFormat, type RunFormat } from "../../model/format";
|
|
9
9
|
import type { FormattingContext } from "./context";
|
|
10
10
|
import { type ParagraphPlacement, type ResolvedParagraph } from "./resolve";
|
|
11
11
|
/** The two derived paragraph attrs (`format` and `styleRun` in `schema`) */
|
|
@@ -25,3 +25,21 @@ export declare function paragraphAttrsFor(pPr: string | null, context: Formattin
|
|
|
25
25
|
* An inline that is not text and carries no mark is left as it is.
|
|
26
26
|
*/
|
|
27
27
|
export declare function runMarkUnder(mark: Mark | null, isText: boolean, paragraph: ResolvedParagraph, context: FormattingContext): Mark | null;
|
|
28
|
+
/**
|
|
29
|
+
* The paragraph with the values the hierarchy gives it, and the text inside it wearing the run
|
|
30
|
+
* mark that goes with them.
|
|
31
|
+
*
|
|
32
|
+
* The style's run values are also laid on the paragraph itself, so that text carrying no run of
|
|
33
|
+
* its own - typed in the editor - is drawn in them (`styleRun` in `schema`).
|
|
34
|
+
* Where the paragraph stands in a table cell, `placement` is the part of the table it belongs to,
|
|
35
|
+
* which the table style dresses on top of everything else it lays down.
|
|
36
|
+
*/
|
|
37
|
+
export declare function styledParagraph(node: PMNode, context: FormattingContext, placement?: ParagraphPlacement | null): PMNode;
|
|
38
|
+
/** Table display inputs, refreshed from the same style context as the paragraphs inside it. */
|
|
39
|
+
export declare function tableStyleAttrs(tblPr: Element | null, context: FormattingContext): {
|
|
40
|
+
format: import("../..").TableFormat | null;
|
|
41
|
+
styleInside: import("../tableFormatting").InsideBorders | null;
|
|
42
|
+
styleCellMargins: import("../tableFormatting").CellMargins | null;
|
|
43
|
+
styleConditions: Readonly<Partial<Record<"band1Horz" | "band1Vert" | "band2Horz" | "band2Vert" | "firstCol" | "firstRow" | "lastCol" | "lastRow" | "neCell" | "nwCell" | "seCell" | "swCell" | "wholeTable", import("../tableFormatting").CellStyleFormat>>> | null;
|
|
44
|
+
styleBands: import("../tableFormatting").BandSizes | null;
|
|
45
|
+
};
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
// src/docx/formatting/attrs.ts
|
|
2
|
+
import { Fragment } from "prosemirror-model";
|
|
3
|
+
import {
|
|
4
|
+
toBandSizes,
|
|
5
|
+
toCellMargins,
|
|
6
|
+
toInsideBorders,
|
|
7
|
+
toTableStyleConditions
|
|
8
|
+
} from "../../model/format.js";
|
|
2
9
|
import { docxSchema } from "../../schema/index.js";
|
|
10
|
+
import {
|
|
11
|
+
cellConditionsOf,
|
|
12
|
+
layerBandSizes,
|
|
13
|
+
NO_BAND_SIZES,
|
|
14
|
+
readBandSizes,
|
|
15
|
+
readTableFormat,
|
|
16
|
+
tblStyleIdOf
|
|
17
|
+
} from "../tableFormatting.js";
|
|
3
18
|
import {
|
|
4
19
|
resolveParagraph,
|
|
5
|
-
resolveRun
|
|
20
|
+
resolveRun,
|
|
21
|
+
tableStyleFor
|
|
6
22
|
} from "./resolve.js";
|
|
23
|
+
import { layerTableFormat } from "./styles.js";
|
|
7
24
|
function paragraphAttrsOf(paragraph) {
|
|
8
25
|
return { format: paragraph.format, styleRun: paragraph.styleRun };
|
|
9
26
|
}
|
|
@@ -24,8 +41,46 @@ function runMarkUnder(mark, isText, paragraph, context) {
|
|
|
24
41
|
const format = resolveRun(null, paragraph, context);
|
|
25
42
|
return format === null ? null : docxSchema.marks.run.create({ rPr: null, rAttrs: null, format });
|
|
26
43
|
}
|
|
44
|
+
function styledParagraph(node, context, placement = null) {
|
|
45
|
+
const pPr = node.attrs.pPr;
|
|
46
|
+
const paragraph = resolveParagraph(
|
|
47
|
+
typeof pPr === "string" ? pPr : null,
|
|
48
|
+
context,
|
|
49
|
+
placement
|
|
50
|
+
);
|
|
51
|
+
const inline = node.children.map((child) => {
|
|
52
|
+
const mark = runMarkUnder(
|
|
53
|
+
child.marks.find((entry) => entry.type === docxSchema.marks.run) ?? null,
|
|
54
|
+
child.isText,
|
|
55
|
+
paragraph,
|
|
56
|
+
context
|
|
57
|
+
);
|
|
58
|
+
return mark ? child.mark(mark.addToSet(child.marks)) : child;
|
|
59
|
+
});
|
|
60
|
+
return node.type.create(
|
|
61
|
+
{ ...node.attrs, ...paragraphAttrsOf(paragraph) },
|
|
62
|
+
Fragment.fromArray(inline),
|
|
63
|
+
node.marks
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function tableStyleAttrs(tblPr, context) {
|
|
67
|
+
const style = tableStyleFor(tblStyleIdOf(tblPr), context);
|
|
68
|
+
return {
|
|
69
|
+
format: layerTableFormat(style?.table ?? {}, readTableFormat(tblPr)),
|
|
70
|
+
styleInside: toInsideBorders(style?.tableInside),
|
|
71
|
+
styleCellMargins: toCellMargins(style?.tableCellMargins),
|
|
72
|
+
styleConditions: toTableStyleConditions(
|
|
73
|
+
cellConditionsOf(style?.tableConditions ?? {})
|
|
74
|
+
),
|
|
75
|
+
styleBands: toBandSizes(
|
|
76
|
+
layerBandSizes(style?.tableBands ?? NO_BAND_SIZES, readBandSizes(tblPr))
|
|
77
|
+
)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
27
80
|
export {
|
|
28
81
|
paragraphAttrsFor,
|
|
29
82
|
paragraphAttrsOf,
|
|
30
|
-
runMarkUnder
|
|
83
|
+
runMarkUnder,
|
|
84
|
+
styledParagraph,
|
|
85
|
+
tableStyleAttrs
|
|
31
86
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RunFormat } from "../../model/format";
|
|
2
|
-
import { type Numbering } from "../../numbering/parseNumbering";
|
|
2
|
+
import { type Numbering, type NumberingOptions } from "../../numbering/parseNumbering";
|
|
3
3
|
import { type CompatSettings } from "../documentSettings";
|
|
4
4
|
import { type ThemeFonts } from "../theme";
|
|
5
5
|
import { type StyleTable } from "./styles";
|
|
@@ -27,5 +27,13 @@ export interface FormattingContext {
|
|
|
27
27
|
compat: CompatSettings;
|
|
28
28
|
}
|
|
29
29
|
export declare const NO_FORMATTING: FormattingContext;
|
|
30
|
+
/**
|
|
31
|
+
* How a document's numbering part is read against the rest of what the document lays down.
|
|
32
|
+
*
|
|
33
|
+
* The numbering folder cannot reach styles.xml, so the links a definition follows are handed to it
|
|
34
|
+
* from here, and the two callers that read a numbering part - opening a document and asking an
|
|
35
|
+
* open one for its lists - resolve the same links.
|
|
36
|
+
*/
|
|
37
|
+
export declare function numberingOptionsFor(styles: StyleTable, themeFonts: ThemeFonts): NumberingOptions;
|
|
30
38
|
/** The context an opened document resolves against. A document without a styles part lays down nothing */
|
|
31
|
-
export declare function formattingContextOf(styles: Document | null,
|
|
39
|
+
export declare function formattingContextOf(styles: Document | null, numberingXml: string | null, themeFonts: ThemeFonts, compat?: CompatSettings): FormattingContext;
|