@portone/docx-editor 0.2.0 → 0.3.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 +174 -0
- package/CONTRIBUTING.md +9 -1
- package/dist/DocxEditor.d.ts +6 -0
- package/dist/DocxEditor.js +12 -29
- package/dist/core.d.ts +23 -8
- package/dist/core.js +9 -4
- package/dist/docx/cloning.d.ts +38 -0
- package/dist/docx/cloning.js +74 -0
- package/dist/docx/commentOnlyChange.d.ts +14 -7
- package/dist/docx/commentOnlyChange.js +9 -139
- package/dist/docx/comments/constants.d.ts +3 -4
- package/dist/docx/comments/constants.js +4 -5
- package/dist/docx/comments/grammar.d.ts +86 -0
- package/dist/docx/comments/grammar.js +223 -0
- package/dist/docx/comments/parts.d.ts +52 -0
- package/dist/docx/comments/parts.js +279 -0
- package/dist/docx/comments/people.d.ts +11 -2
- package/dist/docx/comments/people.js +28 -106
- package/dist/docx/comments/policy.d.ts +7 -0
- package/dist/docx/comments/policy.js +43 -0
- package/dist/docx/comments/reading.d.ts +5 -3
- package/dist/docx/comments/reading.js +30 -29
- package/dist/docx/comments/writing.d.ts +19 -7
- package/dist/docx/comments/writing.js +105 -137
- package/dist/docx/documentSettings.d.ts +7 -0
- package/dist/docx/documentSettings.js +10 -2
- package/dist/docx/exportDocx.d.ts +40 -5
- package/dist/docx/exportDocx.js +71 -72
- package/dist/docx/exportRefs.d.ts +5 -2
- package/dist/docx/exportRefs.js +3 -1
- package/dist/docx/fidelity.d.ts +43 -0
- package/dist/docx/fidelity.js +64 -0
- package/dist/docx/formatting/attrs.d.ts +27 -0
- package/dist/docx/formatting/attrs.js +31 -0
- package/dist/docx/formatting/context.d.ts +31 -0
- package/dist/docx/formatting/context.js +42 -0
- package/dist/docx/formatting/direct.d.ts +6 -5
- package/dist/docx/formatting/direct.js +52 -81
- package/dist/docx/formatting/resolve.d.ts +45 -0
- package/dist/docx/formatting/resolve.js +140 -0
- package/dist/docx/formatting/runProperties.d.ts +93 -0
- package/dist/docx/formatting/runProperties.js +316 -0
- package/dist/docx/formatting/styles.js +3 -3
- package/dist/docx/formatting/tabStops.js +7 -22
- package/dist/docx/formatting.d.ts +4 -1
- package/dist/docx/formatting.js +4 -1
- package/dist/docx/headersFooters.js +13 -22
- package/dist/docx/identities.d.ts +67 -0
- package/dist/docx/identities.js +174 -0
- package/dist/docx/importDocx.d.ts +12 -1
- package/dist/docx/importDocx.js +72 -79
- package/dist/docx/importParagraph.d.ts +1 -1
- package/dist/docx/importParagraph.js +4 -3
- package/dist/docx/importTable.d.ts +1 -1
- package/dist/docx/importTable.js +17 -1
- package/dist/docx/invariants.d.ts +33 -0
- package/dist/docx/invariants.js +256 -0
- package/dist/docx/media.d.ts +6 -4
- package/dist/docx/media.js +6 -37
- package/dist/docx/newLists.d.ts +20 -0
- package/dist/docx/newLists.js +36 -0
- package/dist/docx/notes.js +6 -12
- package/dist/docx/numberingPlanner.d.ts +8 -0
- package/dist/docx/numberingPlanner.js +19 -0
- package/dist/docx/packageParts.d.ts +42 -0
- package/dist/docx/packageParts.js +135 -0
- package/dist/docx/pageGeometry.d.ts +2 -0
- package/dist/docx/pageGeometry.js +18 -9
- package/dist/docx/paraProps.d.ts +10 -22
- package/dist/docx/paraProps.js +75 -99
- package/dist/docx/partPlan.d.ts +36 -0
- package/dist/docx/partPlan.js +59 -0
- package/dist/docx/protectionPolicy.d.ts +127 -0
- package/dist/docx/protectionPolicy.js +169 -0
- package/dist/docx/relationships.d.ts +1 -1
- package/dist/docx/relationships.js +15 -15
- package/dist/docx/runProps.d.ts +9 -22
- package/dist/docx/runProps.js +15 -168
- package/dist/docx/scan.js +20 -52
- package/dist/docx/sdt.js +14 -37
- package/dist/docx/sdtProps.d.ts +8 -1
- package/dist/docx/sdtProps.js +10 -0
- package/dist/docx/serializeBlock.d.ts +2 -0
- package/dist/docx/serializeBlock.js +9 -7
- package/dist/docx/serializeParagraph.d.ts +2 -1
- package/dist/docx/serializeParagraph.js +25 -14
- package/dist/docx/serializeTable.js +63 -32
- package/dist/docx/session.d.ts +42 -14
- package/dist/docx/session.js +43 -17
- package/dist/docx/storyProjection.d.ts +36 -0
- package/dist/docx/storyProjection.js +23 -0
- package/dist/docx/tableFormatting/editing.js +130 -185
- package/dist/docx/tableFormatting/reading.d.ts +16 -6
- package/dist/docx/tableFormatting/reading.js +40 -20
- package/dist/docx/tableTemplate.js +37 -5
- package/dist/docx/theme.d.ts +0 -6
- package/dist/docx/theme.js +0 -8
- package/dist/download.d.ts +8 -5
- package/dist/download.js +2 -0
- package/dist/editor/clipboard/images.js +17 -3
- package/dist/editor/clipboard/inlineFormatting.d.ts +7 -0
- package/dist/editor/clipboard/inlineFormatting.js +20 -30
- package/dist/editor/commands/breakCommands.js +4 -3
- package/dist/editor/commands/canRunCommand.d.ts +2 -2
- package/dist/editor/commands/canRunCommand.js +1 -1
- package/dist/editor/commands/comments/editing.d.ts +6 -2
- package/dist/editor/commands/comments/editing.js +21 -36
- package/dist/editor/commands/exportQueries.d.ts +15 -0
- package/dist/editor/commands/exportQueries.js +14 -0
- package/dist/editor/commands/fidelityQueries.d.ts +12 -0
- package/dist/editor/commands/fidelityQueries.js +8 -0
- package/dist/editor/commands/formatting/editing.d.ts +2 -2
- package/dist/editor/commands/formatting/editing.js +26 -108
- package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
- package/dist/editor/commands/formatting/propertyCommands.js +103 -0
- package/dist/editor/commands/formatting/shared.d.ts +3 -3
- package/dist/editor/commands/formatting/shared.js +5 -2
- package/dist/editor/commands/historyCommands.js +2 -1
- package/dist/editor/commands/indentCommands.js +5 -4
- package/dist/editor/commands/index.d.ts +11 -0
- package/dist/editor/commands/index.js +5 -0
- package/dist/editor/commands/linkCommands.js +5 -6
- package/dist/editor/commands/listCommands.js +8 -10
- package/dist/editor/commands/lockCommands.d.ts +7 -1
- package/dist/editor/commands/lockCommands.js +35 -37
- package/dist/editor/commands/paragraphCommands.js +28 -31
- package/dist/editor/commands/spacingCommands.js +1 -1
- package/dist/editor/commands/tabCommands.js +4 -3
- package/dist/editor/createEditor.d.ts +17 -29
- package/dist/editor/createEditor.js +61 -67
- package/dist/editor/documentStyles.d.ts +11 -35
- package/dist/editor/documentStyles.js +9 -52
- package/dist/editor/editorDocument.d.ts +56 -0
- package/dist/editor/editorDocument.js +74 -0
- package/dist/editor/externalClipboard.js +166 -33
- package/dist/editor/insertImage.js +4 -3
- package/dist/editor/insertTable.js +4 -3
- package/dist/editor/paragraphEdits.d.ts +11 -18
- package/dist/editor/paragraphEdits.js +7 -16
- package/dist/editor/plugins/displayDerivation.d.ts +47 -0
- package/dist/editor/plugins/displayDerivation.js +78 -0
- package/dist/editor/plugins/documentProtection.d.ts +3 -3
- package/dist/editor/plugins/imagePaste.js +4 -3
- package/dist/editor/plugins/keymap.js +18 -3
- package/dist/editor/plugins/lockedContent.d.ts +4 -4
- package/dist/editor/plugins/lockedContent.js +1 -1
- package/dist/editor/plugins/numberingDecorations.d.ts +5 -11
- package/dist/editor/plugins/numberingDecorations.js +7 -17
- package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
- package/dist/editor/plugins/paragraphDisplay.js +51 -0
- package/dist/editor/plugins/tabLayout.js +1 -1
- package/dist/editor/plugins/tableDisplay.d.ts +6 -0
- package/dist/editor/plugins/tableDisplay.js +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/model/format.d.ts +30 -8
- package/dist/model/format.js +35 -22
- package/dist/model/tabStops.d.ts +9 -0
- package/dist/model/tabStops.js +18 -0
- package/dist/numbering/listTemplate.js +49 -10
- package/dist/numbering/parseNumbering.d.ts +14 -1
- package/dist/numbering/parseNumbering.js +35 -22
- package/dist/numbering/writeNumbering.d.ts +3 -4
- package/dist/numbering/writeNumbering.js +14 -25
- package/dist/ooxml/childOrder.d.ts +34 -0
- package/dist/ooxml/childOrder.js +496 -0
- package/dist/ooxml/element.d.ts +65 -0
- package/dist/ooxml/element.js +68 -0
- package/dist/ooxml/errors.d.ts +3 -2
- package/dist/ooxml/fragment.d.ts +53 -0
- package/dist/ooxml/fragment.js +76 -0
- package/dist/ooxml/image.d.ts +4 -0
- package/dist/ooxml/image.js +3 -5
- package/dist/ooxml/names.d.ts +27 -0
- package/dist/ooxml/names.js +29 -0
- package/dist/ooxml/partSplice.d.ts +67 -0
- package/dist/ooxml/partSplice.js +169 -0
- package/dist/ooxml/precedence.d.ts +31 -0
- package/dist/ooxml/precedence.js +51 -0
- package/dist/ooxml/props.d.ts +112 -0
- package/dist/ooxml/props.js +214 -0
- package/dist/ooxml/simpleTypes.d.ts +103 -0
- package/dist/ooxml/simpleTypes.js +182 -0
- package/dist/ooxml/tabStops.js +8 -27
- package/dist/ooxml/tagScan.d.ts +34 -0
- package/dist/ooxml/tagScan.js +108 -0
- package/dist/ooxml/units.d.ts +25 -13
- package/dist/ooxml/units.js +65 -31
- package/dist/ooxml/xml.d.ts +52 -0
- package/dist/ooxml/xml.js +64 -5
- package/dist/page/blockKinds.d.ts +103 -0
- package/dist/page/blockKinds.js +11 -0
- package/dist/page/kinds/index.d.ts +6 -0
- package/dist/page/kinds/index.js +10 -0
- package/dist/page/kinds/paragraphKind.d.ts +10 -0
- package/dist/page/kinds/paragraphKind.js +71 -0
- package/dist/page/kinds/tableKind.d.ts +10 -0
- package/dist/page/kinds/tableKind.js +178 -0
- package/dist/page/measureBlocks.d.ts +3 -1
- package/dist/page/measureBlocks.js +24 -25
- package/dist/page/pageDecorations.d.ts +27 -28
- package/dist/page/pageDecorations.js +70 -151
- package/dist/page/pageLayout.d.ts +10 -62
- package/dist/page/pageLayout.js +60 -53
- package/dist/page/usePageLayout.d.ts +2 -2
- package/dist/page/usePageLayout.js +3 -11
- package/dist/schema/attrRoles.d.ts +42 -0
- package/dist/schema/attrRoles.js +141 -0
- package/dist/schema/displayDerivation.d.ts +82 -0
- package/dist/schema/displayDerivation.js +130 -0
- package/dist/schema/docxSchema.d.ts +9 -0
- package/dist/schema/docxSchema.js +237 -114
- package/dist/schema/editGuard.d.ts +99 -0
- package/dist/schema/editGuard.js +43 -0
- package/dist/schema/guards.d.ts +91 -0
- package/dist/schema/guards.js +108 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/locks.d.ts +17 -77
- package/dist/schema/locks.js +26 -70
- package/dist/schema/preservedGuards.d.ts +50 -0
- package/dist/schema/preservedGuards.js +80 -0
- package/dist/schema/protection.d.ts +17 -4
- package/dist/schema/protection.js +4 -2
- package/dist/schema/sourceEquality.d.ts +19 -0
- package/dist/schema/sourceEquality.js +39 -0
- package/dist/styles/inlineStyle.js +15 -6
- package/dist/table/cellFormatting.d.ts +8 -1
- package/dist/table/cellFormatting.js +10 -17
- package/dist/table/commands.d.ts +2 -2
- package/dist/table/commands.js +20 -18
- package/dist/table/format.d.ts +3 -0
- package/dist/table/format.js +3 -9
- package/dist/table/gridBorders.d.ts +14 -16
- package/dist/table/gridBorders.js +3 -41
- package/dist/table/index.d.ts +2 -2
- package/dist/table/merge.d.ts +4 -8
- package/dist/table/merge.js +5 -5
- package/package.json +10 -3
- package/dist/docx/comments/contentTypes.d.ts +0 -7
- package/dist/docx/comments/contentTypes.js +0 -38
- package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
- package/dist/docx/formatting/effectiveParagraph.js +0 -81
- package/dist/docx/propsXml.d.ts +0 -49
- package/dist/docx/propsXml.js +0 -302
- package/dist/docx/uniqueControls.d.ts +0 -14
- package/dist/docx/uniqueControls.js +0 -62
- package/dist/editor/plugins/bookmarkProtection.d.ts +0 -3
- package/dist/editor/plugins/bookmarkProtection.js +0 -28
- package/dist/editor/plugins/commentReservations.d.ts +0 -5
- package/dist/editor/plugins/commentReservations.js +0 -26
- package/dist/editor/plugins/noteProtection.d.ts +0 -3
- package/dist/editor/plugins/noteProtection.js +0 -25
- package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
- package/dist/editor/plugins/styledParagraphs.js +0 -65
- package/dist/page/tableMeasurements.d.ts +0 -10
- package/dist/page/tableMeasurements.js +0 -115
|
@@ -1,59 +1,27 @@
|
|
|
1
1
|
// src/docx/formatting/direct.ts
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
isUnderlineKind
|
|
3
|
+
RUN_FORMAT_KEYS
|
|
5
4
|
} from "../../model/format.js";
|
|
5
|
+
import {
|
|
6
|
+
ST_DecimalNumber,
|
|
7
|
+
ST_SignedTwipsMeasure,
|
|
8
|
+
ST_TwipsMeasure,
|
|
9
|
+
TWIPS_PER_PT
|
|
10
|
+
} from "../../ooxml/simpleTypes.js";
|
|
6
11
|
import { readTabStopDirectives } from "../../ooxml/tabStops.js";
|
|
7
12
|
import {
|
|
8
13
|
ALIGN_BY_JC,
|
|
9
14
|
borderSide,
|
|
10
15
|
childValue,
|
|
11
|
-
halfPointsToPt,
|
|
12
16
|
isOn,
|
|
13
17
|
round,
|
|
14
18
|
shadingOf,
|
|
15
|
-
toHexColor,
|
|
16
|
-
toNumber,
|
|
17
19
|
twipsToPt,
|
|
18
20
|
wAttr
|
|
19
21
|
} from "../../ooxml/units.js";
|
|
20
22
|
import { childByLocalName } from "../../ooxml/xml.js";
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
THEME_ATTRS,
|
|
24
|
-
themeFontName
|
|
25
|
-
} from "../theme.js";
|
|
26
|
-
var VERTICAL_ALIGN_BY_VAL = {
|
|
27
|
-
superscript: "superscript",
|
|
28
|
-
subscript: "subscript"
|
|
29
|
-
};
|
|
30
|
-
function fontNamesOf(cssNames) {
|
|
31
|
-
if (!cssNames) return [];
|
|
32
|
-
return cssNames.split(",").map((name) => name.trim().replace(/^"|"$/g, "")).filter((name) => name.length > 0);
|
|
33
|
-
}
|
|
34
|
-
var FONT_SLOTS = ["ascii", "eastAsia", "hAnsi", "cs"];
|
|
35
|
-
function slotFontName(rFonts, slot, themeFonts) {
|
|
36
|
-
const written = wAttr(rFonts, slot);
|
|
37
|
-
if (written !== null) return written;
|
|
38
|
-
for (const attr of THEME_ATTRS[slot] ?? []) {
|
|
39
|
-
const resolved = themeFontName(themeFonts, wAttr(rFonts, attr));
|
|
40
|
-
if (resolved !== null) return resolved;
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
function fontFamilyOf(rFonts, themeFonts) {
|
|
45
|
-
const names = FONT_SLOTS.map((slot) => slotFontName(rFonts, slot, themeFonts)).filter((name) => name !== null).filter((name) => name.length > 0 && !/["';\\]/.test(name));
|
|
46
|
-
const unique = Array.from(new Set(names));
|
|
47
|
-
return unique.length > 0 ? unique.map((name) => `"${name}"`).join(",") : null;
|
|
48
|
-
}
|
|
49
|
-
function langOf(rPr) {
|
|
50
|
-
const lang = childByLocalName(rPr, "lang");
|
|
51
|
-
if (!lang) return null;
|
|
52
|
-
const eastAsia = wAttr(lang, "eastAsia");
|
|
53
|
-
if (eastAsia !== null && eastAsia.length > 0) return eastAsia;
|
|
54
|
-
const value = wAttr(lang, "val");
|
|
55
|
-
return value !== null && value.length > 0 ? value : null;
|
|
56
|
-
}
|
|
23
|
+
import { NO_THEME_FONTS } from "../theme.js";
|
|
24
|
+
import { RUN_PROPERTIES } from "./runProperties.js";
|
|
57
25
|
function drawnBorder(pBdr, side) {
|
|
58
26
|
const css = borderSide(pBdr, side);
|
|
59
27
|
return css === "none" ? null : css;
|
|
@@ -76,33 +44,39 @@ function readIndent(pPr) {
|
|
|
76
44
|
const ind = childByLocalName(pPr, "ind");
|
|
77
45
|
if (!ind) return {};
|
|
78
46
|
const format = {};
|
|
79
|
-
const start = twipsToPt(
|
|
47
|
+
const start = twipsToPt(
|
|
48
|
+
ST_SignedTwipsMeasure.parse(wAttr(ind, "start") ?? wAttr(ind, "left"))
|
|
49
|
+
);
|
|
80
50
|
if (start !== null) format.indentStartPt = start;
|
|
81
|
-
const end = twipsToPt(
|
|
51
|
+
const end = twipsToPt(
|
|
52
|
+
ST_SignedTwipsMeasure.parse(wAttr(ind, "end") ?? wAttr(ind, "right"))
|
|
53
|
+
);
|
|
82
54
|
if (end !== null) format.indentEndPt = end;
|
|
83
|
-
const hanging = twipsToPt(wAttr(ind, "hanging"));
|
|
84
|
-
const firstLine = twipsToPt(wAttr(ind, "firstLine"));
|
|
55
|
+
const hanging = twipsToPt(ST_TwipsMeasure.parse(wAttr(ind, "hanging")));
|
|
56
|
+
const firstLine = twipsToPt(ST_TwipsMeasure.parse(wAttr(ind, "firstLine")));
|
|
85
57
|
if (hanging !== null) format.textIndentPt = -hanging;
|
|
86
58
|
else if (firstLine !== null) format.textIndentPt = firstLine;
|
|
87
59
|
return format;
|
|
88
60
|
}
|
|
61
|
+
var LINE_UNITS_PER_LINE = 240;
|
|
89
62
|
function readLineSpacing(pPr) {
|
|
90
63
|
const spacing = childByLocalName(pPr, "spacing");
|
|
91
64
|
if (!spacing) return null;
|
|
92
|
-
const line =
|
|
65
|
+
const line = ST_SignedTwipsMeasure.parse(wAttr(spacing, "line"));
|
|
93
66
|
if (line === null) return null;
|
|
94
67
|
const rule = wAttr(spacing, "lineRule");
|
|
95
|
-
|
|
96
|
-
if (rule === "
|
|
97
|
-
return { rule: "
|
|
68
|
+
const pt = round(line / TWIPS_PER_PT);
|
|
69
|
+
if (rule === "exact") return { rule: "exact", pt };
|
|
70
|
+
if (rule === "atLeast") return { rule: "atLeast", pt };
|
|
71
|
+
return { rule: "auto", lines: round(line / LINE_UNITS_PER_LINE) };
|
|
98
72
|
}
|
|
99
73
|
function readSpacing(pPr) {
|
|
100
74
|
const spacing = childByLocalName(pPr, "spacing");
|
|
101
75
|
if (!spacing) return {};
|
|
102
76
|
const format = {};
|
|
103
|
-
const before = twipsToPt(wAttr(spacing, "before"));
|
|
77
|
+
const before = twipsToPt(ST_TwipsMeasure.parse(wAttr(spacing, "before")));
|
|
104
78
|
if (before !== null) format.spaceBeforePt = before;
|
|
105
|
-
const after = twipsToPt(wAttr(spacing, "after"));
|
|
79
|
+
const after = twipsToPt(ST_TwipsMeasure.parse(wAttr(spacing, "after")));
|
|
106
80
|
if (after !== null) format.spaceAfterPt = after;
|
|
107
81
|
const lineSpacing = readLineSpacing(pPr);
|
|
108
82
|
if (lineSpacing) format.lineSpacing = lineSpacing;
|
|
@@ -111,13 +85,13 @@ function readSpacing(pPr) {
|
|
|
111
85
|
function readNumbering(pPr) {
|
|
112
86
|
const numPr = childByLocalName(pPr, "numPr");
|
|
113
87
|
if (!numPr) return {};
|
|
114
|
-
const numId =
|
|
88
|
+
const numId = ST_DecimalNumber.parse(childValue(numPr, "numId"));
|
|
115
89
|
if (numId === 0) return { numbering: null };
|
|
116
90
|
if (numId === null || numId < 0) return {};
|
|
117
91
|
return {
|
|
118
92
|
numbering: {
|
|
119
|
-
numId
|
|
120
|
-
ilvl:
|
|
93
|
+
numId,
|
|
94
|
+
ilvl: ST_DecimalNumber.parse(childValue(numPr, "ilvl")) ?? 0
|
|
121
95
|
}
|
|
122
96
|
};
|
|
123
97
|
}
|
|
@@ -137,34 +111,23 @@ function readParagraphFormat(pPr) {
|
|
|
137
111
|
format.direction = isOn(pPr, "bidi") ? "rtl" : "ltr";
|
|
138
112
|
}
|
|
139
113
|
if (isOn(pPr, "pageBreakBefore")) format.pageBreakBefore = true;
|
|
114
|
+
if (childByLocalName(pPr, "keepNext")) {
|
|
115
|
+
format.keepNext = isOn(pPr, "keepNext");
|
|
116
|
+
}
|
|
140
117
|
const background = shadingOf(pPr);
|
|
141
118
|
if (background) format.background = background;
|
|
142
119
|
return format;
|
|
143
120
|
}
|
|
121
|
+
function readRunProperty(format, key, rPr, themeFonts) {
|
|
122
|
+
const value = RUN_PROPERTIES[key].read(rPr, themeFonts);
|
|
123
|
+
if (value !== void 0) format[key] = value;
|
|
124
|
+
}
|
|
144
125
|
function readRunFormat(rPr, themeFonts = NO_THEME_FONTS) {
|
|
145
126
|
if (!rPr) return null;
|
|
146
127
|
const format = {};
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (isOn(rPr, "smallCaps")) format.smallCaps = true;
|
|
151
|
-
const underline = childValue(rPr, "u");
|
|
152
|
-
if (isUnderlineKind(underline)) format.underline = underline;
|
|
153
|
-
const fontSizePt = halfPointsToPt(childValue(rPr, "sz"));
|
|
154
|
-
if (fontSizePt !== null) format.fontSizePt = fontSizePt;
|
|
155
|
-
const rFonts = childByLocalName(rPr, "rFonts");
|
|
156
|
-
const fontFamily = rFonts ? fontFamilyOf(rFonts, themeFonts) : null;
|
|
157
|
-
if (fontFamily) format.fontFamily = fontFamily;
|
|
158
|
-
const color = toHexColor(childValue(rPr, "color"));
|
|
159
|
-
if (color) format.color = color;
|
|
160
|
-
const highlight = childValue(rPr, "highlight");
|
|
161
|
-
if (isHighlightName(highlight)) format.highlight = highlight;
|
|
162
|
-
const background = shadingOf(rPr);
|
|
163
|
-
if (background) format.background = background;
|
|
164
|
-
const verticalAlign = VERTICAL_ALIGN_BY_VAL[childValue(rPr, "vertAlign") ?? ""];
|
|
165
|
-
if (verticalAlign) format.verticalAlign = verticalAlign;
|
|
166
|
-
const lang = langOf(rPr);
|
|
167
|
-
if (lang) format.lang = lang;
|
|
128
|
+
for (const key of RUN_FORMAT_KEYS) {
|
|
129
|
+
readRunProperty(format, key, rPr, themeFonts);
|
|
130
|
+
}
|
|
168
131
|
return format;
|
|
169
132
|
}
|
|
170
133
|
var NO_DOCUMENT_DEFAULTS = {
|
|
@@ -180,22 +143,30 @@ function defaultProperties(styles, slot, name) {
|
|
|
180
143
|
function readDefaultParagraphFormat(styles) {
|
|
181
144
|
return readParagraphFormat(defaultProperties(styles, "pPrDefault", "pPr")) ?? {};
|
|
182
145
|
}
|
|
146
|
+
function readRunDefaults(styles, themeFonts = NO_THEME_FONTS) {
|
|
147
|
+
return readRunFormat(defaultProperties(styles, "rPrDefault", "rPr"), themeFonts) ?? {};
|
|
148
|
+
}
|
|
149
|
+
function runStyleIdOf(rPr) {
|
|
150
|
+
const id = rPr ? childValue(rPr, "rStyle") : null;
|
|
151
|
+
return id !== null && id.length > 0 ? id : null;
|
|
152
|
+
}
|
|
183
153
|
function readDocumentDefaults(styles, themeFonts = NO_THEME_FONTS) {
|
|
184
|
-
const
|
|
154
|
+
const run = readRunDefaults(styles, themeFonts);
|
|
185
155
|
const pPr = defaultProperties(styles, "pPrDefault", "pPr");
|
|
186
|
-
const rFonts = rPr ? childByLocalName(rPr, "rFonts") : null;
|
|
187
156
|
return {
|
|
188
|
-
fontSizePt:
|
|
189
|
-
fontFamily:
|
|
157
|
+
fontSizePt: run.fontSizePt ?? null,
|
|
158
|
+
fontFamily: run.fontFamily ?? null,
|
|
190
159
|
lineSpacing: pPr ? readLineSpacing(pPr) : null
|
|
191
160
|
};
|
|
192
161
|
}
|
|
193
162
|
export {
|
|
163
|
+
LINE_UNITS_PER_LINE,
|
|
194
164
|
NO_DOCUMENT_DEFAULTS,
|
|
195
|
-
fontNamesOf,
|
|
196
165
|
readDefaultParagraphFormat,
|
|
197
166
|
readDocumentDefaults,
|
|
198
167
|
readLineSpacing,
|
|
199
168
|
readParagraphFormat,
|
|
200
|
-
|
|
169
|
+
readRunDefaults,
|
|
170
|
+
readRunFormat,
|
|
171
|
+
runStyleIdOf
|
|
201
172
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the §17.7.2 hierarchy for one paragraph and for the runs inside it.
|
|
3
|
+
*
|
|
4
|
+
* The layers are put in order here and nowhere else, so a paragraph's display values are the
|
|
5
|
+
* same whichever path asked for them: opening the document, an edit, a paste, or a paragraph an
|
|
6
|
+
* edit built from nothing.
|
|
7
|
+
*/
|
|
8
|
+
import { type ParagraphFormat, type RunFormat } from "../../model/format";
|
|
9
|
+
import type { TabStop } from "../../model/tabStops";
|
|
10
|
+
import type { TableStyleOverrideType } from "../tableFormatting";
|
|
11
|
+
import type { FormattingContext } from "./context";
|
|
12
|
+
/** Where a paragraph sits when it is inside a table cell. null for body text */
|
|
13
|
+
export interface ParagraphPlacement {
|
|
14
|
+
tableStyleId: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* The conditional formats the cell takes, lowest first. Not read yet: a table style
|
|
17
|
+
* contributes the values it lays down for the whole table alone
|
|
18
|
+
*/
|
|
19
|
+
conditions: readonly TableStyleOverrideType[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The layer of the hierarchy a tab stop came from. Removing an inherited stop means writing a
|
|
23
|
+
* `clear` over it, while a direct one is deleted from the paragraph's own list, which is what a
|
|
24
|
+
* ruler needs to tell apart. The document defaults and a table style count as `style`, since a
|
|
25
|
+
* stop from either is taken away the same way
|
|
26
|
+
*/
|
|
27
|
+
export type TabStopLayer = "numbering" | "style" | "direct" | "implicit";
|
|
28
|
+
export interface LayeredTabStop extends TabStop {
|
|
29
|
+
layer: TabStopLayer;
|
|
30
|
+
}
|
|
31
|
+
export interface ResolvedParagraph {
|
|
32
|
+
/** `format` in `schema`: docDefaults < table style < numbering level < paragraph style < direct */
|
|
33
|
+
format: ParagraphFormat | null;
|
|
34
|
+
/** `styleRun` in `schema`: run defaults < table style rPr < paragraph style rPr. Default font and size stay in CSS variables */
|
|
35
|
+
styleRun: RunFormat | null;
|
|
36
|
+
/** Everything below a run's own formatting, docDefaults included. What a removed run property falls back to */
|
|
37
|
+
inheritedRun: RunFormat;
|
|
38
|
+
/** The stops `format.tabStops` holds, each with the layer that laid it down */
|
|
39
|
+
tabStops: readonly LayeredTabStop[];
|
|
40
|
+
}
|
|
41
|
+
export declare function resolveParagraph(pPr: string | null, context: FormattingContext, placement?: ParagraphPlacement | null): ResolvedParagraph;
|
|
42
|
+
/** `format` on a run mark: paragraph.styleRun < character style < the run's own rPr */
|
|
43
|
+
export declare function resolveRun(rPr: string | null, paragraph: ResolvedParagraph, context: FormattingContext): RunFormat | null;
|
|
44
|
+
/** paragraph.inheritedRun < character style. What a run property taken out of the rPr falls back to */
|
|
45
|
+
export declare function inheritedRunFormat(rPr: string | null, paragraph: ResolvedParagraph, context: FormattingContext): RunFormat;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// src/docx/formatting/resolve.ts
|
|
2
|
+
import {
|
|
3
|
+
toParagraphFormat
|
|
4
|
+
} from "../../model/format.js";
|
|
5
|
+
import {
|
|
6
|
+
levelIndentPt
|
|
7
|
+
} from "../../numbering/parseNumbering.js";
|
|
8
|
+
import { parsePropsXml } from "../../ooxml/props.js";
|
|
9
|
+
import { readParagraphFormat, readRunFormat, runStyleIdOf } from "./direct.js";
|
|
10
|
+
import {
|
|
11
|
+
layerRunFormat,
|
|
12
|
+
paragraphStyleFormat
|
|
13
|
+
} from "./styles.js";
|
|
14
|
+
function directLayer(pPr) {
|
|
15
|
+
return pPr === null ? {} : readParagraphFormat(parsePropsXml(pPr)) ?? {};
|
|
16
|
+
}
|
|
17
|
+
function tableStyleOf(placement, context) {
|
|
18
|
+
const id = placement?.tableStyleId ?? null;
|
|
19
|
+
return id === null ? void 0 : context.styles.get(id);
|
|
20
|
+
}
|
|
21
|
+
function numberingLevelOf(layers, context) {
|
|
22
|
+
const ref = layers.reduce(
|
|
23
|
+
(found, layer) => layer.numbering === void 0 ? found : layer.numbering,
|
|
24
|
+
void 0
|
|
25
|
+
);
|
|
26
|
+
if (!ref) return void 0;
|
|
27
|
+
return context.numbering.lists.get(ref.numId)?.levels.get(ref.ilvl);
|
|
28
|
+
}
|
|
29
|
+
function numberingLayer(level) {
|
|
30
|
+
return level?.tabStops ? { tabStops: level.tabStops } : {};
|
|
31
|
+
}
|
|
32
|
+
function layerValues(base, over) {
|
|
33
|
+
const { tabStops: _stops, ...values } = over;
|
|
34
|
+
return { ...base, ...values };
|
|
35
|
+
}
|
|
36
|
+
function byPosition(left, right) {
|
|
37
|
+
return left.positionPt - right.positionPt;
|
|
38
|
+
}
|
|
39
|
+
function explicitStops(layers) {
|
|
40
|
+
const spoken = /* @__PURE__ */ new Map();
|
|
41
|
+
for (const { values, stops } of layers) {
|
|
42
|
+
for (const stop of values.tabStops ?? []) {
|
|
43
|
+
spoken.set(stop.positionPt, { stop, layer: stops });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return [...spoken.values()].flatMap(
|
|
47
|
+
({ stop, layer }) => stop.align === "clear" ? [] : [{ ...stop, layer }]
|
|
48
|
+
).sort(byPosition);
|
|
49
|
+
}
|
|
50
|
+
function hangingStopPt(values, level) {
|
|
51
|
+
const leading = values.indentStartPt ?? values.indentLeftPt ?? level.startPt;
|
|
52
|
+
const textIndent = values.textIndentPt ?? level.textIndentPt;
|
|
53
|
+
return leading !== null && textIndent !== null && textIndent < 0 ? leading : null;
|
|
54
|
+
}
|
|
55
|
+
function withImplicitStop(stops, positionPt) {
|
|
56
|
+
if (positionPt === null) return stops;
|
|
57
|
+
if (stops.some((stop) => stop.positionPt === positionPt)) return stops;
|
|
58
|
+
const implicit = {
|
|
59
|
+
positionPt,
|
|
60
|
+
align: "start",
|
|
61
|
+
layer: "implicit"
|
|
62
|
+
};
|
|
63
|
+
return [...stops, implicit].sort(byPosition);
|
|
64
|
+
}
|
|
65
|
+
function orNull(values) {
|
|
66
|
+
return Object.keys(values).length === 0 ? null : values;
|
|
67
|
+
}
|
|
68
|
+
function resolveParagraph(pPr, context, placement = null) {
|
|
69
|
+
const tableStyle = tableStyleOf(placement, context);
|
|
70
|
+
const style = paragraphStyleFormat(
|
|
71
|
+
pPr,
|
|
72
|
+
context.styles,
|
|
73
|
+
context.defaultParagraphStyleId
|
|
74
|
+
);
|
|
75
|
+
const direct = directLayer(pPr);
|
|
76
|
+
const explicit = [
|
|
77
|
+
{ values: context.paragraphDefaults, stops: "style" },
|
|
78
|
+
{ values: tableStyle?.paragraph ?? {}, stops: "style" },
|
|
79
|
+
{ values: style?.paragraph ?? {}, stops: "style" },
|
|
80
|
+
{ values: direct, stops: "direct" }
|
|
81
|
+
];
|
|
82
|
+
const level = numberingLevelOf(
|
|
83
|
+
explicit.map((layer) => layer.values),
|
|
84
|
+
context
|
|
85
|
+
);
|
|
86
|
+
const layers = [
|
|
87
|
+
...explicit.slice(0, 2),
|
|
88
|
+
{ values: numberingLayer(level), stops: "numbering" },
|
|
89
|
+
...explicit.slice(2)
|
|
90
|
+
];
|
|
91
|
+
const values = layers.reduce(
|
|
92
|
+
(base, layer) => layerValues(base, layer.values),
|
|
93
|
+
{}
|
|
94
|
+
);
|
|
95
|
+
const stops = explicitStops(layers);
|
|
96
|
+
const tabStops = context.compat.noTabHangInd ? stops : withImplicitStop(
|
|
97
|
+
stops,
|
|
98
|
+
hangingStopPt(values, levelIndentPt(level?.indent ?? null))
|
|
99
|
+
);
|
|
100
|
+
const format = toParagraphFormat(values) ?? {};
|
|
101
|
+
if (tabStops.length > 0) {
|
|
102
|
+
format.tabStops = tabStops.map(({ layer: _layer, ...stop }) => stop);
|
|
103
|
+
}
|
|
104
|
+
const {
|
|
105
|
+
fontSizePt: _size,
|
|
106
|
+
fontFamily: _font,
|
|
107
|
+
...displayDefaults
|
|
108
|
+
} = context.runDefaults;
|
|
109
|
+
const styleRun = {
|
|
110
|
+
...displayDefaults,
|
|
111
|
+
...tableStyle?.run,
|
|
112
|
+
...style?.run
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
format: orNull(format),
|
|
116
|
+
styleRun: orNull(styleRun),
|
|
117
|
+
inheritedRun: { ...context.runDefaults, ...styleRun },
|
|
118
|
+
tabStops
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function characterStyleRun(rPr, context) {
|
|
122
|
+
const id = runStyleIdOf(rPr);
|
|
123
|
+
return id === null ? {} : context.styles.get(id)?.run ?? {};
|
|
124
|
+
}
|
|
125
|
+
function resolveRun(rPr, paragraph, context) {
|
|
126
|
+
const el = rPr === null ? null : parsePropsXml(rPr);
|
|
127
|
+
return layerRunFormat(
|
|
128
|
+
{ ...paragraph.styleRun, ...characterStyleRun(el, context) },
|
|
129
|
+
readRunFormat(el, context.themeFonts)
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
function inheritedRunFormat(rPr, paragraph, context) {
|
|
133
|
+
const el = rPr === null ? null : parsePropsXml(rPr);
|
|
134
|
+
return { ...paragraph.inheritedRun, ...characterStyleRun(el, context) };
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
inheritedRunFormat,
|
|
138
|
+
resolveParagraph,
|
|
139
|
+
resolveRun
|
|
140
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One row per run property: what it reads out of an rPr, what it writes into one, and whether
|
|
3
|
+
* text already carries a value.
|
|
4
|
+
*
|
|
5
|
+
* Reading, writing and comparing used to be three hand-kept copies of the same vocabulary, so a
|
|
6
|
+
* property could be read under one name and written under another. Here each is one row, and the
|
|
7
|
+
* readers and writers below walk the table, so anything else that has to speak for a run
|
|
8
|
+
* property - a tracked change's `w:rPrChange` snapshot, a style's `w:rPr` - asks the same row.
|
|
9
|
+
*
|
|
10
|
+
* The values read are for display only. What goes back into the document is the rPr string, and
|
|
11
|
+
* a write is a list of children swapped into it (`ooxml/props`), never a tree serialized again.
|
|
12
|
+
*/
|
|
13
|
+
import { type RunFormat } from "../../model/format";
|
|
14
|
+
import { type Props } from "../../ooxml/props";
|
|
15
|
+
import { type ThemeFonts } from "../theme";
|
|
16
|
+
/** What text one child of the rPr is to be changed to. A null xml removes that child */
|
|
17
|
+
export type ChildEdit = readonly [name: string, xml: string | null];
|
|
18
|
+
/** What an edit is written against: the rPr as it stands, and everything the layers below the run lay down */
|
|
19
|
+
export interface RunEditContext {
|
|
20
|
+
rPr: Props;
|
|
21
|
+
inherited: RunFormat;
|
|
22
|
+
}
|
|
23
|
+
type Read<K extends keyof RunFormat> = NonNullable<RunFormat[K]>;
|
|
24
|
+
/**
|
|
25
|
+
* The value an edit sets. An off - `false`, an underline of `none` - is not one: it is spelled
|
|
26
|
+
* as null, the withdrawal, and pinned into the rPr only where the layers below would otherwise
|
|
27
|
+
* show through.
|
|
28
|
+
*/
|
|
29
|
+
export type RunSetting<K extends keyof RunFormat> = Exclude<Read<K>, false | "none">;
|
|
30
|
+
/** A run property as it is read and compared. `R` is the value read, `S` the value an edit sets */
|
|
31
|
+
export interface RunProperty<R, S> {
|
|
32
|
+
/**
|
|
33
|
+
* The rPr children the property owns, in the order CT_RPr lays them down. A `w:rPrChange`
|
|
34
|
+
* snapshot of the property is exactly these
|
|
35
|
+
*/
|
|
36
|
+
readonly children: readonly string[];
|
|
37
|
+
read(rPr: Element, themeFonts: ThemeFonts): R | undefined;
|
|
38
|
+
/** Whether the display values switch or paint the property on, which is what a withdrawal has to undo */
|
|
39
|
+
isOn(format: RunFormat): boolean;
|
|
40
|
+
/** Whether the display values already carry the value, so that writing it would change nothing */
|
|
41
|
+
matches(format: RunFormat, value: S): boolean;
|
|
42
|
+
}
|
|
43
|
+
/** A run property an edit may write as well */
|
|
44
|
+
export interface EditableRunProperty<R, S> extends RunProperty<R, S> {
|
|
45
|
+
/** The children that make the run say the value. null for a value the document cannot record */
|
|
46
|
+
write(value: S, context: RunEditContext): ChildEdit[] | null;
|
|
47
|
+
/** The children that take the run's own say away, pinned off where the layers below would otherwise show through */
|
|
48
|
+
off(context: RunEditContext): ChildEdit[];
|
|
49
|
+
}
|
|
50
|
+
/** The properties read for display alone. Nothing writes them, so no edit names them */
|
|
51
|
+
declare const DISPLAY_ONLY_RUN_KEYS: readonly ["lang"];
|
|
52
|
+
type DisplayOnlyRunKey = (typeof DISPLAY_ONLY_RUN_KEYS)[number];
|
|
53
|
+
export type EditableRunKey = Exclude<keyof RunFormat, DisplayOnlyRunKey>;
|
|
54
|
+
/**
|
|
55
|
+
* A job that changes one run property. A null value withdraws the run's own setting: the layers
|
|
56
|
+
* below stand again, except where they would switch or paint the property on, in which case the
|
|
57
|
+
* off is pinned into the run.
|
|
58
|
+
*/
|
|
59
|
+
export type RunEdit<K extends EditableRunKey = EditableRunKey> = {
|
|
60
|
+
[P in K]: {
|
|
61
|
+
key: P;
|
|
62
|
+
value: RunSetting<P> | null;
|
|
63
|
+
};
|
|
64
|
+
}[K];
|
|
65
|
+
/** The settings an rPr built from nothing records */
|
|
66
|
+
export type RunSettings = {
|
|
67
|
+
[K in EditableRunKey]?: RunSetting<K>;
|
|
68
|
+
};
|
|
69
|
+
/** The editable properties, in the order they are read */
|
|
70
|
+
export declare const EDITABLE_RUN_KEYS: readonly EditableRunKey[];
|
|
71
|
+
/**
|
|
72
|
+
* The font names held in a display value.
|
|
73
|
+
* Splits the CSS name list `fontFamilyOf` produced back into individual names.
|
|
74
|
+
*/
|
|
75
|
+
export declare function fontNamesOf(cssNames: string | undefined | null): string[];
|
|
76
|
+
export declare const RUN_PROPERTIES: {
|
|
77
|
+
[K in keyof Required<RunFormat>]: RunProperty<Read<K>, RunSetting<K>>;
|
|
78
|
+
};
|
|
79
|
+
/** Which children of the rPr one job changes and how. null for a value whose meaning cannot be made out */
|
|
80
|
+
export declare function runChildEdits<K extends EditableRunKey>(edit: RunEdit<K>, context: RunEditContext): ChildEdit[] | null;
|
|
81
|
+
/** Whether this text is already in the state the job wants. If it already is, we leave it untouched */
|
|
82
|
+
export declare function matchesRunEdit<K extends EditableRunKey>(format: RunFormat | null, edit: RunEdit<K>): boolean;
|
|
83
|
+
/** The rPr with these children swapped in */
|
|
84
|
+
export declare function withChildEdits(rPr: Props, edits: readonly ChildEdit[]): Props;
|
|
85
|
+
/** Turning formatting on for a run with no formatting creates a minimal rPr from scratch */
|
|
86
|
+
export declare const EMPTY_RUN_PROPS: Props;
|
|
87
|
+
/**
|
|
88
|
+
* A whole rPr recording these settings, built from nothing, and null where they record nothing.
|
|
89
|
+
* A setting the document cannot record is left out, the way an edit refusing it leaves the run
|
|
90
|
+
* as it was.
|
|
91
|
+
*/
|
|
92
|
+
export declare function rPrOf(settings: RunSettings): string | null;
|
|
93
|
+
export {};
|