@portone/docx-editor 0.1.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 +7 -0
- package/CONTRIBUTING.md +63 -0
- package/LICENSE +203 -0
- package/README.md +48 -0
- package/assets/editor.png +0 -0
- package/dist/DocxEditor.d.ts +123 -0
- package/dist/DocxEditor.js +348 -0
- package/dist/core.d.ts +36 -0
- package/dist/core.js +38 -0
- package/dist/docx/comments/constants.d.ts +8 -0
- package/dist/docx/comments/constants.js +20 -0
- package/dist/docx/comments/model.d.ts +37 -0
- package/dist/docx/comments/model.js +104 -0
- package/dist/docx/comments/reading.d.ts +36 -0
- package/dist/docx/comments/reading.js +149 -0
- package/dist/docx/comments/writing.d.ts +11 -0
- package/dist/docx/comments/writing.js +327 -0
- package/dist/docx/comments.d.ts +3 -0
- package/dist/docx/comments.js +4 -0
- package/dist/docx/container.d.ts +12 -0
- package/dist/docx/container.js +130 -0
- package/dist/docx/documentSettings.d.ts +4 -0
- package/dist/docx/documentSettings.js +14 -0
- package/dist/docx/exportDocx.d.ts +15 -0
- package/dist/docx/exportDocx.js +163 -0
- package/dist/docx/exportRefs.d.ts +16 -0
- package/dist/docx/exportRefs.js +10 -0
- package/dist/docx/formatting/direct.d.ts +30 -0
- package/dist/docx/formatting/direct.js +201 -0
- package/dist/docx/formatting/effectiveParagraph.d.ts +15 -0
- package/dist/docx/formatting/effectiveParagraph.js +81 -0
- package/dist/docx/formatting/styles.d.ts +67 -0
- package/dist/docx/formatting/styles.js +165 -0
- package/dist/docx/formatting/tabStops.d.ts +8 -0
- package/dist/docx/formatting/tabStops.js +65 -0
- package/dist/docx/formatting.d.ts +4 -0
- package/dist/docx/formatting.js +4 -0
- package/dist/docx/headersFooters.d.ts +36 -0
- package/dist/docx/headersFooters.js +218 -0
- package/dist/docx/hyperlink.d.ts +75 -0
- package/dist/docx/hyperlink.js +71 -0
- package/dist/docx/importDocx.d.ts +21 -0
- package/dist/docx/importDocx.js +263 -0
- package/dist/docx/importParagraph.d.ts +32 -0
- package/dist/docx/importParagraph.js +308 -0
- package/dist/docx/importTable.d.ts +9 -0
- package/dist/docx/importTable.js +275 -0
- package/dist/docx/media.d.ts +60 -0
- package/dist/docx/media.js +213 -0
- package/dist/docx/notes.d.ts +22 -0
- package/dist/docx/notes.js +71 -0
- package/dist/docx/pageGeometry.d.ts +75 -0
- package/dist/docx/pageGeometry.js +88 -0
- package/dist/docx/paraProps.d.ts +74 -0
- package/dist/docx/paraProps.js +167 -0
- package/dist/docx/propsXml.d.ts +49 -0
- package/dist/docx/propsXml.js +302 -0
- package/dist/docx/relationships.d.ts +42 -0
- package/dist/docx/relationships.js +94 -0
- package/dist/docx/runProps.d.ts +51 -0
- package/dist/docx/runProps.js +207 -0
- package/dist/docx/scan.d.ts +20 -0
- package/dist/docx/scan.js +110 -0
- package/dist/docx/sdt.d.ts +56 -0
- package/dist/docx/sdt.js +104 -0
- package/dist/docx/sdtProps.d.ts +18 -0
- package/dist/docx/sdtProps.js +11 -0
- package/dist/docx/serializeBlock.d.ts +4 -0
- package/dist/docx/serializeBlock.js +30 -0
- package/dist/docx/serializeParagraph.d.ts +15 -0
- package/dist/docx/serializeParagraph.js +208 -0
- package/dist/docx/serializeTable.d.ts +12 -0
- package/dist/docx/serializeTable.js +134 -0
- package/dist/docx/session.d.ts +81 -0
- package/dist/docx/session.js +79 -0
- package/dist/docx/tableFormatting/editing.d.ts +64 -0
- package/dist/docx/tableFormatting/editing.js +318 -0
- package/dist/docx/tableFormatting/reading.d.ts +96 -0
- package/dist/docx/tableFormatting/reading.js +221 -0
- package/dist/docx/tableFormatting.d.ts +2 -0
- package/dist/docx/tableFormatting.js +3 -0
- package/dist/docx/tableTemplate.d.ts +22 -0
- package/dist/docx/tableTemplate.js +111 -0
- package/dist/docx/theme.d.ts +40 -0
- package/dist/docx/theme.js +61 -0
- package/dist/docx/uniqueControls.d.ts +14 -0
- package/dist/docx/uniqueControls.js +62 -0
- package/dist/download.d.ts +57 -0
- package/dist/download.js +44 -0
- package/dist/editor/clipboard/images.d.ts +14 -0
- package/dist/editor/clipboard/images.js +158 -0
- package/dist/editor/clipboard/inlineFormatting.d.ts +21 -0
- package/dist/editor/clipboard/inlineFormatting.js +232 -0
- package/dist/editor/commands/breakCommands.d.ts +8 -0
- package/dist/editor/commands/breakCommands.js +19 -0
- package/dist/editor/commands/canRunCommand.d.ts +6 -0
- package/dist/editor/commands/canRunCommand.js +10 -0
- package/dist/editor/commands/commentCommands.d.ts +3 -0
- package/dist/editor/commands/commentCommands.js +4 -0
- package/dist/editor/commands/comments/editing.d.ts +21 -0
- package/dist/editor/commands/comments/editing.js +305 -0
- package/dist/editor/commands/comments/model.d.ts +31 -0
- package/dist/editor/commands/comments/model.js +0 -0
- package/dist/editor/commands/comments/reading.d.ts +8 -0
- package/dist/editor/commands/comments/reading.js +58 -0
- package/dist/editor/commands/formatting/editing.d.ts +32 -0
- package/dist/editor/commands/formatting/editing.js +138 -0
- package/dist/editor/commands/formatting/reading.d.ts +57 -0
- package/dist/editor/commands/formatting/reading.js +82 -0
- package/dist/editor/commands/formatting/shared.d.ts +32 -0
- package/dist/editor/commands/formatting/shared.js +53 -0
- package/dist/editor/commands/formattingCommands.d.ts +2 -0
- package/dist/editor/commands/formattingCommands.js +3 -0
- package/dist/editor/commands/historyCommands.d.ts +11 -0
- package/dist/editor/commands/historyCommands.js +16 -0
- package/dist/editor/commands/indentCommands.d.ts +15 -0
- package/dist/editor/commands/indentCommands.js +44 -0
- package/dist/editor/commands/index.d.ts +82 -0
- package/dist/editor/commands/index.js +171 -0
- package/dist/editor/commands/linkCommands.d.ts +56 -0
- package/dist/editor/commands/linkCommands.js +146 -0
- package/dist/editor/commands/listCommands.d.ts +58 -0
- package/dist/editor/commands/listCommands.js +140 -0
- package/dist/editor/commands/lockCommands.d.ts +47 -0
- package/dist/editor/commands/lockCommands.js +198 -0
- package/dist/editor/commands/noteQueries.d.ts +12 -0
- package/dist/editor/commands/noteQueries.js +29 -0
- package/dist/editor/commands/paragraphCommands.d.ts +59 -0
- package/dist/editor/commands/paragraphCommands.js +113 -0
- package/dist/editor/commands/spacingCommands.d.ts +23 -0
- package/dist/editor/commands/spacingCommands.js +48 -0
- package/dist/editor/commands/tabCommands.d.ts +5 -0
- package/dist/editor/commands/tabCommands.js +65 -0
- package/dist/editor/createEditor.d.ts +59 -0
- package/dist/editor/createEditor.js +160 -0
- package/dist/editor/documentStyles.d.ts +60 -0
- package/dist/editor/documentStyles.js +80 -0
- package/dist/editor/externalClipboard.d.ts +11 -0
- package/dist/editor/externalClipboard.js +323 -0
- package/dist/editor/imageFiles.d.ts +74 -0
- package/dist/editor/imageFiles.js +173 -0
- package/dist/editor/insertImage.d.ts +31 -0
- package/dist/editor/insertImage.js +35 -0
- package/dist/editor/insertTable.d.ts +18 -0
- package/dist/editor/insertTable.js +44 -0
- package/dist/editor/paragraphEdits.d.ts +42 -0
- package/dist/editor/paragraphEdits.js +59 -0
- package/dist/editor/plainText.d.ts +3 -0
- package/dist/editor/plainText.js +50 -0
- package/dist/editor/plugins/bookmarkProtection.d.ts +3 -0
- package/dist/editor/plugins/bookmarkProtection.js +28 -0
- package/dist/editor/plugins/columnResize.d.ts +27 -0
- package/dist/editor/plugins/columnResize.js +192 -0
- package/dist/editor/plugins/commentDecorations.d.ts +3 -0
- package/dist/editor/plugins/commentDecorations.js +23 -0
- package/dist/editor/plugins/commentReservations.d.ts +5 -0
- package/dist/editor/plugins/commentReservations.js +26 -0
- package/dist/editor/plugins/dropCaret.d.ts +10 -0
- package/dist/editor/plugins/dropCaret.js +11 -0
- package/dist/editor/plugins/imagePaste.d.ts +8 -0
- package/dist/editor/plugins/imagePaste.js +265 -0
- package/dist/editor/plugins/keymap.d.ts +5 -0
- package/dist/editor/plugins/keymap.js +94 -0
- package/dist/editor/plugins/linkPanel.d.ts +23 -0
- package/dist/editor/plugins/linkPanel.js +39 -0
- package/dist/editor/plugins/listInputRules.d.ts +14 -0
- package/dist/editor/plugins/listInputRules.js +36 -0
- package/dist/editor/plugins/lockedContent.d.ts +6 -0
- package/dist/editor/plugins/lockedContent.js +41 -0
- package/dist/editor/plugins/noteProtection.d.ts +3 -0
- package/dist/editor/plugins/noteProtection.js +25 -0
- package/dist/editor/plugins/numberingDecorations.d.ts +42 -0
- package/dist/editor/plugins/numberingDecorations.js +110 -0
- package/dist/editor/plugins/rowResize.d.ts +15 -0
- package/dist/editor/plugins/rowResize.js +196 -0
- package/dist/editor/plugins/styledParagraphs.d.ts +15 -0
- package/dist/editor/plugins/styledParagraphs.js +65 -0
- package/dist/editor/plugins/tabCaret.d.ts +3 -0
- package/dist/editor/plugins/tabCaret.js +126 -0
- package/dist/editor/plugins/tabDecorations.d.ts +11 -0
- package/dist/editor/plugins/tabDecorations.js +87 -0
- package/dist/editor/plugins/tabLayout.d.ts +16 -0
- package/dist/editor/plugins/tabLayout.js +328 -0
- package/dist/editor/plugins/tabPointer.d.ts +7 -0
- package/dist/editor/plugins/tabPointer.js +95 -0
- package/dist/editor/plugins/tableContextMenu.d.ts +21 -0
- package/dist/editor/plugins/tableContextMenu.js +88 -0
- package/dist/editor/plugins/textContextMenu.d.ts +15 -0
- package/dist/editor/plugins/textContextMenu.js +90 -0
- package/dist/editor/views/imageResize.d.ts +53 -0
- package/dist/editor/views/imageResize.js +167 -0
- package/dist/editor/views/runMarkView.d.ts +15 -0
- package/dist/editor/views/runMarkView.js +9 -0
- package/dist/editor/views/tableView.d.ts +24 -0
- package/dist/editor/views/tableView.js +32 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +38 -0
- package/dist/model/format.d.ts +240 -0
- package/dist/model/format.js +305 -0
- package/dist/model/tabStops.d.ts +17 -0
- package/dist/model/tabStops.js +22 -0
- package/dist/numbering/listTemplate.d.ts +29 -0
- package/dist/numbering/listTemplate.js +83 -0
- package/dist/numbering/markers.d.ts +24 -0
- package/dist/numbering/markers.js +93 -0
- package/dist/numbering/parseNumbering.d.ts +65 -0
- package/dist/numbering/parseNumbering.js +116 -0
- package/dist/numbering/writeNumbering.d.ts +13 -0
- package/dist/numbering/writeNumbering.js +49 -0
- package/dist/ooxml/errors.d.ts +39 -0
- package/dist/ooxml/errors.js +21 -0
- package/dist/ooxml/image.d.ts +88 -0
- package/dist/ooxml/image.js +106 -0
- package/dist/ooxml/tabStops.d.ts +3 -0
- package/dist/ooxml/tabStops.js +51 -0
- package/dist/ooxml/units.d.ts +37 -0
- package/dist/ooxml/units.js +116 -0
- package/dist/ooxml/xml.d.ts +36 -0
- package/dist/ooxml/xml.js +89 -0
- package/dist/page/PageGuides.d.ts +16 -0
- package/dist/page/PageGuides.js +114 -0
- package/dist/page/measureBlocks.d.ts +25 -0
- package/dist/page/measureBlocks.js +80 -0
- package/dist/page/pageDecorations.d.ts +36 -0
- package/dist/page/pageDecorations.js +211 -0
- package/dist/page/pageLayout.d.ts +176 -0
- package/dist/page/pageLayout.js +157 -0
- package/dist/page/tableMeasurements.d.ts +10 -0
- package/dist/page/tableMeasurements.js +115 -0
- package/dist/page/usePageLayout.d.ts +57 -0
- package/dist/page/usePageLayout.js +141 -0
- package/dist/schema/docxSchema.d.ts +9 -0
- package/dist/schema/docxSchema.js +863 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +9 -0
- package/dist/schema/locks.d.ts +112 -0
- package/dist/schema/locks.js +211 -0
- package/dist/schema/rendering.d.ts +6 -0
- package/dist/schema/rendering.js +46 -0
- package/dist/styles/classNames.d.ts +214 -0
- package/dist/styles/classNames.js +208 -0
- package/dist/styles/colors.d.ts +11 -0
- package/dist/styles/colors.js +14 -0
- package/dist/styles/fontSizes.d.ts +6 -0
- package/dist/styles/fontSizes.js +20 -0
- package/dist/styles/fontStack.d.ts +55 -0
- package/dist/styles/fontStack.js +262 -0
- package/dist/styles/fonts.d.ts +6 -0
- package/dist/styles/fonts.js +11 -0
- package/dist/styles/inlineStyle.d.ts +67 -0
- package/dist/styles/inlineStyle.js +212 -0
- package/dist/styles/lineSpacings.d.ts +11 -0
- package/dist/styles/lineSpacings.js +10 -0
- package/dist/styles.css +1650 -0
- package/dist/table/cellBorders.d.ts +12 -0
- package/dist/table/cellBorders.js +9 -0
- package/dist/table/cellFormatting.d.ts +57 -0
- package/dist/table/cellFormatting.js +173 -0
- package/dist/table/columns.d.ts +25 -0
- package/dist/table/columns.js +155 -0
- package/dist/table/commands.d.ts +19 -0
- package/dist/table/commands.js +63 -0
- package/dist/table/format.d.ts +35 -0
- package/dist/table/format.js +26 -0
- package/dist/table/gridBorders.d.ts +42 -0
- package/dist/table/gridBorders.js +192 -0
- package/dist/table/index.d.ts +16 -0
- package/dist/table/index.js +52 -0
- package/dist/table/merge.d.ts +36 -0
- package/dist/table/merge.js +125 -0
- package/dist/table/resize.d.ts +55 -0
- package/dist/table/resize.js +66 -0
- package/dist/table/rowResize.d.ts +14 -0
- package/dist/table/rowResize.js +44 -0
- package/dist/table/rows.d.ts +32 -0
- package/dist/table/rows.js +89 -0
- package/dist/table/widths.d.ts +69 -0
- package/dist/table/widths.js +97 -0
- package/dist/ui/AlignMenu.d.ts +15 -0
- package/dist/ui/AlignMenu.js +64 -0
- package/dist/ui/CellStyleGroup.d.ts +15 -0
- package/dist/ui/CellStyleGroup.js +232 -0
- package/dist/ui/ColorPicker.d.ts +13 -0
- package/dist/ui/ColorPicker.js +165 -0
- package/dist/ui/CommentsPanel.d.ts +15 -0
- package/dist/ui/CommentsPanel.js +348 -0
- package/dist/ui/FontFamilySelect.d.ts +14 -0
- package/dist/ui/FontFamilySelect.js +59 -0
- package/dist/ui/FontSizeSelect.d.ts +11 -0
- package/dist/ui/FontSizeSelect.js +49 -0
- package/dist/ui/InsertImageButton.d.ts +9 -0
- package/dist/ui/InsertImageButton.js +47 -0
- package/dist/ui/LinkCard.d.ts +12 -0
- package/dist/ui/LinkCard.js +127 -0
- package/dist/ui/LinkPanel.d.ts +9 -0
- package/dist/ui/LinkPanel.js +121 -0
- package/dist/ui/MenuChoice.d.ts +11 -0
- package/dist/ui/MenuChoice.js +32 -0
- package/dist/ui/NotesPanel.d.ts +6 -0
- package/dist/ui/NotesPanel.js +33 -0
- package/dist/ui/ParagraphStyleSelect.d.ts +11 -0
- package/dist/ui/ParagraphStyleSelect.js +62 -0
- package/dist/ui/Popover.d.ts +22 -0
- package/dist/ui/Popover.js +74 -0
- package/dist/ui/SpacingMenu.d.ts +12 -0
- package/dist/ui/SpacingMenu.js +54 -0
- package/dist/ui/TableMenu.d.ts +12 -0
- package/dist/ui/TableMenu.js +112 -0
- package/dist/ui/TableSizePicker.d.ts +9 -0
- package/dist/ui/TableSizePicker.js +53 -0
- package/dist/ui/TextMenu.d.ts +15 -0
- package/dist/ui/TextMenu.js +194 -0
- package/dist/ui/Toolbar.d.ts +19 -0
- package/dist/ui/Toolbar.js +448 -0
- package/dist/ui/ToolbarButton.d.ts +23 -0
- package/dist/ui/ToolbarButton.js +56 -0
- package/dist/ui/Tooltip.d.ts +19 -0
- package/dist/ui/Tooltip.js +47 -0
- package/dist/ui/ZoomSelect.d.ts +7 -0
- package/dist/ui/ZoomSelect.js +44 -0
- package/dist/ui/comments/CommentComposer.d.ts +17 -0
- package/dist/ui/comments/CommentComposer.js +59 -0
- package/dist/ui/comments/useCommentRailLayout.d.ts +18 -0
- package/dist/ui/comments/useCommentRailLayout.js +183 -0
- package/dist/ui/keyboardWalk.d.ts +22 -0
- package/dist/ui/keyboardWalk.js +70 -0
- package/dist/ui/openAddress.d.ts +11 -0
- package/dist/ui/openAddress.js +16 -0
- package/dist/ui/panelPlacement.d.ts +51 -0
- package/dist/ui/panelPlacement.js +71 -0
- package/dist/ui/presets.d.ts +11 -0
- package/dist/ui/presets.js +0 -0
- package/dist/ui/rovingFocus.d.ts +20 -0
- package/dist/ui/rovingFocus.js +61 -0
- package/dist/ui/runCommand.d.ts +5 -0
- package/dist/ui/runCommand.js +13 -0
- package/dist/ui/useDismiss.d.ts +6 -0
- package/dist/ui/useDismiss.js +31 -0
- package/dist/ui/useFitWidthZoom.d.ts +2 -0
- package/dist/ui/useFitWidthZoom.js +26 -0
- package/dist/ui/useGridKeyboard.d.ts +12 -0
- package/dist/ui/useGridKeyboard.js +90 -0
- package/dist/ui/useMenuKeyboard.d.ts +12 -0
- package/dist/ui/useMenuKeyboard.js +56 -0
- package/dist/ui/zoom.d.ts +4 -0
- package/dist/ui/zoom.js +21 -0
- package/package.json +120 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// src/docx/propsXml.ts
|
|
2
|
+
import { elementChildren, localPart, parseXml, W_NS } from "../ooxml/xml.js";
|
|
3
|
+
var RUN_PR_ORDER = [
|
|
4
|
+
"rStyle",
|
|
5
|
+
"rFonts",
|
|
6
|
+
"b",
|
|
7
|
+
"bCs",
|
|
8
|
+
"i",
|
|
9
|
+
"iCs",
|
|
10
|
+
"caps",
|
|
11
|
+
"smallCaps",
|
|
12
|
+
"strike",
|
|
13
|
+
"dstrike",
|
|
14
|
+
"outline",
|
|
15
|
+
"shadow",
|
|
16
|
+
"emboss",
|
|
17
|
+
"imprint",
|
|
18
|
+
"noProof",
|
|
19
|
+
"snapToGrid",
|
|
20
|
+
"vanish",
|
|
21
|
+
"webHidden",
|
|
22
|
+
"color",
|
|
23
|
+
"spacing",
|
|
24
|
+
"w",
|
|
25
|
+
"kern",
|
|
26
|
+
"position",
|
|
27
|
+
"sz",
|
|
28
|
+
"szCs",
|
|
29
|
+
"highlight",
|
|
30
|
+
"u",
|
|
31
|
+
"effect",
|
|
32
|
+
"bdr",
|
|
33
|
+
"shd",
|
|
34
|
+
"fitText",
|
|
35
|
+
"vertAlign",
|
|
36
|
+
"rtl",
|
|
37
|
+
"cs",
|
|
38
|
+
"em",
|
|
39
|
+
"lang",
|
|
40
|
+
"eastAsianLayout",
|
|
41
|
+
"specVanish",
|
|
42
|
+
"oMath",
|
|
43
|
+
"rPrChange"
|
|
44
|
+
];
|
|
45
|
+
var P_PR_ORDER = [
|
|
46
|
+
"pStyle",
|
|
47
|
+
"keepNext",
|
|
48
|
+
"keepLines",
|
|
49
|
+
"pageBreakBefore",
|
|
50
|
+
"framePr",
|
|
51
|
+
"widowControl",
|
|
52
|
+
"numPr",
|
|
53
|
+
"suppressLineNumbers",
|
|
54
|
+
"pBdr",
|
|
55
|
+
"shd",
|
|
56
|
+
"tabs",
|
|
57
|
+
"suppressAutoHyphens",
|
|
58
|
+
"kinsoku",
|
|
59
|
+
"wordWrap",
|
|
60
|
+
"overflowPunct",
|
|
61
|
+
"topLinePunct",
|
|
62
|
+
"autoSpaceDE",
|
|
63
|
+
"autoSpaceDN",
|
|
64
|
+
"bidi",
|
|
65
|
+
"adjustRightInd",
|
|
66
|
+
"snapToGrid",
|
|
67
|
+
"spacing",
|
|
68
|
+
"ind",
|
|
69
|
+
"contextualSpacing",
|
|
70
|
+
"mirrorIndents",
|
|
71
|
+
"suppressOverlap",
|
|
72
|
+
"jc",
|
|
73
|
+
"textDirection",
|
|
74
|
+
"textAlignment",
|
|
75
|
+
"textboxTightWrap",
|
|
76
|
+
"outlineLvl",
|
|
77
|
+
"divId",
|
|
78
|
+
"cnfStyle",
|
|
79
|
+
"rPr",
|
|
80
|
+
"sectPr",
|
|
81
|
+
"pPrChange"
|
|
82
|
+
];
|
|
83
|
+
var TC_PR_ORDER = [
|
|
84
|
+
"cnfStyle",
|
|
85
|
+
"tcW",
|
|
86
|
+
"gridSpan",
|
|
87
|
+
"hMerge",
|
|
88
|
+
"vMerge",
|
|
89
|
+
"tcBorders",
|
|
90
|
+
"shd",
|
|
91
|
+
"noWrap",
|
|
92
|
+
"tcMar",
|
|
93
|
+
"textDirection",
|
|
94
|
+
"tcFitText",
|
|
95
|
+
"vAlign",
|
|
96
|
+
"hideMark",
|
|
97
|
+
"headers",
|
|
98
|
+
"cellIns",
|
|
99
|
+
"cellDel",
|
|
100
|
+
"cellMerge",
|
|
101
|
+
"tcPrChange"
|
|
102
|
+
];
|
|
103
|
+
var TR_PR_ORDER = [
|
|
104
|
+
"cnfStyle",
|
|
105
|
+
"divId",
|
|
106
|
+
"gridBefore",
|
|
107
|
+
"gridAfter",
|
|
108
|
+
"wBefore",
|
|
109
|
+
"wAfter",
|
|
110
|
+
"cantSplit",
|
|
111
|
+
"trHeight",
|
|
112
|
+
"tblHeader",
|
|
113
|
+
"tblCellSpacing",
|
|
114
|
+
"jc",
|
|
115
|
+
"hidden",
|
|
116
|
+
"ins",
|
|
117
|
+
"del",
|
|
118
|
+
"trPrChange"
|
|
119
|
+
];
|
|
120
|
+
var TBL_PR_ORDER = [
|
|
121
|
+
"tblStyle",
|
|
122
|
+
"tblpPr",
|
|
123
|
+
"tblOverlap",
|
|
124
|
+
"bidiVisual",
|
|
125
|
+
"tblStyleRowBandSize",
|
|
126
|
+
"tblStyleColBandSize",
|
|
127
|
+
"tblW",
|
|
128
|
+
"jc",
|
|
129
|
+
"tblCellSpacing",
|
|
130
|
+
"tblInd",
|
|
131
|
+
"tblBorders",
|
|
132
|
+
"shd",
|
|
133
|
+
"tblLayout",
|
|
134
|
+
"tblCellMar",
|
|
135
|
+
"tblLook",
|
|
136
|
+
"tblCaption",
|
|
137
|
+
"tblDescription",
|
|
138
|
+
"tblPrChange"
|
|
139
|
+
];
|
|
140
|
+
function skipPast(source, from, marker) {
|
|
141
|
+
const at = source.indexOf(marker, from);
|
|
142
|
+
return at === -1 ? -1 : at + marker.length;
|
|
143
|
+
}
|
|
144
|
+
function otherTag(end) {
|
|
145
|
+
return end === -1 ? null : { kind: "other", name: "", nameEnd: end, end };
|
|
146
|
+
}
|
|
147
|
+
function readTag(source, lt) {
|
|
148
|
+
if (source.startsWith("<?", lt)) return otherTag(skipPast(source, lt, "?>"));
|
|
149
|
+
if (source.startsWith("<!--", lt))
|
|
150
|
+
return otherTag(skipPast(source, lt, "-->"));
|
|
151
|
+
if (source.startsWith("<![CDATA[", lt))
|
|
152
|
+
return otherTag(skipPast(source, lt, "]]>"));
|
|
153
|
+
if (source.startsWith("<!", lt)) return otherTag(skipPast(source, lt, ">"));
|
|
154
|
+
const closing = source.startsWith("</", lt);
|
|
155
|
+
let i = lt + (closing ? 2 : 1);
|
|
156
|
+
const nameStart = i;
|
|
157
|
+
while (i < source.length && !" \r\n/>".includes(source[i])) i += 1;
|
|
158
|
+
const name = source.slice(nameStart, i);
|
|
159
|
+
if (!name) return null;
|
|
160
|
+
const nameEnd = i;
|
|
161
|
+
let quote = null;
|
|
162
|
+
while (i < source.length) {
|
|
163
|
+
const ch = source[i];
|
|
164
|
+
if (quote !== null) {
|
|
165
|
+
if (ch === quote) quote = null;
|
|
166
|
+
} else if (ch === '"' || ch === "'") {
|
|
167
|
+
quote = ch;
|
|
168
|
+
} else if (ch === ">") {
|
|
169
|
+
const selfClosing = source[i - 1] === "/";
|
|
170
|
+
const kind = closing ? "close" : selfClosing ? "empty" : "open";
|
|
171
|
+
return { kind, name, nameEnd, end: i + 1 };
|
|
172
|
+
}
|
|
173
|
+
i += 1;
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
function attrsOf(source, tag) {
|
|
178
|
+
const closeLength = tag.kind === "empty" ? 2 : 1;
|
|
179
|
+
const attrs = source.slice(tag.nameEnd, tag.end - closeLength).trim();
|
|
180
|
+
return attrs.length > 0 ? attrs : null;
|
|
181
|
+
}
|
|
182
|
+
function parseProps(xml) {
|
|
183
|
+
const open = readTag(xml, 0);
|
|
184
|
+
if (!open || xml[0] !== "<") return null;
|
|
185
|
+
const attrs = attrsOf(xml, open);
|
|
186
|
+
if (open.kind === "empty") {
|
|
187
|
+
return open.end === xml.length ? { tag: open.name, attrs, children: [] } : null;
|
|
188
|
+
}
|
|
189
|
+
if (open.kind !== "open") return null;
|
|
190
|
+
const children = [];
|
|
191
|
+
let depth = 0;
|
|
192
|
+
let childStart = -1;
|
|
193
|
+
let childName = "";
|
|
194
|
+
let i = open.end;
|
|
195
|
+
while (i < xml.length) {
|
|
196
|
+
const lt = xml.indexOf("<", i);
|
|
197
|
+
if (lt === -1) return null;
|
|
198
|
+
const tag = readTag(xml, lt);
|
|
199
|
+
if (!tag) return null;
|
|
200
|
+
if (tag.kind === "other") {
|
|
201
|
+
i = tag.end;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (depth === 0) {
|
|
205
|
+
if (tag.kind === "close") {
|
|
206
|
+
if (tag.name !== open.name || tag.end !== xml.length) return null;
|
|
207
|
+
return { tag: open.name, attrs, children };
|
|
208
|
+
}
|
|
209
|
+
childStart = lt;
|
|
210
|
+
childName = tag.name;
|
|
211
|
+
if (tag.kind === "empty") {
|
|
212
|
+
children.push({
|
|
213
|
+
name: localPart(childName),
|
|
214
|
+
xml: xml.slice(childStart, tag.end)
|
|
215
|
+
});
|
|
216
|
+
} else {
|
|
217
|
+
depth = 1;
|
|
218
|
+
}
|
|
219
|
+
} else if (tag.kind === "open") {
|
|
220
|
+
depth += 1;
|
|
221
|
+
} else if (tag.kind === "close") {
|
|
222
|
+
depth -= 1;
|
|
223
|
+
if (depth === 0) {
|
|
224
|
+
children.push({
|
|
225
|
+
name: localPart(childName),
|
|
226
|
+
xml: xml.slice(childStart, tag.end)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
i = tag.end;
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
function renderProps(props) {
|
|
235
|
+
if (props.children.length === 0) return "";
|
|
236
|
+
const open = props.attrs ? `<${props.tag} ${props.attrs}>` : `<${props.tag}>`;
|
|
237
|
+
return open + props.children.map((child) => child.xml).join("") + `</${props.tag}>`;
|
|
238
|
+
}
|
|
239
|
+
function insertIndex(children, name, order) {
|
|
240
|
+
const target = order.indexOf(name);
|
|
241
|
+
if (target === -1) return children.length;
|
|
242
|
+
let previous = -1;
|
|
243
|
+
for (const [index, child] of children.entries()) {
|
|
244
|
+
const known = order.indexOf(child.name);
|
|
245
|
+
const effective = known === -1 ? previous : known;
|
|
246
|
+
if (effective > target) return index;
|
|
247
|
+
previous = effective;
|
|
248
|
+
}
|
|
249
|
+
return children.length;
|
|
250
|
+
}
|
|
251
|
+
function setPropsChild(children, name, xml, order) {
|
|
252
|
+
const without = children.filter((child2) => child2.name !== name);
|
|
253
|
+
if (xml === null) return without;
|
|
254
|
+
const child = { name, xml };
|
|
255
|
+
const at = children.findIndex((entry) => entry.name === name);
|
|
256
|
+
if (at === -1) {
|
|
257
|
+
const index = insertIndex(without, name, order);
|
|
258
|
+
return [...without.slice(0, index), child, ...without.slice(index)];
|
|
259
|
+
}
|
|
260
|
+
return [
|
|
261
|
+
...children.slice(0, at),
|
|
262
|
+
child,
|
|
263
|
+
...children.slice(at + 1).filter((entry) => entry.name !== name)
|
|
264
|
+
];
|
|
265
|
+
}
|
|
266
|
+
function propsChild(children, name) {
|
|
267
|
+
return children.find((child) => child.name === name);
|
|
268
|
+
}
|
|
269
|
+
function namespaceDecls(xml) {
|
|
270
|
+
const prefixes = /* @__PURE__ */ new Set(["w"]);
|
|
271
|
+
for (const [, prefix] of xml.matchAll(/<\/?([A-Za-z_][\w.-]*):/g)) {
|
|
272
|
+
prefixes.add(prefix);
|
|
273
|
+
}
|
|
274
|
+
for (const [, prefix] of xml.matchAll(/[\s"']([A-Za-z_][\w.-]*):[\w.-]+=/g)) {
|
|
275
|
+
prefixes.add(prefix);
|
|
276
|
+
}
|
|
277
|
+
prefixes.delete("xml");
|
|
278
|
+
prefixes.delete("xmlns");
|
|
279
|
+
return Array.from(prefixes).map(
|
|
280
|
+
(prefix) => `xmlns:${prefix}="${prefix === "w" ? W_NS : `urn:docx-editor:${prefix}`}"`
|
|
281
|
+
).join(" ");
|
|
282
|
+
}
|
|
283
|
+
function parsePropsXml(xml) {
|
|
284
|
+
try {
|
|
285
|
+
const wrapped = `<props ${namespaceDecls(xml)}>${xml}</props>`;
|
|
286
|
+
return elementChildren(parseXml(wrapped).documentElement)[0] ?? null;
|
|
287
|
+
} catch {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
export {
|
|
292
|
+
P_PR_ORDER,
|
|
293
|
+
RUN_PR_ORDER,
|
|
294
|
+
TBL_PR_ORDER,
|
|
295
|
+
TC_PR_ORDER,
|
|
296
|
+
TR_PR_ORDER,
|
|
297
|
+
parseProps,
|
|
298
|
+
parsePropsXml,
|
|
299
|
+
propsChild,
|
|
300
|
+
renderProps,
|
|
301
|
+
setPropsChild
|
|
302
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The relationships part beside the body: what it already declares, and what an export adds.
|
|
3
|
+
*
|
|
4
|
+
* An addition is spliced in ahead of the closing tag and the original text is left exactly as it
|
|
5
|
+
* came, so a package the editor only added to keeps every byte it arrived with.
|
|
6
|
+
*
|
|
7
|
+
* Both writers that need a relationship come through here, and they share the ids: an image points
|
|
8
|
+
* at a part inside the package (`docx/media`), a hyperlink at an address outside it, which is what
|
|
9
|
+
* `TargetMode="External"` says (`docx/hyperlink`). Two writers handing out ids of their own would
|
|
10
|
+
* hand out the same one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function directoryOf(partPath: string): string;
|
|
13
|
+
export declare function relsPathOf(partPath: string): string;
|
|
14
|
+
/** A relationship target resolved against the part that declares it */
|
|
15
|
+
export declare function resolveTarget(partPath: string, target: string): string;
|
|
16
|
+
export interface Relationship {
|
|
17
|
+
id: string;
|
|
18
|
+
type: string;
|
|
19
|
+
target: string;
|
|
20
|
+
/** Set when the target is a file outside the package */
|
|
21
|
+
external: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function readRelationships(parts: Map<string, Uint8Array>, relsPath: string): Relationship[];
|
|
24
|
+
/** A relationship an export puts in. The target is escaped here, so hand it in as it reads */
|
|
25
|
+
export interface NewRelationship {
|
|
26
|
+
type: string;
|
|
27
|
+
target: string;
|
|
28
|
+
/** Whether the target lies outside the package, which is every address a hyperlink names */
|
|
29
|
+
external?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface RelationshipWriter {
|
|
32
|
+
/** Every relationship the part declared when the document was opened */
|
|
33
|
+
readonly opened: readonly Relationship[];
|
|
34
|
+
/** Puts one in and hands back the id it went in under */
|
|
35
|
+
add(relationship: NewRelationship): string;
|
|
36
|
+
/**
|
|
37
|
+
* The part with everything added, built from the original text. null when nothing was added,
|
|
38
|
+
* which is what leaves the part out of the export altogether.
|
|
39
|
+
*/
|
|
40
|
+
part(original: Uint8Array | undefined): Uint8Array | null;
|
|
41
|
+
}
|
|
42
|
+
export declare function relationshipWriter(opened: readonly Relationship[]): RelationshipWriter;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/docx/relationships.ts
|
|
2
|
+
import { DocxExportError } from "../ooxml/errors.js";
|
|
3
|
+
import {
|
|
4
|
+
decodeUtf8,
|
|
5
|
+
elementChildren,
|
|
6
|
+
encodeUtf8,
|
|
7
|
+
escapeXml,
|
|
8
|
+
parseXml
|
|
9
|
+
} from "../ooxml/xml.js";
|
|
10
|
+
var RELATIONSHIPS_NS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
11
|
+
function directoryOf(partPath) {
|
|
12
|
+
return partPath.replace(/[^/]+$/, "");
|
|
13
|
+
}
|
|
14
|
+
function relsPathOf(partPath) {
|
|
15
|
+
const directory = directoryOf(partPath);
|
|
16
|
+
return `${directory}_rels/${partPath.slice(directory.length)}.rels`;
|
|
17
|
+
}
|
|
18
|
+
function resolveTarget(partPath, target) {
|
|
19
|
+
const combined = target.startsWith("/") ? target.slice(1) : directoryOf(partPath) + target;
|
|
20
|
+
const segments = [];
|
|
21
|
+
for (const segment of combined.split("/")) {
|
|
22
|
+
if (!segment || segment === ".") continue;
|
|
23
|
+
if (segment === "..") {
|
|
24
|
+
segments.pop();
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
segments.push(segment);
|
|
28
|
+
}
|
|
29
|
+
return segments.join("/");
|
|
30
|
+
}
|
|
31
|
+
function readRelationships(parts, relsPath) {
|
|
32
|
+
const bytes = parts.get(relsPath);
|
|
33
|
+
if (!bytes) return [];
|
|
34
|
+
return elementChildren(parseXml(decodeUtf8(bytes).text).documentElement).filter((el) => el.localName === "Relationship").map((el) => ({
|
|
35
|
+
id: el.getAttribute("Id") ?? "",
|
|
36
|
+
type: el.getAttribute("Type") ?? "",
|
|
37
|
+
target: el.getAttribute("Target") ?? "",
|
|
38
|
+
external: el.getAttribute("TargetMode") === "External"
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
function takeRelId(taken) {
|
|
42
|
+
for (let number = taken.size + 1; ; number += 1) {
|
|
43
|
+
const id = `rId${number}`;
|
|
44
|
+
if (!taken.has(id)) {
|
|
45
|
+
taken.add(id);
|
|
46
|
+
return id;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function relationshipXml(added) {
|
|
51
|
+
const mode = added.external ? ' TargetMode="External"' : "";
|
|
52
|
+
return `<Relationship Id="${added.id}" Type="${added.type}" Target="${escapeXml(added.target)}"${mode}/>`;
|
|
53
|
+
}
|
|
54
|
+
function relationshipsPart(original, added) {
|
|
55
|
+
const entries = added.map(relationshipXml).join("");
|
|
56
|
+
if (!original) {
|
|
57
|
+
return encodeUtf8(
|
|
58
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="${RELATIONSHIPS_NS}">${entries}</Relationships>`,
|
|
59
|
+
false
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const { text, hadBom } = decodeUtf8(original);
|
|
63
|
+
const closing = text.lastIndexOf("</Relationships>");
|
|
64
|
+
if (closing === -1) {
|
|
65
|
+
throw new DocxExportError(
|
|
66
|
+
"malformed-xml",
|
|
67
|
+
"the relationships part has no closing tag"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return encodeUtf8(
|
|
71
|
+
text.slice(0, closing) + entries + text.slice(closing),
|
|
72
|
+
hadBom
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
function relationshipWriter(opened) {
|
|
76
|
+
const taken = new Set(opened.map((relationship) => relationship.id));
|
|
77
|
+
const added = [];
|
|
78
|
+
return {
|
|
79
|
+
opened,
|
|
80
|
+
add: (relationship) => {
|
|
81
|
+
const id = takeRelId(taken);
|
|
82
|
+
added.push({ ...relationship, id });
|
|
83
|
+
return id;
|
|
84
|
+
},
|
|
85
|
+
part: (original) => added.length === 0 ? null : relationshipsPart(original, added)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
directoryOf,
|
|
90
|
+
readRelationships,
|
|
91
|
+
relationshipWriter,
|
|
92
|
+
relsPathOf,
|
|
93
|
+
resolveTarget
|
|
94
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Changes the character formatting XML (`<w:rPr>`) one item at a time.
|
|
3
|
+
*
|
|
4
|
+
* Turning bold on and off must not lose the other formatting that run wrote down (fonts, shading,
|
|
5
|
+
* even things we do not know about). So instead of building a new fragment we swap out just the one
|
|
6
|
+
* child. It is the same principle `tableFormatting` applies to `w:tcPr`.
|
|
7
|
+
*
|
|
8
|
+
* The display values produced here are used on screen only. What goes back into the document is
|
|
9
|
+
* always the rPr string.
|
|
10
|
+
*/
|
|
11
|
+
import { type RunFormat } from "../model/format";
|
|
12
|
+
/** The character formatting that is toggled on and off */
|
|
13
|
+
export type RunToggle = "bold" | "italic" | "underline" | "strike";
|
|
14
|
+
/** A job that changes one piece of character formatting. A null value means withdrawing the setting */
|
|
15
|
+
export type RunEdit = {
|
|
16
|
+
kind: "toggle";
|
|
17
|
+
toggle: RunToggle;
|
|
18
|
+
on: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
kind: "fontSize";
|
|
21
|
+
pt: number | null;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "fontFamily";
|
|
24
|
+
name: string | null;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "color";
|
|
27
|
+
hex: string | null;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "background";
|
|
30
|
+
hex: string | null;
|
|
31
|
+
};
|
|
32
|
+
/** The formatting a run holds. The original XML and the display values derived from that XML form a pair */
|
|
33
|
+
export interface RunProps {
|
|
34
|
+
/** The whole `<w:rPr>...</w:rPr>` XML. null for a run with no formatting */
|
|
35
|
+
rPr: string | null;
|
|
36
|
+
format: RunFormat | null;
|
|
37
|
+
}
|
|
38
|
+
/** Derives the display values again from the rPr we operated on. The same rPr always yields the same display values */
|
|
39
|
+
export declare function readRunProps(rPr: string | null): RunFormat | null;
|
|
40
|
+
/**
|
|
41
|
+
* The rPr and display values after changing one piece of character formatting.
|
|
42
|
+
*
|
|
43
|
+
* `pPr` is used only to see whether the paragraph points at a style.
|
|
44
|
+
* null for an rPr whose shape could not be made out, or for a value that cannot be written into
|
|
45
|
+
* the document, in which case the original is left untouched.
|
|
46
|
+
*/
|
|
47
|
+
export declare function editRunProps(current: RunProps, pPr: string | null, edit: RunEdit): RunProps | null;
|
|
48
|
+
/** Whether one of the toggled formats is on in these display values */
|
|
49
|
+
export declare function isRunToggleOn(format: RunFormat | null, toggle: RunToggle): boolean;
|
|
50
|
+
/** Whether this text is already in the state the job wants. If it already is, we leave it untouched */
|
|
51
|
+
export declare function matchesRunEdit(format: RunFormat | null, edit: RunEdit): boolean;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// src/docx/runProps.ts
|
|
2
|
+
import { toRunFormat } from "../model/format.js";
|
|
3
|
+
import { normalizeHex } from "../ooxml/units.js";
|
|
4
|
+
import { escapeXml, localPart } from "../ooxml/xml.js";
|
|
5
|
+
import { isEastAsianFontName } from "../styles/fontStack.js";
|
|
6
|
+
import { fontNamesOf, readRunFormat } from "./formatting.js";
|
|
7
|
+
import {
|
|
8
|
+
parseProps,
|
|
9
|
+
parsePropsXml,
|
|
10
|
+
propsChild,
|
|
11
|
+
RUN_PR_ORDER,
|
|
12
|
+
renderProps,
|
|
13
|
+
setPropsChild
|
|
14
|
+
} from "./propsXml.js";
|
|
15
|
+
import { THEME_ATTRS } from "./theme.js";
|
|
16
|
+
var TOGGLE_CHILDREN = {
|
|
17
|
+
bold: ["b", "bCs"],
|
|
18
|
+
italic: ["i", "iCs"],
|
|
19
|
+
underline: ["u"],
|
|
20
|
+
strike: ["strike"]
|
|
21
|
+
};
|
|
22
|
+
var TOGGLE_ON_VALUE = {
|
|
23
|
+
bold: null,
|
|
24
|
+
italic: null,
|
|
25
|
+
underline: "single",
|
|
26
|
+
strike: null
|
|
27
|
+
};
|
|
28
|
+
var TOGGLE_OFF_VALUE = {
|
|
29
|
+
bold: "0",
|
|
30
|
+
italic: "0",
|
|
31
|
+
underline: "none",
|
|
32
|
+
strike: "0"
|
|
33
|
+
};
|
|
34
|
+
var MAX_FONT_SIZE_PT = 819;
|
|
35
|
+
function elementXml(name, value) {
|
|
36
|
+
return value === null ? `<w:${name}/>` : `<w:${name} w:val="${value}"/>`;
|
|
37
|
+
}
|
|
38
|
+
function shadingXml(fill) {
|
|
39
|
+
return `<w:shd w:val="clear" w:color="auto" w:fill="${fill}"/>`;
|
|
40
|
+
}
|
|
41
|
+
function halfPoints(pt) {
|
|
42
|
+
if (!Number.isFinite(pt) || pt <= 0 || pt > MAX_FONT_SIZE_PT) return null;
|
|
43
|
+
const half = pt * 2;
|
|
44
|
+
return Number.isInteger(half) ? half : null;
|
|
45
|
+
}
|
|
46
|
+
var LATIN_SLOTS = ["ascii", "hAnsi"];
|
|
47
|
+
var EAST_ASIAN_SLOTS = [...LATIN_SLOTS, "eastAsia"];
|
|
48
|
+
function fontSlots(name, hasComplexScript) {
|
|
49
|
+
const slots = isEastAsianFontName(name) ? EAST_ASIAN_SLOTS : LATIN_SLOTS;
|
|
50
|
+
return hasComplexScript ? [...slots, "cs"] : slots;
|
|
51
|
+
}
|
|
52
|
+
function fontName(value) {
|
|
53
|
+
const name = value.trim();
|
|
54
|
+
return name.length > 0 && !/["';<>&]/.test(name) ? name : null;
|
|
55
|
+
}
|
|
56
|
+
function rFontsAttrs(xml) {
|
|
57
|
+
if (xml === null) return [];
|
|
58
|
+
const el = parsePropsXml(xml);
|
|
59
|
+
if (!el) return null;
|
|
60
|
+
return Array.from(el.attributes, (attr) => [
|
|
61
|
+
attr.name,
|
|
62
|
+
attr.value
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
function rFontsXml(current, name) {
|
|
66
|
+
const attrs = rFontsAttrs(current);
|
|
67
|
+
if (!attrs) return null;
|
|
68
|
+
const slots = fontSlots(
|
|
69
|
+
name,
|
|
70
|
+
attrs.some(([attr]) => localPart(attr) === "cs")
|
|
71
|
+
);
|
|
72
|
+
const dropped = slots.flatMap((slot) => [slot, ...THEME_ATTRS[slot] ?? []]);
|
|
73
|
+
const kept = attrs.filter(([attr]) => !dropped.includes(localPart(attr)));
|
|
74
|
+
const text = [
|
|
75
|
+
...slots.map((slot) => [`w:${slot}`, name]),
|
|
76
|
+
...kept
|
|
77
|
+
].map(([attr, value]) => `${attr}="${escapeXml(value)}"`).join(" ");
|
|
78
|
+
return `<w:rFonts ${text}/>`;
|
|
79
|
+
}
|
|
80
|
+
function hasChild(xml, name) {
|
|
81
|
+
if (xml === null) return false;
|
|
82
|
+
const props = parseProps(xml);
|
|
83
|
+
return props !== null && propsChild(props.children, name) !== void 0;
|
|
84
|
+
}
|
|
85
|
+
function propsOf(rPr) {
|
|
86
|
+
if (rPr === null) return { tag: "w:rPr", attrs: null, children: [] };
|
|
87
|
+
return parseProps(rPr);
|
|
88
|
+
}
|
|
89
|
+
function offEdit(name, value, inherited) {
|
|
90
|
+
return [name, inherited ? elementXml(name, value) : null];
|
|
91
|
+
}
|
|
92
|
+
function childEdits(edit, inherited, rFonts) {
|
|
93
|
+
switch (edit.kind) {
|
|
94
|
+
case "toggle": {
|
|
95
|
+
const names = TOGGLE_CHILDREN[edit.toggle];
|
|
96
|
+
if (edit.on) {
|
|
97
|
+
const value = TOGGLE_ON_VALUE[edit.toggle];
|
|
98
|
+
return names.map((name) => [name, elementXml(name, value)]);
|
|
99
|
+
}
|
|
100
|
+
const off = TOGGLE_OFF_VALUE[edit.toggle];
|
|
101
|
+
return names.map((name) => offEdit(name, off, inherited));
|
|
102
|
+
}
|
|
103
|
+
case "fontSize": {
|
|
104
|
+
if (edit.pt === null) {
|
|
105
|
+
return [
|
|
106
|
+
["sz", null],
|
|
107
|
+
["szCs", null]
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
const half = halfPoints(edit.pt);
|
|
111
|
+
if (half === null) return null;
|
|
112
|
+
return [
|
|
113
|
+
["sz", elementXml("sz", `${half}`)],
|
|
114
|
+
["szCs", elementXml("szCs", `${half}`)]
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
case "fontFamily": {
|
|
118
|
+
if (edit.name === null) return [["rFonts", null]];
|
|
119
|
+
const name = fontName(edit.name);
|
|
120
|
+
if (name === null) return null;
|
|
121
|
+
const xml = rFontsXml(rFonts, name);
|
|
122
|
+
return xml === null ? null : [["rFonts", xml]];
|
|
123
|
+
}
|
|
124
|
+
case "color": {
|
|
125
|
+
if (edit.hex === null) return [offEdit("color", "auto", inherited)];
|
|
126
|
+
const hex = normalizeHex(edit.hex);
|
|
127
|
+
return hex === null ? null : [["color", elementXml("color", hex)]];
|
|
128
|
+
}
|
|
129
|
+
case "background": {
|
|
130
|
+
const highlight = offEdit("highlight", "none", inherited);
|
|
131
|
+
if (edit.hex === null) {
|
|
132
|
+
return [["shd", inherited ? shadingXml("auto") : null], highlight];
|
|
133
|
+
}
|
|
134
|
+
const hex = normalizeHex(edit.hex);
|
|
135
|
+
return hex === null ? null : [["shd", shadingXml(hex)], highlight];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function readRunProps(rPr) {
|
|
140
|
+
return rPr === null ? null : readRunFormat(parsePropsXml(rPr));
|
|
141
|
+
}
|
|
142
|
+
function inheritedFormat(current) {
|
|
143
|
+
const direct = new Set(Object.keys(readRunProps(current.rPr) ?? {}));
|
|
144
|
+
const inherited = {};
|
|
145
|
+
for (const [key, value] of Object.entries(current.format ?? {})) {
|
|
146
|
+
if (!direct.has(key)) inherited[key] = value;
|
|
147
|
+
}
|
|
148
|
+
return inherited;
|
|
149
|
+
}
|
|
150
|
+
function nextProps(rPr, previous) {
|
|
151
|
+
const inherited = inheritedFormat(previous);
|
|
152
|
+
const format = toRunFormat({ ...inherited, ...readRunProps(rPr) ?? {} });
|
|
153
|
+
if (rPr === null && (format === null || Object.keys(format).length === 0)) {
|
|
154
|
+
return { rPr: null, format: null };
|
|
155
|
+
}
|
|
156
|
+
return { rPr, format };
|
|
157
|
+
}
|
|
158
|
+
function editRunProps(current, pPr, edit) {
|
|
159
|
+
const props = propsOf(current.rPr);
|
|
160
|
+
if (!props) return null;
|
|
161
|
+
const inherited = propsChild(props.children, "rStyle") !== void 0 || hasChild(pPr, "pStyle");
|
|
162
|
+
const rFonts = propsChild(props.children, "rFonts")?.xml ?? null;
|
|
163
|
+
const edits = childEdits(edit, inherited, rFonts);
|
|
164
|
+
if (!edits) return null;
|
|
165
|
+
const children = edits.reduce(
|
|
166
|
+
(kept, [name, xml]) => setPropsChild(kept, name, xml, RUN_PR_ORDER),
|
|
167
|
+
props.children
|
|
168
|
+
);
|
|
169
|
+
const rPr = renderProps({ ...props, children });
|
|
170
|
+
return nextProps(rPr === "" ? null : rPr, current);
|
|
171
|
+
}
|
|
172
|
+
function isRunToggleOn(format, toggle) {
|
|
173
|
+
if (!format) return false;
|
|
174
|
+
if (toggle === "bold") return format.bold === true;
|
|
175
|
+
if (toggle === "italic") return format.italic === true;
|
|
176
|
+
if (toggle === "strike") return format.strike === true;
|
|
177
|
+
return format.underline !== void 0;
|
|
178
|
+
}
|
|
179
|
+
function matchesRunEdit(format, edit) {
|
|
180
|
+
switch (edit.kind) {
|
|
181
|
+
case "toggle":
|
|
182
|
+
return isRunToggleOn(format, edit.toggle) === edit.on;
|
|
183
|
+
case "fontSize":
|
|
184
|
+
return (format?.fontSizePt ?? null) === edit.pt;
|
|
185
|
+
case "fontFamily": {
|
|
186
|
+
const names = fontNamesOf(format?.fontFamily);
|
|
187
|
+
if (edit.name === null) return names.length === 0;
|
|
188
|
+
return names.length === 1 && names[0] === fontName(edit.name);
|
|
189
|
+
}
|
|
190
|
+
case "color": {
|
|
191
|
+
const current = format?.color ?? null;
|
|
192
|
+
if (current === null || edit.hex === null) return current === edit.hex;
|
|
193
|
+
return normalizeHex(current) === normalizeHex(edit.hex);
|
|
194
|
+
}
|
|
195
|
+
case "background": {
|
|
196
|
+
if (format?.highlight !== void 0) return false;
|
|
197
|
+
const fill = format?.background ? normalizeHex(format.background) : null;
|
|
198
|
+
return fill === (edit.hex === null ? null : normalizeHex(edit.hex));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
editRunProps,
|
|
204
|
+
isRunToggleOn,
|
|
205
|
+
matchesRunEdit,
|
|
206
|
+
readRunProps
|
|
207
|
+
};
|