@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
|
@@ -5,24 +5,25 @@ import {
|
|
|
5
5
|
ST_TwipsMeasure
|
|
6
6
|
} from "../ooxml/simpleTypes.js";
|
|
7
7
|
import { readTabStopDirectives } from "../ooxml/tabStops.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ALIGN_BY_JC,
|
|
10
|
+
childValue,
|
|
11
|
+
isOn,
|
|
12
|
+
twipsToPt,
|
|
13
|
+
wAttr
|
|
14
|
+
} from "../ooxml/units.js";
|
|
9
15
|
import {
|
|
10
16
|
childByLocalName,
|
|
11
17
|
elementChildren,
|
|
12
18
|
parseXml,
|
|
13
19
|
withXmlParser
|
|
14
20
|
} from "../ooxml/xml.js";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
];
|
|
22
|
-
var EMPTY_NUMBERING = { lists: /* @__PURE__ */ new Map() };
|
|
23
|
-
function isNumberFormat(value) {
|
|
24
|
-
return NUMBER_FORMATS.some((format) => format === value);
|
|
25
|
-
}
|
|
21
|
+
import { isNumberFormat } from "./spellers.js";
|
|
22
|
+
var NO_ADDED_LISTS = /* @__PURE__ */ new Map();
|
|
23
|
+
var EMPTY_NUMBERING = {
|
|
24
|
+
lists: /* @__PURE__ */ new Map(),
|
|
25
|
+
added: NO_ADDED_LISTS
|
|
26
|
+
};
|
|
26
27
|
function indentOf(lvl) {
|
|
27
28
|
const pPr = childByLocalName(lvl, "pPr");
|
|
28
29
|
const ind = pPr ? childByLocalName(pPr, "ind") : null;
|
|
@@ -56,28 +57,53 @@ function levelIndentPt(indent) {
|
|
|
56
57
|
textIndentPt: hangingPt !== null ? -hangingPt : twipsToPt(indent.firstLineTwips)
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
var LEVEL_SUFFIXES = [
|
|
61
|
+
"tab",
|
|
62
|
+
"space",
|
|
63
|
+
"nothing"
|
|
64
|
+
];
|
|
65
|
+
var LEVEL_ALIGNS = ["left", "center", "right"];
|
|
66
|
+
function suffixOf(lvl) {
|
|
67
|
+
const suffix = childValue(lvl, "suff");
|
|
68
|
+
return LEVEL_SUFFIXES.find((known) => known === suffix) ?? "tab";
|
|
69
|
+
}
|
|
70
|
+
function alignOf(lvl) {
|
|
71
|
+
const jc = childValue(lvl, "lvlJc");
|
|
72
|
+
const align = jc === null ? void 0 : ALIGN_BY_JC[jc];
|
|
73
|
+
return align === void 0 || align === "justify" ? "left" : align;
|
|
74
|
+
}
|
|
75
|
+
function restartAfterLevelOf(lvl) {
|
|
76
|
+
const restart = ST_DecimalNumber.parse(childValue(lvl, "lvlRestart"));
|
|
77
|
+
return restart === null ? null : restart - 1;
|
|
78
|
+
}
|
|
79
|
+
function readLevel(lvl, readRun) {
|
|
60
80
|
const format = childValue(lvl, "numFmt");
|
|
61
81
|
const pPr = childByLocalName(lvl, "pPr");
|
|
62
82
|
const tabStops = readTabStopDirectives(pPr);
|
|
83
|
+
const rPr = childByLocalName(lvl, "rPr");
|
|
63
84
|
return {
|
|
64
85
|
format: isNumberFormat(format) ? format : "decimal",
|
|
65
86
|
text: childValue(lvl, "lvlText") ?? "",
|
|
66
87
|
start: ST_DecimalNumber.parse(childValue(lvl, "start")) ?? 1,
|
|
67
88
|
indent: indentOf(lvl),
|
|
68
|
-
...tabStops.length === 0 ? {} : { tabStops }
|
|
89
|
+
...tabStops.length === 0 ? {} : { tabStops },
|
|
90
|
+
restartAfterLevel: restartAfterLevelOf(lvl),
|
|
91
|
+
legal: isOn(lvl, "isLgl"),
|
|
92
|
+
suffix: suffixOf(lvl),
|
|
93
|
+
align: alignOf(lvl),
|
|
94
|
+
run: rPr && readRun ? readRun(rPr) : null
|
|
69
95
|
};
|
|
70
96
|
}
|
|
71
|
-
function readLevels(parent) {
|
|
97
|
+
function readLevels(parent, readRun) {
|
|
72
98
|
const levels = /* @__PURE__ */ new Map();
|
|
73
99
|
for (const child of elementChildren(parent)) {
|
|
74
100
|
if (child.localName !== "lvl") continue;
|
|
75
101
|
const ilvl = ST_DecimalNumber.parse(wAttr(child, "ilvl"));
|
|
76
|
-
if (ilvl !== null) levels.set(ilvl, readLevel(child));
|
|
102
|
+
if (ilvl !== null) levels.set(ilvl, readLevel(child, readRun));
|
|
77
103
|
}
|
|
78
104
|
return levels;
|
|
79
105
|
}
|
|
80
|
-
function readList(num, abstractLevels) {
|
|
106
|
+
function readList(num, abstractLevels, readRun) {
|
|
81
107
|
const abstractNumId = ST_DecimalNumber.parse(
|
|
82
108
|
childValue(num, "abstractNumId")
|
|
83
109
|
);
|
|
@@ -88,7 +114,7 @@ function readList(num, abstractLevels) {
|
|
|
88
114
|
const ilvl = ST_DecimalNumber.parse(wAttr(child, "ilvl"));
|
|
89
115
|
if (ilvl === null) continue;
|
|
90
116
|
const replacement = childByLocalName(child, "lvl");
|
|
91
|
-
const base = replacement ? readLevel(replacement) : levels.get(ilvl);
|
|
117
|
+
const base = replacement ? readLevel(replacement, readRun) : levels.get(ilvl);
|
|
92
118
|
if (!base) continue;
|
|
93
119
|
const startOverride = ST_DecimalNumber.parse(
|
|
94
120
|
childValue(child, "startOverride")
|
|
@@ -100,29 +126,77 @@ function readList(num, abstractLevels) {
|
|
|
100
126
|
}
|
|
101
127
|
return { levels };
|
|
102
128
|
}
|
|
129
|
+
var NO_STYLE_LINKS = /* @__PURE__ */ new Map();
|
|
130
|
+
function levelsOf(id, definitions, resolved) {
|
|
131
|
+
const path = /* @__PURE__ */ new Set();
|
|
132
|
+
let current = id;
|
|
133
|
+
let levels = /* @__PURE__ */ new Map();
|
|
134
|
+
while (!path.has(current)) {
|
|
135
|
+
const known = resolved.get(current);
|
|
136
|
+
if (known) {
|
|
137
|
+
levels = known;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
path.add(current);
|
|
141
|
+
const el = definitions.byId.get(current);
|
|
142
|
+
if (!el) break;
|
|
143
|
+
levels = readLevels(el, definitions.readRun);
|
|
144
|
+
const styleId = childValue(el, "numStyleLink");
|
|
145
|
+
if (levels.size > 0 || styleId === null) break;
|
|
146
|
+
const named = definitions.links.get(styleId);
|
|
147
|
+
const deferred = (named === void 0 ? void 0 : definitions.ofList.get(named)) ?? definitions.ofStyle.get(styleId);
|
|
148
|
+
if (deferred === void 0) break;
|
|
149
|
+
current = deferred;
|
|
150
|
+
}
|
|
151
|
+
for (const seen of path) resolved.set(seen, levels);
|
|
152
|
+
return levels;
|
|
153
|
+
}
|
|
103
154
|
function parseNumbering(xml, options) {
|
|
104
155
|
if (xml === null) return EMPTY_NUMBERING;
|
|
105
|
-
return withXmlParser(options?.xmlParser, () => readNumbering(xml));
|
|
156
|
+
return withXmlParser(options?.xmlParser, () => readNumbering(xml, options));
|
|
106
157
|
}
|
|
107
|
-
function readNumbering(xml) {
|
|
158
|
+
function readNumbering(xml, options) {
|
|
108
159
|
const root = parseXml(xml).documentElement;
|
|
109
|
-
const
|
|
160
|
+
const byId = /* @__PURE__ */ new Map();
|
|
161
|
+
const ofStyle = /* @__PURE__ */ new Map();
|
|
162
|
+
const ofList = /* @__PURE__ */ new Map();
|
|
110
163
|
for (const child of elementChildren(root)) {
|
|
111
|
-
if (child.localName
|
|
112
|
-
|
|
113
|
-
|
|
164
|
+
if (child.localName === "abstractNum") {
|
|
165
|
+
const id = ST_DecimalNumber.parse(wAttr(child, "abstractNumId"));
|
|
166
|
+
if (id === null) continue;
|
|
167
|
+
byId.set(id, child);
|
|
168
|
+
const styleId = childValue(child, "styleLink");
|
|
169
|
+
if (styleId !== null) ofStyle.set(styleId, id);
|
|
170
|
+
} else if (child.localName === "num") {
|
|
171
|
+
const numId = ST_DecimalNumber.parse(wAttr(child, "numId"));
|
|
172
|
+
const id = ST_DecimalNumber.parse(childValue(child, "abstractNumId"));
|
|
173
|
+
if (numId !== null && id !== null) ofList.set(numId, id);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const definitions = {
|
|
177
|
+
byId,
|
|
178
|
+
ofList,
|
|
179
|
+
ofStyle,
|
|
180
|
+
links: options?.links ?? NO_STYLE_LINKS,
|
|
181
|
+
readRun: options?.readRun
|
|
182
|
+
};
|
|
183
|
+
const abstractLevels = /* @__PURE__ */ new Map();
|
|
184
|
+
for (const id of byId.keys()) {
|
|
185
|
+
abstractLevels.set(id, levelsOf(id, definitions, abstractLevels));
|
|
114
186
|
}
|
|
115
187
|
const lists = /* @__PURE__ */ new Map();
|
|
116
188
|
for (const child of elementChildren(root)) {
|
|
117
189
|
if (child.localName !== "num") continue;
|
|
118
190
|
const numId = ST_DecimalNumber.parse(wAttr(child, "numId"));
|
|
119
|
-
const list = numId === null ? null : readList(child, abstractLevels);
|
|
191
|
+
const list = numId === null ? null : readList(child, abstractLevels, options?.readRun);
|
|
120
192
|
if (numId !== null && list) lists.set(numId, list);
|
|
121
193
|
}
|
|
122
|
-
return { lists };
|
|
194
|
+
return { lists, added: NO_ADDED_LISTS };
|
|
123
195
|
}
|
|
124
196
|
export {
|
|
125
197
|
EMPTY_NUMBERING,
|
|
198
|
+
LEVEL_ALIGNS,
|
|
199
|
+
LEVEL_SUFFIXES,
|
|
126
200
|
NO_LEVEL_INDENT,
|
|
127
201
|
levelIndentPt,
|
|
128
202
|
parseNumbering
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How each number format spells the count of a list item.
|
|
3
|
+
*
|
|
4
|
+
* `w:numFmt` names some sixty formats (§17.18.59). The ones here are the ones a marker is drawn
|
|
5
|
+
* in; a level naming any other counts in decimal instead. A format belongs to `NumberFormat`
|
|
6
|
+
* because it has a speller here, so a marker can never be counted in a format nothing can write.
|
|
7
|
+
*/
|
|
8
|
+
/** A `w:numFmt` this editor spells out. Every other one is drawn as a decimal */
|
|
9
|
+
export type NumberFormat = "decimal" | "decimalZero" | "bullet" | "lowerLetter" | "upperLetter" | "lowerRoman" | "upperRoman" | "ganada" | "koreanDigital" | "chineseCounting";
|
|
10
|
+
export declare function isNumberFormat(value: string | null): value is NumberFormat;
|
|
11
|
+
/**
|
|
12
|
+
* The count as this format writes it, and as a decimal where spelling it out would run past the
|
|
13
|
+
* length a marker is ever drawn at.
|
|
14
|
+
*/
|
|
15
|
+
export declare function spellNumber(count: number, format: NumberFormat, maxChars: number): string;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// src/numbering/spellers.ts
|
|
2
|
+
var ROMAN = [
|
|
3
|
+
[1e3, "M"],
|
|
4
|
+
[900, "CM"],
|
|
5
|
+
[500, "D"],
|
|
6
|
+
[400, "CD"],
|
|
7
|
+
[100, "C"],
|
|
8
|
+
[90, "XC"],
|
|
9
|
+
[50, "L"],
|
|
10
|
+
[40, "XL"],
|
|
11
|
+
[10, "X"],
|
|
12
|
+
[9, "IX"],
|
|
13
|
+
[5, "V"],
|
|
14
|
+
[4, "IV"],
|
|
15
|
+
[1, "I"]
|
|
16
|
+
];
|
|
17
|
+
function toRoman(count) {
|
|
18
|
+
let rest = count;
|
|
19
|
+
let out = "";
|
|
20
|
+
for (const [amount, sign] of ROMAN) {
|
|
21
|
+
while (rest >= amount) {
|
|
22
|
+
out += sign;
|
|
23
|
+
rest -= amount;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
function repeated(symbols, count) {
|
|
29
|
+
const index = (count - 1) % symbols.length;
|
|
30
|
+
const times = Math.floor((count - 1) / symbols.length) + 1;
|
|
31
|
+
return (symbols[index] ?? "").repeat(times);
|
|
32
|
+
}
|
|
33
|
+
var LATIN = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
34
|
+
var GANADA = "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC\uC544\uC790\uCC28\uCE74\uD0C0\uD30C\uD558";
|
|
35
|
+
var KOREAN_DIGITS = "\uC601\uC77C\uC774\uC0BC\uC0AC\uC624\uC721\uCE60\uD314\uAD6C";
|
|
36
|
+
function digits(symbols, count) {
|
|
37
|
+
return Array.from(`${count}`, (digit) => symbols[Number(digit)] ?? "").join(
|
|
38
|
+
""
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
var CHINESE_DIGITS = "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341";
|
|
42
|
+
function chineseCounting(count) {
|
|
43
|
+
if (count <= 10) return CHINESE_DIGITS[count] ?? "";
|
|
44
|
+
if (count >= 100) return digits(CHINESE_DIGITS, count);
|
|
45
|
+
const tens = Math.floor(count / 10);
|
|
46
|
+
const unit = count % 10;
|
|
47
|
+
return (tens === 1 ? "" : CHINESE_DIGITS[tens] ?? "") + CHINESE_DIGITS[10] + (unit === 0 ? "" : CHINESE_DIGITS[unit] ?? "");
|
|
48
|
+
}
|
|
49
|
+
var POSITIONAL = Number.POSITIVE_INFINITY;
|
|
50
|
+
var NUMBER_SPELLERS = {
|
|
51
|
+
decimal: { spell: (count) => `${count}`, countsPerChar: POSITIONAL },
|
|
52
|
+
/** The counts up to nine written with a zero in front (§17.18.59 decimalZero) */
|
|
53
|
+
decimalZero: {
|
|
54
|
+
spell: (count) => count < 10 ? `0${count}` : `${count}`,
|
|
55
|
+
countsPerChar: POSITIONAL
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* A bullet counts nothing: its `w:lvlText` is the symbol itself. A `%n` slot naming a bullet
|
|
59
|
+
* level has no symbol to put there, so the count goes in as a decimal, as Word draws it.
|
|
60
|
+
*/
|
|
61
|
+
bullet: { spell: (count) => `${count}`, countsPerChar: POSITIONAL },
|
|
62
|
+
lowerLetter: {
|
|
63
|
+
spell: (count) => repeated(LATIN, count).toLowerCase(),
|
|
64
|
+
countsPerChar: LATIN.length
|
|
65
|
+
},
|
|
66
|
+
upperLetter: {
|
|
67
|
+
spell: (count) => repeated(LATIN, count),
|
|
68
|
+
countsPerChar: LATIN.length
|
|
69
|
+
},
|
|
70
|
+
lowerRoman: {
|
|
71
|
+
spell: (count) => toRoman(count).toLowerCase(),
|
|
72
|
+
countsPerChar: 1e3
|
|
73
|
+
},
|
|
74
|
+
upperRoman: { spell: toRoman, countsPerChar: 1e3 },
|
|
75
|
+
ganada: {
|
|
76
|
+
spell: (count) => repeated(GANADA, count),
|
|
77
|
+
countsPerChar: GANADA.length
|
|
78
|
+
},
|
|
79
|
+
koreanDigital: {
|
|
80
|
+
spell: (count) => digits(KOREAN_DIGITS, count),
|
|
81
|
+
countsPerChar: POSITIONAL
|
|
82
|
+
},
|
|
83
|
+
chineseCounting: { spell: chineseCounting, countsPerChar: POSITIONAL }
|
|
84
|
+
};
|
|
85
|
+
function isNumberFormat(value) {
|
|
86
|
+
return value !== null && Object.hasOwn(NUMBER_SPELLERS, value);
|
|
87
|
+
}
|
|
88
|
+
function spellNumber(count, format, maxChars) {
|
|
89
|
+
const speller = NUMBER_SPELLERS[format];
|
|
90
|
+
if (count < 1 || count > speller.countsPerChar * maxChars) return `${count}`;
|
|
91
|
+
return speller.spell(count);
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
isNumberFormat,
|
|
95
|
+
spellNumber
|
|
96
|
+
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Splices the definitions
|
|
2
|
+
* Splices the definitions the newly started lists were registered with into the original
|
|
3
|
+
* numbering.xml.
|
|
3
4
|
*
|
|
4
5
|
* Not one character of the original is altered; new elements are merely slotted in.
|
|
5
6
|
* OOXML requires the definitions (`abstractNum`) to come before the numbers (`num`), and
|
|
6
7
|
* `CHILD_ORDER.numbering` is what places each where it belongs among what the part holds.
|
|
7
8
|
*/
|
|
9
|
+
import type { NewList } from "./parseNumbering";
|
|
8
10
|
/**
|
|
9
|
-
* numbering.xml with
|
|
11
|
+
* numbering.xml with the definition each of these lists was started with added under its number.
|
|
10
12
|
* When there is nothing to add, the original string is returned unchanged.
|
|
11
13
|
*/
|
|
12
|
-
export declare function addListDefinitions(xml: string,
|
|
14
|
+
export declare function addListDefinitions(xml: string, lists: ReadonlyMap<number, NewList>): string;
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
// src/numbering/writeNumbering.ts
|
|
2
2
|
import { splicePart } from "../ooxml/partSplice.js";
|
|
3
|
+
import { ST_DecimalNumber } from "../ooxml/simpleTypes.js";
|
|
3
4
|
import { wAttr } from "../ooxml/units.js";
|
|
4
5
|
import { elementChildren, parseXml } from "../ooxml/xml.js";
|
|
5
|
-
import { abstractNumXml,
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
return max;
|
|
6
|
+
import { abstractNumXml, numberingIdAllocator, numXml } from "./listTemplate.js";
|
|
7
|
+
function abstractNumIds(xml) {
|
|
8
|
+
return elementChildren(parseXml(xml).documentElement).flatMap((child) => {
|
|
9
|
+
if (child.localName !== "abstractNum") return [];
|
|
10
|
+
const id = ST_DecimalNumber.parse(wAttr(child, "abstractNumId"));
|
|
11
|
+
return id === null ? [] : [id];
|
|
12
|
+
});
|
|
14
13
|
}
|
|
15
|
-
function addListDefinitions(xml,
|
|
16
|
-
if (
|
|
17
|
-
const
|
|
18
|
-
const additions = [...
|
|
14
|
+
function addListDefinitions(xml, lists) {
|
|
15
|
+
if (lists.size === 0) return xml;
|
|
16
|
+
const takeId = numberingIdAllocator(abstractNumIds(xml));
|
|
17
|
+
const additions = [...lists].sort(([left], [right]) => left - right).map(([numId, list]) => ({
|
|
19
18
|
numId,
|
|
20
|
-
|
|
19
|
+
list,
|
|
20
|
+
abstractNumId: takeId()
|
|
21
21
|
}));
|
|
22
22
|
return splicePart(xml, {
|
|
23
23
|
root: "numbering",
|
|
24
24
|
insert: [
|
|
25
25
|
...additions.map((added) => ({
|
|
26
26
|
name: "abstractNum",
|
|
27
|
-
xml: abstractNumXml(added.abstractNumId,
|
|
27
|
+
xml: abstractNumXml(added.abstractNumId, added.list)
|
|
28
28
|
})),
|
|
29
29
|
...additions.map((added) => ({
|
|
30
30
|
name: "num",
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which conformance class a package is written in, and whether its main part is one this editor
|
|
3
|
+
* can write back into. Both are settled once, when the file is opened.
|
|
4
|
+
*
|
|
5
|
+
* ECMA-376 defines two document conformance classes, Strict (Part 1 §2.1) and Transitional
|
|
6
|
+
* (Part 4 §2.1). They describe the same vocabulary under different names: the main document part's
|
|
7
|
+
* root namespace and the relationship the package reaches it through differ between the two
|
|
8
|
+
* (Part 1 §11.3.10, Part 4 §9.2.10). This editor supports a subset of Transitional. Strict is
|
|
9
|
+
* refused explicitly so that its markup is never read using Transitional assumptions.
|
|
10
|
+
*
|
|
11
|
+
* A namespace prefix is the producer's own choice and carries no meaning of its own, so readers
|
|
12
|
+
* identify markup by namespace URI and local name. The WordprocessingML writer emits `w`
|
|
13
|
+
* (`ooxml/names`), so the main part's root must bind that prefix to the Transitional namespace.
|
|
14
|
+
*/
|
|
15
|
+
/** The WordprocessingML namespace of a Strict main document part (Part 1 §11.3.10) */
|
|
16
|
+
export declare const STRICT_W_NS = "http://purl.oclc.org/ooxml/wordprocessingml/main";
|
|
17
|
+
/** The relationship a Strict package reaches its main document part through (Part 1 §11.3.10) */
|
|
18
|
+
export declare const STRICT_OFFICE_DOCUMENT_REL = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument";
|
|
19
|
+
export type Conformance = "transitional" | "strict";
|
|
20
|
+
/** The class this main part root is written in, null for a root of neither vocabulary */
|
|
21
|
+
export declare function conformanceOf(root: Element): Conformance | null;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the root binds the prefix every writer emits (`w`) to the WordprocessingML namespace.
|
|
24
|
+
*
|
|
25
|
+
* A root has nothing above it to inherit a declaration from, so what it writes itself is the whole
|
|
26
|
+
* answer. A default namespace or another prefix alone does not bind `w`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function bindsWritingPrefix(root: Element): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/ooxml/conformance.ts
|
|
2
|
+
import { W_NS, W_PREFIX } from "./names.js";
|
|
3
|
+
var STRICT_W_NS = "http://purl.oclc.org/ooxml/wordprocessingml/main";
|
|
4
|
+
var STRICT_OFFICE_DOCUMENT_REL = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument";
|
|
5
|
+
function conformanceOf(root) {
|
|
6
|
+
if (root.namespaceURI === W_NS) return "transitional";
|
|
7
|
+
if (root.namespaceURI === STRICT_W_NS) return "strict";
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
function bindsWritingPrefix(root) {
|
|
11
|
+
return Array.from(root.attributes).some(
|
|
12
|
+
(attr) => attr.name === `xmlns:${W_PREFIX}` && attr.value === W_NS
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
STRICT_OFFICE_DOCUMENT_REL,
|
|
17
|
+
STRICT_W_NS,
|
|
18
|
+
bindsWritingPrefix,
|
|
19
|
+
conformanceOf
|
|
20
|
+
};
|
package/dist/ooxml/errors.d.ts
CHANGED
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
* - `missing-part`: the package has no main document part to read
|
|
15
15
|
* - `missing-body`: the main part carries no `w:body`
|
|
16
16
|
* - `malformed-xml`: the XML cannot be parsed, declares a DTD, or its markup is inconsistent
|
|
17
|
+
* - `unsupported-conformance`: the package is an ECMA-376 Strict one, and this editor reads Transitional
|
|
17
18
|
* - `unsupported-content`: the document holds markup we cannot write back out unchanged
|
|
18
19
|
*/
|
|
19
|
-
export type DocxImportErrorCode = "no-xml-parser" | "not-a-docx" | "too-large" | "missing-part" | "missing-body" | "malformed-xml" | "unsupported-content";
|
|
20
|
+
export type DocxImportErrorCode = "no-xml-parser" | "not-a-docx" | "too-large" | "missing-part" | "missing-body" | "malformed-xml" | "unsupported-conformance" | "unsupported-content";
|
|
20
21
|
/** Thrown when we hit a document whose content cannot be kept safely. We refuse to open it instead of losing it silently */
|
|
21
22
|
export declare class DocxImportError extends Error {
|
|
22
23
|
readonly code: DocxImportErrorCode;
|
|
@@ -25,14 +26,13 @@ export declare class DocxImportError extends Error {
|
|
|
25
26
|
/**
|
|
26
27
|
* Why a document could not be written back out.
|
|
27
28
|
*
|
|
28
|
-
* - `missing-
|
|
29
|
-
* - `
|
|
30
|
-
* - `unsupported-content`: the document holds a node kind we have no way to serialize, or a preserved block standing in two places, which has one original XML to write
|
|
29
|
+
* - `missing-content-types`: a part the writer adds, be it an image, a list definition or a comment, needs a [Content_Types].xml the package does not have
|
|
30
|
+
* - `unsupported-content`: the document holds something no correct file can be written from: a node kind we have no way to serialize, a preserved block standing in two places, which has one original XML to write, or a paragraph in a list nothing defines
|
|
31
31
|
* - `lost-original`: a node that only carries its original XML has lost it
|
|
32
32
|
* - `malformed-xml`: an original XML fragment cannot be read well enough to rewrite
|
|
33
33
|
* - `invalid-table`: the table grid is inconsistent, e.g. a vertical merge outliving its rows
|
|
34
34
|
*/
|
|
35
|
-
export type DocxExportErrorCode = "missing-
|
|
35
|
+
export type DocxExportErrorCode = "missing-content-types" | "unsupported-content" | "lost-original" | "malformed-xml" | "invalid-table";
|
|
36
36
|
/** Thrown when an edited document cannot be written back out without losing or corrupting content */
|
|
37
37
|
export declare class DocxExportError extends Error {
|
|
38
38
|
readonly code: DocxExportErrorCode;
|
package/dist/ooxml/fragment.d.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* What a raw XML string has to look like to be let into the attr that carries it.
|
|
17
17
|
*
|
|
18
18
|
* `element` is a whole element: a properties fragment, a drawing, an annotation reference.
|
|
19
|
+
* `elements` is a run of them standing side by side, as a table carries between its rows.
|
|
19
20
|
* `attributes` is what stood inside an opening tag, as `attrString` writes it.
|
|
20
21
|
* `openTag` is an opening tag with everything it wrapped cut away, which the writer puts back by
|
|
21
22
|
* appending the closing text `closedBy` names. `head` is what may still stand between the two:
|
|
@@ -24,6 +25,8 @@
|
|
|
24
25
|
export type RawXmlShape = {
|
|
25
26
|
kind: "element";
|
|
26
27
|
names: readonly string[] | "any";
|
|
28
|
+
} | {
|
|
29
|
+
kind: "elements";
|
|
27
30
|
} | {
|
|
28
31
|
kind: "attributes";
|
|
29
32
|
} | {
|
|
@@ -42,6 +45,14 @@ export declare function ELEMENT(...names: string[]): RawXmlShape;
|
|
|
42
45
|
* turn a document the editor reads today into a demoted one.
|
|
43
46
|
*/
|
|
44
47
|
export declare const ANY_ELEMENT: RawXmlShape;
|
|
48
|
+
/**
|
|
49
|
+
* A run of one or more elements standing side by side, of any name, in any namespace.
|
|
50
|
+
*
|
|
51
|
+
* A table carries the markers that stood between its rows, and a row those between its cells
|
|
52
|
+
* (`docx/importTable`), and there may be several of them in a row: the end of one bookmark and the
|
|
53
|
+
* start of the next stand together with nothing between them.
|
|
54
|
+
*/
|
|
55
|
+
export declare const ANY_ELEMENTS: RawXmlShape;
|
|
45
56
|
/** The attributes of an opening tag, with neither the tag nor anything it held */
|
|
46
57
|
export declare const ATTRIBUTES: RawXmlShape;
|
|
47
58
|
/**
|
package/dist/ooxml/fragment.js
CHANGED
|
@@ -10,17 +10,22 @@ function ELEMENT(...names) {
|
|
|
10
10
|
return { kind: "element", names };
|
|
11
11
|
}
|
|
12
12
|
var ANY_ELEMENT = { kind: "element", names: "any" };
|
|
13
|
+
var ANY_ELEMENTS = { kind: "elements" };
|
|
13
14
|
var ATTRIBUTES = { kind: "attributes" };
|
|
14
|
-
function
|
|
15
|
+
function wrappedElements(xml) {
|
|
15
16
|
let root;
|
|
16
17
|
try {
|
|
17
18
|
root = parseXml(`<x ${namespaceDecls(xml)}>${xml}</x>`).documentElement;
|
|
18
19
|
} catch {
|
|
19
20
|
return null;
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return
|
|
22
|
+
const elements = elementChildren(root);
|
|
23
|
+
if (root.childNodes.length !== elements.length) return null;
|
|
24
|
+
return elements.some(rebindsReservedPrefix) ? null : elements;
|
|
25
|
+
}
|
|
26
|
+
function loneElement(xml) {
|
|
27
|
+
const elements = wrappedElements(xml);
|
|
28
|
+
return elements?.length === 1 ? elements[0] : null;
|
|
24
29
|
}
|
|
25
30
|
function isNamed(el, names) {
|
|
26
31
|
if (!names.includes(el.localName)) return false;
|
|
@@ -54,6 +59,10 @@ function holdsShape(shape, value) {
|
|
|
54
59
|
if (el === null) return false;
|
|
55
60
|
return shape.names === "any" || isNamed(el, shape.names);
|
|
56
61
|
}
|
|
62
|
+
case "elements": {
|
|
63
|
+
const elements = wrappedElements(value);
|
|
64
|
+
return elements !== null && elements.length > 0;
|
|
65
|
+
}
|
|
57
66
|
case "attributes": {
|
|
58
67
|
const el = loneElement(`<y ${value}></y>`);
|
|
59
68
|
return el !== null && el.childNodes.length === 0;
|
|
@@ -70,6 +79,7 @@ function acceptRawXml(shape, value) {
|
|
|
70
79
|
}
|
|
71
80
|
export {
|
|
72
81
|
ANY_ELEMENT,
|
|
82
|
+
ANY_ELEMENTS,
|
|
73
83
|
ATTRIBUTES,
|
|
74
84
|
ELEMENT,
|
|
75
85
|
acceptRawXml
|
package/dist/ooxml/image.d.ts
CHANGED
|
@@ -67,11 +67,10 @@ export interface DrawingPicture {
|
|
|
67
67
|
*/
|
|
68
68
|
export declare function readDrawingPicture(drawing: Element): DrawingPicture | null;
|
|
69
69
|
/**
|
|
70
|
-
* The same drawing XML with
|
|
70
|
+
* The same drawing XML with its inline extent and its picture transform's extent set to this size.
|
|
71
71
|
*
|
|
72
|
-
* Only those two elements are touched; every other byte
|
|
73
|
-
*
|
|
74
|
-
* unchanged, so nothing has to keep track of whether a resize happened.
|
|
72
|
+
* Only those two elements' size attributes are touched; every other byte stays where it was.
|
|
73
|
+
* Values already equal to the requested size keep their original spelling as well.
|
|
75
74
|
*/
|
|
76
75
|
export declare function withExtent(xml: string, extent: ImageExtent): string;
|
|
77
76
|
/** A picture that was inserted during editing and has no original XML to go back to */
|
package/dist/ooxml/image.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/ooxml/image.ts
|
|
2
2
|
import { NAMESPACES } from "./names.js";
|
|
3
|
-
import {
|
|
3
|
+
import { parseAttrs, readTag } from "./tagScan.js";
|
|
4
|
+
import { childByLocalName, escapeXml, localPart, R_NS } from "./xml.js";
|
|
4
5
|
var EMU_PER_PX = 9525;
|
|
5
6
|
function emuToPx(emu) {
|
|
6
7
|
return emu / EMU_PER_PX;
|
|
@@ -76,11 +77,55 @@ function readDrawingPicture(drawing) {
|
|
|
76
77
|
const descr = childOf(inline, "docPr")?.getAttribute("descr") ?? null;
|
|
77
78
|
return { relId, extent, alt: descr === "" ? null : descr };
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
function isPictureSize(path) {
|
|
81
|
+
const names = path.join("/");
|
|
82
|
+
return names === "drawing/inline/extent" || names === "drawing/inline/graphic/graphicData/pic/spPr/xfrm/ext";
|
|
83
|
+
}
|
|
84
|
+
function resizeTag(open, extent) {
|
|
85
|
+
const tag = readTag(open, 0);
|
|
86
|
+
if (!tag) return open;
|
|
87
|
+
const attrs = new Map(
|
|
88
|
+
parseAttrs(
|
|
89
|
+
open.slice(tag.nameEnd, tag.end - (tag.kind === "empty" ? 2 : 1))
|
|
90
|
+
) ?? []
|
|
91
|
+
);
|
|
92
|
+
return open.replace(
|
|
93
|
+
/(\s+)([^\s=/>]+)(\s*=\s*)(["'])([\s\S]*?)\4/g,
|
|
94
|
+
(whole, gap, name, equals, quote) => {
|
|
95
|
+
if (name !== "cx" && name !== "cy") return whole;
|
|
96
|
+
const size = extent[name];
|
|
97
|
+
if (Number(attrs.get(name)) === size) return whole;
|
|
98
|
+
return `${gap}${name}${equals}${quote}${size}${quote}`;
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
81
102
|
function withExtent(xml, extent) {
|
|
82
|
-
const
|
|
83
|
-
|
|
103
|
+
const path = [];
|
|
104
|
+
const parts = [];
|
|
105
|
+
let at = 0;
|
|
106
|
+
let kept = 0;
|
|
107
|
+
for (; ; ) {
|
|
108
|
+
const lt = xml.indexOf("<", at);
|
|
109
|
+
if (lt === -1) break;
|
|
110
|
+
const tag = readTag(xml, lt);
|
|
111
|
+
if (!tag) return xml;
|
|
112
|
+
if (tag.kind === "close") {
|
|
113
|
+
path.pop();
|
|
114
|
+
} else if (tag.kind !== "other") {
|
|
115
|
+
path.push(localPart(tag.name));
|
|
116
|
+
if (isPictureSize(path)) {
|
|
117
|
+
parts.push(
|
|
118
|
+
xml.slice(kept, lt),
|
|
119
|
+
resizeTag(xml.slice(lt, tag.end), extent)
|
|
120
|
+
);
|
|
121
|
+
kept = tag.end;
|
|
122
|
+
}
|
|
123
|
+
if (tag.kind === "empty") path.pop();
|
|
124
|
+
}
|
|
125
|
+
at = tag.end;
|
|
126
|
+
}
|
|
127
|
+
parts.push(xml.slice(kept));
|
|
128
|
+
return parts.join("");
|
|
84
129
|
}
|
|
85
130
|
function imageDrawingXml(image) {
|
|
86
131
|
const size = `cx="${image.extent.cx}" cy="${image.extent.cy}"`;
|
package/dist/ooxml/names.d.ts
CHANGED
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
* here, and the part a fragment is spliced into declares the same binding, so the prefix is
|
|
7
7
|
* decided once rather than at every call site.
|
|
8
8
|
*/
|
|
9
|
+
/** The wordprocessing namespace that every element we read lives in */
|
|
10
|
+
export declare const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
11
|
+
/**
|
|
12
|
+
* The relationship namespace. It is both where the `r:embed` attributes live and the base
|
|
13
|
+
* every relationship type name is built on
|
|
14
|
+
*/
|
|
15
|
+
export declare const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
16
|
+
/**
|
|
17
|
+
* The math namespace. Nothing here is written under a prefix of ours - a `m:oMath` travels as the
|
|
18
|
+
* XML it arrived as - so it names the namespace alone and stays out of `NAMESPACES`, which is the
|
|
19
|
+
* list of prefixes the writer spells out.
|
|
20
|
+
*/
|
|
21
|
+
export declare const M_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math";
|
|
9
22
|
/** The prefix every WordprocessingML element and attribute this package writes carries */
|
|
10
23
|
export declare const W_PREFIX = "w";
|
|
11
24
|
export declare const NAMESPACES: {
|
|
@@ -19,6 +32,8 @@ export declare const NAMESPACES: {
|
|
|
19
32
|
readonly pic: "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
20
33
|
};
|
|
21
34
|
export type KnownPrefix = keyof typeof NAMESPACES;
|
|
35
|
+
/** Whether this is a prefix the package has a namespace for, rather than one a document brought */
|
|
36
|
+
export declare function isKnownPrefix(prefix: string): prefix is KnownPrefix;
|
|
22
37
|
/** The name `local` goes out under (`qualify("w15", "commentEx")` -> `w15:commentEx`) */
|
|
23
38
|
export declare function qualify(prefix: KnownPrefix, local: string): string;
|
|
24
39
|
/** `wName("val")` -> `w:val`. The one place the written WordprocessingML prefix is decided */
|