@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,305 @@
|
|
|
1
|
+
// src/model/format.ts
|
|
2
|
+
var ALIGNS = ["left", "center", "right", "justify"];
|
|
3
|
+
var VERTICAL_ALIGNS = ["superscript", "subscript"];
|
|
4
|
+
var CELL_VERTICAL_ALIGNS = ["top", "center", "bottom"];
|
|
5
|
+
var NO_FILL = "none";
|
|
6
|
+
var UNDERLINES = [
|
|
7
|
+
"single",
|
|
8
|
+
"words",
|
|
9
|
+
"double",
|
|
10
|
+
"thick",
|
|
11
|
+
"dotted",
|
|
12
|
+
"dottedHeavy",
|
|
13
|
+
"dash",
|
|
14
|
+
"dashedHeavy",
|
|
15
|
+
"dashLong",
|
|
16
|
+
"dashLongHeavy",
|
|
17
|
+
"dotDash",
|
|
18
|
+
"dashDotHeavy",
|
|
19
|
+
"dotDotDash",
|
|
20
|
+
"dashDotDotHeavy",
|
|
21
|
+
"wave",
|
|
22
|
+
"wavyHeavy",
|
|
23
|
+
"wavyDouble"
|
|
24
|
+
];
|
|
25
|
+
var HIGHLIGHTS = [
|
|
26
|
+
"black",
|
|
27
|
+
"blue",
|
|
28
|
+
"cyan",
|
|
29
|
+
"darkBlue",
|
|
30
|
+
"darkCyan",
|
|
31
|
+
"darkGray",
|
|
32
|
+
"darkGreen",
|
|
33
|
+
"darkMagenta",
|
|
34
|
+
"darkRed",
|
|
35
|
+
"darkYellow",
|
|
36
|
+
"green",
|
|
37
|
+
"lightGray",
|
|
38
|
+
"magenta",
|
|
39
|
+
"red",
|
|
40
|
+
"white",
|
|
41
|
+
"yellow"
|
|
42
|
+
];
|
|
43
|
+
function isUnderlineKind(value) {
|
|
44
|
+
return UNDERLINES.some((kind) => kind === value);
|
|
45
|
+
}
|
|
46
|
+
function isHighlightName(value) {
|
|
47
|
+
return HIGHLIGHTS.some((name) => name === value);
|
|
48
|
+
}
|
|
49
|
+
function widthNumber(width) {
|
|
50
|
+
if (width.type === "dxa") return width.twips;
|
|
51
|
+
if (width.type === "pct") return width.fiftieths;
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function withWidthNumber(width, value) {
|
|
55
|
+
if (width.type === "dxa") return { type: "dxa", twips: value };
|
|
56
|
+
if (width.type === "pct") return { type: "pct", fiftieths: value };
|
|
57
|
+
return width;
|
|
58
|
+
}
|
|
59
|
+
function isRecord(value) {
|
|
60
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
61
|
+
}
|
|
62
|
+
var HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
|
|
63
|
+
var BORDER_CSS = /^(none|\d+(\.\d{1,2})?pt (solid|double|dotted|dashed) #[0-9a-fA-F]{6})$/;
|
|
64
|
+
var FILL = /^(none|#[0-9a-fA-F]{6})$/;
|
|
65
|
+
var FONT_FAMILY = /^"[^"';]+"(,"[^"';]+")*$/;
|
|
66
|
+
var LANGUAGE_TAG = /^[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8}){0,4}$/;
|
|
67
|
+
function matching(pattern, value) {
|
|
68
|
+
return typeof value === "string" && pattern.test(value) ? value : void 0;
|
|
69
|
+
}
|
|
70
|
+
function isAlign(value) {
|
|
71
|
+
return ALIGNS.some((align) => align === value);
|
|
72
|
+
}
|
|
73
|
+
function isVerticalAlign(value) {
|
|
74
|
+
return VERTICAL_ALIGNS.some((align) => align === value);
|
|
75
|
+
}
|
|
76
|
+
function toLineSpacing(value) {
|
|
77
|
+
if (!isRecord(value)) return null;
|
|
78
|
+
if (value.rule === "auto" && typeof value.lines === "number") {
|
|
79
|
+
return { rule: "auto", lines: value.lines };
|
|
80
|
+
}
|
|
81
|
+
if (typeof value.pt !== "number") return null;
|
|
82
|
+
if (value.rule === "exact") return { rule: "exact", pt: value.pt };
|
|
83
|
+
if (value.rule === "atLeast") return { rule: "atLeast", pt: value.pt };
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function toNumberingRef(value) {
|
|
87
|
+
if (!isRecord(value)) return null;
|
|
88
|
+
const { numId, ilvl } = value;
|
|
89
|
+
if (typeof numId !== "number" || typeof ilvl !== "number") return null;
|
|
90
|
+
return { numId, ilvl };
|
|
91
|
+
}
|
|
92
|
+
var TAB_ALIGNMENTS = [
|
|
93
|
+
"start",
|
|
94
|
+
"center",
|
|
95
|
+
"end",
|
|
96
|
+
"decimal",
|
|
97
|
+
"num",
|
|
98
|
+
"bar"
|
|
99
|
+
];
|
|
100
|
+
var TAB_LEADERS = [
|
|
101
|
+
"none",
|
|
102
|
+
"dot",
|
|
103
|
+
"hyphen",
|
|
104
|
+
"underscore",
|
|
105
|
+
"heavy",
|
|
106
|
+
"middleDot"
|
|
107
|
+
];
|
|
108
|
+
function toTabStops(value) {
|
|
109
|
+
if (!Array.isArray(value)) return null;
|
|
110
|
+
const stops = [];
|
|
111
|
+
for (const entry of value) {
|
|
112
|
+
if (!isRecord(entry) || typeof entry.positionPt !== "number" || !Number.isFinite(entry.positionPt)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const align = TAB_ALIGNMENTS.find((candidate) => candidate === entry.align);
|
|
116
|
+
if (!align) continue;
|
|
117
|
+
const leader = TAB_LEADERS.find((candidate) => candidate === entry.leader);
|
|
118
|
+
stops.push({
|
|
119
|
+
positionPt: entry.positionPt,
|
|
120
|
+
align,
|
|
121
|
+
...leader === void 0 ? {} : { leader }
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return stops.length > 0 ? stops : null;
|
|
125
|
+
}
|
|
126
|
+
function toParagraphFormat(value) {
|
|
127
|
+
if (!isRecord(value)) return null;
|
|
128
|
+
const format = {};
|
|
129
|
+
if (isAlign(value.align)) format.align = value.align;
|
|
130
|
+
if (value.direction === "ltr" || value.direction === "rtl")
|
|
131
|
+
format.direction = value.direction;
|
|
132
|
+
if (typeof value.indentLeftPt === "number")
|
|
133
|
+
format.indentLeftPt = value.indentLeftPt;
|
|
134
|
+
if (typeof value.indentRightPt === "number")
|
|
135
|
+
format.indentRightPt = value.indentRightPt;
|
|
136
|
+
if (typeof value.indentStartPt === "number")
|
|
137
|
+
format.indentStartPt = value.indentStartPt;
|
|
138
|
+
if (typeof value.indentEndPt === "number")
|
|
139
|
+
format.indentEndPt = value.indentEndPt;
|
|
140
|
+
if (typeof value.textIndentPt === "number")
|
|
141
|
+
format.textIndentPt = value.textIndentPt;
|
|
142
|
+
if (typeof value.spaceBeforePt === "number")
|
|
143
|
+
format.spaceBeforePt = value.spaceBeforePt;
|
|
144
|
+
if (typeof value.spaceAfterPt === "number")
|
|
145
|
+
format.spaceAfterPt = value.spaceAfterPt;
|
|
146
|
+
const lineSpacing = toLineSpacing(value.lineSpacing);
|
|
147
|
+
if (lineSpacing) format.lineSpacing = lineSpacing;
|
|
148
|
+
const numbering = toNumberingRef(value.numbering);
|
|
149
|
+
if (numbering) format.numbering = numbering;
|
|
150
|
+
const tabStops = toTabStops(value.tabStops);
|
|
151
|
+
if (tabStops) format.tabStops = tabStops;
|
|
152
|
+
if (value.pageBreakBefore === true) format.pageBreakBefore = true;
|
|
153
|
+
copyBorders(value, format);
|
|
154
|
+
const background = matching(FILL, value.background);
|
|
155
|
+
if (background) format.background = background;
|
|
156
|
+
return format;
|
|
157
|
+
}
|
|
158
|
+
function toRunFormat(value) {
|
|
159
|
+
if (!isRecord(value)) return null;
|
|
160
|
+
const format = {};
|
|
161
|
+
if (value.bold === true) format.bold = true;
|
|
162
|
+
if (value.italic === true) format.italic = true;
|
|
163
|
+
if (value.strike === true) format.strike = true;
|
|
164
|
+
if (value.smallCaps === true) format.smallCaps = true;
|
|
165
|
+
if (isUnderlineKind(value.underline)) format.underline = value.underline;
|
|
166
|
+
if (typeof value.fontSizePt === "number")
|
|
167
|
+
format.fontSizePt = value.fontSizePt;
|
|
168
|
+
const fontFamily = matching(FONT_FAMILY, value.fontFamily);
|
|
169
|
+
if (fontFamily) format.fontFamily = fontFamily;
|
|
170
|
+
const color = matching(HEX_COLOR, value.color);
|
|
171
|
+
if (color) format.color = color;
|
|
172
|
+
if (isHighlightName(value.highlight)) format.highlight = value.highlight;
|
|
173
|
+
const background = matching(FILL, value.background);
|
|
174
|
+
if (background) format.background = background;
|
|
175
|
+
if (isVerticalAlign(value.verticalAlign))
|
|
176
|
+
format.verticalAlign = value.verticalAlign;
|
|
177
|
+
const lang = matching(LANGUAGE_TAG, value.lang);
|
|
178
|
+
if (lang) format.lang = lang;
|
|
179
|
+
return format;
|
|
180
|
+
}
|
|
181
|
+
function isCellVerticalAlign(value) {
|
|
182
|
+
return CELL_VERTICAL_ALIGNS.some((align) => align === value);
|
|
183
|
+
}
|
|
184
|
+
function toTableWidth(value) {
|
|
185
|
+
if (!isRecord(value)) return null;
|
|
186
|
+
if (value.type === "auto") return { type: "auto" };
|
|
187
|
+
if (value.type === "nil") return { type: "nil" };
|
|
188
|
+
if (value.type === "dxa" && typeof value.twips === "number")
|
|
189
|
+
return { type: "dxa", twips: value.twips };
|
|
190
|
+
if (value.type === "pct" && typeof value.fiftieths === "number")
|
|
191
|
+
return { type: "pct", fiftieths: value.fiftieths };
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
function toGridCols(value) {
|
|
195
|
+
if (!Array.isArray(value)) return [];
|
|
196
|
+
return value.filter((entry) => typeof entry === "number");
|
|
197
|
+
}
|
|
198
|
+
function toColWidth(value) {
|
|
199
|
+
if (!Array.isArray(value)) return null;
|
|
200
|
+
const widths = value.filter(
|
|
201
|
+
(entry) => typeof entry === "number"
|
|
202
|
+
);
|
|
203
|
+
return widths.length === value.length && widths.length > 0 ? widths : null;
|
|
204
|
+
}
|
|
205
|
+
function copyBorders(value, format) {
|
|
206
|
+
const top = matching(BORDER_CSS, value.borderTop);
|
|
207
|
+
if (top) format.borderTop = top;
|
|
208
|
+
const bottom = matching(BORDER_CSS, value.borderBottom);
|
|
209
|
+
if (bottom) format.borderBottom = bottom;
|
|
210
|
+
const left = matching(BORDER_CSS, value.borderLeft);
|
|
211
|
+
if (left) format.borderLeft = left;
|
|
212
|
+
const right = matching(BORDER_CSS, value.borderRight);
|
|
213
|
+
if (right) format.borderRight = right;
|
|
214
|
+
}
|
|
215
|
+
function toTableFormat(value) {
|
|
216
|
+
if (!isRecord(value)) return null;
|
|
217
|
+
const format = {};
|
|
218
|
+
copyBorders(value, format);
|
|
219
|
+
const background = matching(FILL, value.background);
|
|
220
|
+
if (background) format.background = background;
|
|
221
|
+
if (isAlign(value.align)) format.align = value.align;
|
|
222
|
+
if (typeof value.indentLeftPt === "number")
|
|
223
|
+
format.indentLeftPt = value.indentLeftPt;
|
|
224
|
+
return format;
|
|
225
|
+
}
|
|
226
|
+
function toInsideBorders(value) {
|
|
227
|
+
if (!isRecord(value)) return null;
|
|
228
|
+
const horizontal = matching(BORDER_CSS, value.horizontal) ?? null;
|
|
229
|
+
const vertical = matching(BORDER_CSS, value.vertical) ?? null;
|
|
230
|
+
if (horizontal === null && vertical === null) return null;
|
|
231
|
+
return { horizontal, vertical };
|
|
232
|
+
}
|
|
233
|
+
function marginSide(value) {
|
|
234
|
+
return typeof value === "number" ? value : null;
|
|
235
|
+
}
|
|
236
|
+
function toCellMargins(value) {
|
|
237
|
+
if (!isRecord(value)) return null;
|
|
238
|
+
const margins = {
|
|
239
|
+
topPt: marginSide(value.topPt),
|
|
240
|
+
rightPt: marginSide(value.rightPt),
|
|
241
|
+
bottomPt: marginSide(value.bottomPt),
|
|
242
|
+
leftPt: marginSide(value.leftPt)
|
|
243
|
+
};
|
|
244
|
+
const sides = [
|
|
245
|
+
margins.topPt,
|
|
246
|
+
margins.rightPt,
|
|
247
|
+
margins.bottomPt,
|
|
248
|
+
margins.leftPt
|
|
249
|
+
];
|
|
250
|
+
return sides.every((side) => side === null) ? null : margins;
|
|
251
|
+
}
|
|
252
|
+
function toRowHeight(value) {
|
|
253
|
+
if (!isRecord(value) || typeof value.pt !== "number") return null;
|
|
254
|
+
if (value.rule === "exact") return { rule: "exact", pt: value.pt };
|
|
255
|
+
if (value.rule === "atLeast") return { rule: "atLeast", pt: value.pt };
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
function toRowFormat(value) {
|
|
259
|
+
if (!isRecord(value)) return null;
|
|
260
|
+
const format = {};
|
|
261
|
+
const height = toRowHeight(value.height);
|
|
262
|
+
if (height) format.height = height;
|
|
263
|
+
if (value.repeatHeader === true) format.repeatHeader = true;
|
|
264
|
+
if (value.cantSplit === true) format.cantSplit = true;
|
|
265
|
+
return format;
|
|
266
|
+
}
|
|
267
|
+
function toCellFormat(value) {
|
|
268
|
+
if (!isRecord(value)) return null;
|
|
269
|
+
const format = {};
|
|
270
|
+
copyBorders(value, format);
|
|
271
|
+
const background = matching(FILL, value.background);
|
|
272
|
+
if (background) format.background = background;
|
|
273
|
+
if (isCellVerticalAlign(value.verticalAlign))
|
|
274
|
+
format.verticalAlign = value.verticalAlign;
|
|
275
|
+
if (typeof value.paddingTopPt === "number")
|
|
276
|
+
format.paddingTopPt = value.paddingTopPt;
|
|
277
|
+
if (typeof value.paddingRightPt === "number")
|
|
278
|
+
format.paddingRightPt = value.paddingRightPt;
|
|
279
|
+
if (typeof value.paddingBottomPt === "number")
|
|
280
|
+
format.paddingBottomPt = value.paddingBottomPt;
|
|
281
|
+
if (typeof value.paddingLeftPt === "number")
|
|
282
|
+
format.paddingLeftPt = value.paddingLeftPt;
|
|
283
|
+
return format;
|
|
284
|
+
}
|
|
285
|
+
function spanCount(value) {
|
|
286
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : 1;
|
|
287
|
+
}
|
|
288
|
+
export {
|
|
289
|
+
NO_FILL,
|
|
290
|
+
isHighlightName,
|
|
291
|
+
isUnderlineKind,
|
|
292
|
+
spanCount,
|
|
293
|
+
toCellFormat,
|
|
294
|
+
toCellMargins,
|
|
295
|
+
toColWidth,
|
|
296
|
+
toGridCols,
|
|
297
|
+
toInsideBorders,
|
|
298
|
+
toParagraphFormat,
|
|
299
|
+
toRowFormat,
|
|
300
|
+
toRunFormat,
|
|
301
|
+
toTableFormat,
|
|
302
|
+
toTableWidth,
|
|
303
|
+
widthNumber,
|
|
304
|
+
withWidthNumber
|
|
305
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type TabAlignment = "start" | "center" | "end" | "decimal" | "num";
|
|
2
|
+
export type TabLeader = "none" | "dot" | "hyphen" | "underscore" | "heavy" | "middleDot";
|
|
3
|
+
/** One effective custom tab entry. Positions are points from the paragraph's leading margin. */
|
|
4
|
+
export interface TabStop {
|
|
5
|
+
positionPt: number;
|
|
6
|
+
align: TabAlignment | "bar";
|
|
7
|
+
leader?: TabLeader;
|
|
8
|
+
}
|
|
9
|
+
/** A tab entry before the paragraph-property hierarchy has been resolved. */
|
|
10
|
+
export type TabStopDirective = TabStop | {
|
|
11
|
+
positionPt: number;
|
|
12
|
+
align: "clear";
|
|
13
|
+
};
|
|
14
|
+
/** Composes two OOXML tab-property layers while retaining clears for a lower layer. */
|
|
15
|
+
export declare function layerTabStopDirectives(base: readonly TabStopDirective[], over: readonly TabStopDirective[]): TabStopDirective[];
|
|
16
|
+
/** Resolves the final OOXML tab-property layers, removing cleared positions. */
|
|
17
|
+
export declare function mergeTabStops(base: readonly TabStopDirective[], over: readonly TabStopDirective[]): TabStop[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/model/tabStops.ts
|
|
2
|
+
function layerTabStopDirectives(base, over) {
|
|
3
|
+
const stops = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const stop of base) {
|
|
5
|
+
stops.set(stop.positionPt, stop);
|
|
6
|
+
}
|
|
7
|
+
for (const stop of over) {
|
|
8
|
+
stops.set(stop.positionPt, stop);
|
|
9
|
+
}
|
|
10
|
+
return [...stops.values()].sort(
|
|
11
|
+
(left, right) => left.positionPt - right.positionPt
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
function mergeTabStops(base, over) {
|
|
15
|
+
return layerTabStopDirectives(base, over).filter(
|
|
16
|
+
(stop) => stop.align !== "clear"
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
layerTabStopDirectives,
|
|
21
|
+
mergeTabStops
|
|
22
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The standard shape of a newly started list.
|
|
3
|
+
*
|
|
4
|
+
* The definition of a new list is not kept in the document model.
|
|
5
|
+
* So its shape has to be derivable from the list number (numId) alone, and that rule
|
|
6
|
+
* lives here. Even numbers are numbered lists, odd numbers are bullet lists.
|
|
7
|
+
*
|
|
8
|
+
* Drawing the markers on screen and writing the definitions into numbering.xml both look
|
|
9
|
+
* at the same template.
|
|
10
|
+
*/
|
|
11
|
+
import type { LevelIndent, Numbering, NumberingList } from "./parseNumbering";
|
|
12
|
+
export type ListKind = "numbered" | "bullet";
|
|
13
|
+
/** A list has nine levels (the count OOXML defines) */
|
|
14
|
+
export declare const LEVEL_COUNT = 9;
|
|
15
|
+
export declare const MAX_ILVL: number;
|
|
16
|
+
export declare function templateIndent(ilvl: number): LevelIndent;
|
|
17
|
+
export declare function listKindOf(numId: number): ListKind;
|
|
18
|
+
/**
|
|
19
|
+
* The list definition for this number.
|
|
20
|
+
* A number the document's numbering.xml does not know is read as the standard template
|
|
21
|
+
* (which is the case for a list that was just started).
|
|
22
|
+
*/
|
|
23
|
+
export declare function listFor(numbering: Numbering, numId: number): NumberingList;
|
|
24
|
+
/** The next number not yet in use. Picks the even or odd one matching the shape */
|
|
25
|
+
export declare function nextNumId(used: Iterable<number>, kind: ListKind): number;
|
|
26
|
+
/** Writes one template out as a `<w:abstractNum>` definition */
|
|
27
|
+
export declare function abstractNumXml(abstractNumId: number, kind: ListKind): string;
|
|
28
|
+
/** The `<w:num>` that ties a list number to a definition */
|
|
29
|
+
export declare function numXml(numId: number, abstractNumId: number): string;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/numbering/listTemplate.ts
|
|
2
|
+
var LEVEL_COUNT = 9;
|
|
3
|
+
var MAX_ILVL = LEVEL_COUNT - 1;
|
|
4
|
+
var NUMBER_CYCLE = [
|
|
5
|
+
"decimal",
|
|
6
|
+
"lowerLetter",
|
|
7
|
+
"lowerRoman"
|
|
8
|
+
];
|
|
9
|
+
var BULLET_CYCLE = ["\u25CF", "\u25CB", "\u25A0"];
|
|
10
|
+
var LEVEL_STEP_TWIPS = 720;
|
|
11
|
+
var HANGING_TWIPS = 360;
|
|
12
|
+
function templateIndent(ilvl) {
|
|
13
|
+
return {
|
|
14
|
+
startTwips: LEVEL_STEP_TWIPS * (ilvl + 1),
|
|
15
|
+
endTwips: null,
|
|
16
|
+
hangingTwips: HANGING_TWIPS,
|
|
17
|
+
firstLineTwips: null
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function cycled(cycle, ilvl, fallback) {
|
|
21
|
+
return cycle[ilvl % cycle.length] ?? fallback;
|
|
22
|
+
}
|
|
23
|
+
function templateLevel(kind, ilvl) {
|
|
24
|
+
const numbered = kind === "numbered";
|
|
25
|
+
return {
|
|
26
|
+
format: numbered ? cycled(NUMBER_CYCLE, ilvl, "decimal") : "bullet",
|
|
27
|
+
text: numbered ? `%${ilvl + 1}.` : cycled(BULLET_CYCLE, ilvl, "\u25CF"),
|
|
28
|
+
start: 1,
|
|
29
|
+
indent: templateIndent(ilvl)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function templateList(kind) {
|
|
33
|
+
const levels = /* @__PURE__ */ new Map();
|
|
34
|
+
for (let ilvl = 0; ilvl < LEVEL_COUNT; ilvl += 1) {
|
|
35
|
+
levels.set(ilvl, templateLevel(kind, ilvl));
|
|
36
|
+
}
|
|
37
|
+
return { levels };
|
|
38
|
+
}
|
|
39
|
+
var TEMPLATES = {
|
|
40
|
+
numbered: templateList("numbered"),
|
|
41
|
+
bullet: templateList("bullet")
|
|
42
|
+
};
|
|
43
|
+
function listKindOf(numId) {
|
|
44
|
+
return numId % 2 === 0 ? "numbered" : "bullet";
|
|
45
|
+
}
|
|
46
|
+
function listFor(numbering, numId) {
|
|
47
|
+
return numbering.lists.get(numId) ?? TEMPLATES[listKindOf(numId)];
|
|
48
|
+
}
|
|
49
|
+
function nextNumId(used, kind) {
|
|
50
|
+
const from = Math.max(0, ...used) + 1;
|
|
51
|
+
return listKindOf(from) === kind ? from : from + 1;
|
|
52
|
+
}
|
|
53
|
+
function indXml(indent) {
|
|
54
|
+
const attrs = [
|
|
55
|
+
["w:left", indent?.startTwips],
|
|
56
|
+
["w:right", indent?.endTwips],
|
|
57
|
+
["w:hanging", indent?.hangingTwips],
|
|
58
|
+
["w:firstLine", indent?.firstLineTwips]
|
|
59
|
+
].filter((entry) => typeof entry[1] === "number").map(([name, value]) => `${name}="${value}"`).join(" ");
|
|
60
|
+
return attrs === "" ? "" : `<w:pPr><w:ind ${attrs}/></w:pPr>`;
|
|
61
|
+
}
|
|
62
|
+
function levelXml(ilvl, level) {
|
|
63
|
+
const ind = indXml(level.indent);
|
|
64
|
+
return `<w:lvl w:ilvl="${ilvl}"><w:start w:val="${level.start}"/><w:numFmt w:val="${level.format}"/><w:lvlText w:val="${level.text}"/><w:lvlJc w:val="left"/>${ind}</w:lvl>`;
|
|
65
|
+
}
|
|
66
|
+
function abstractNumXml(abstractNumId, kind) {
|
|
67
|
+
const levels = TEMPLATES[kind].levels;
|
|
68
|
+
const body = Array.from(levels.entries()).map(([ilvl, level]) => levelXml(ilvl, level)).join("");
|
|
69
|
+
return `<w:abstractNum w:abstractNumId="${abstractNumId}">${body}</w:abstractNum>`;
|
|
70
|
+
}
|
|
71
|
+
function numXml(numId, abstractNumId) {
|
|
72
|
+
return `<w:num w:numId="${numId}"><w:abstractNumId w:val="${abstractNumId}"/></w:num>`;
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
LEVEL_COUNT,
|
|
76
|
+
MAX_ILVL,
|
|
77
|
+
abstractNumXml,
|
|
78
|
+
listFor,
|
|
79
|
+
listKindOf,
|
|
80
|
+
nextNumId,
|
|
81
|
+
numXml,
|
|
82
|
+
templateIndent
|
|
83
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walks the paragraphs in order and computes the number to show for each list paragraph.
|
|
3
|
+
*
|
|
4
|
+
* A pure computation that never touches the document model: the same paragraphs with the
|
|
5
|
+
* same numbering definitions always yield the same numbers.
|
|
6
|
+
*/
|
|
7
|
+
import type { NumberingRef } from "../model/format";
|
|
8
|
+
import { type LevelIndentPt, type Numbering } from "./parseNumbering";
|
|
9
|
+
/** The number to draw in front of one paragraph */
|
|
10
|
+
export interface ListMarker {
|
|
11
|
+
text: string;
|
|
12
|
+
/**
|
|
13
|
+
* The indent defined by the level this paragraph belongs to. Used when the paragraph
|
|
14
|
+
* records none of its own
|
|
15
|
+
*/
|
|
16
|
+
indent: LevelIndentPt;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A slot is null for a paragraph that is not a list item, or whose level shape could not
|
|
20
|
+
* be found.
|
|
21
|
+
* A number the document does not know (a list started fresh while editing) is drawn with
|
|
22
|
+
* the standard template's shape.
|
|
23
|
+
*/
|
|
24
|
+
export declare function computeMarkers(paragraphs: readonly (NumberingRef | null)[], numbering: Numbering): (ListMarker | null)[];
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/numbering/markers.ts
|
|
2
|
+
import { listFor } from "./listTemplate.js";
|
|
3
|
+
import {
|
|
4
|
+
levelIndentPt
|
|
5
|
+
} from "./parseNumbering.js";
|
|
6
|
+
var ROMAN = [
|
|
7
|
+
[1e3, "M"],
|
|
8
|
+
[900, "CM"],
|
|
9
|
+
[500, "D"],
|
|
10
|
+
[400, "CD"],
|
|
11
|
+
[100, "C"],
|
|
12
|
+
[90, "XC"],
|
|
13
|
+
[50, "L"],
|
|
14
|
+
[40, "XL"],
|
|
15
|
+
[10, "X"],
|
|
16
|
+
[9, "IX"],
|
|
17
|
+
[5, "V"],
|
|
18
|
+
[4, "IV"],
|
|
19
|
+
[1, "I"]
|
|
20
|
+
];
|
|
21
|
+
function toRoman(value) {
|
|
22
|
+
let rest = value;
|
|
23
|
+
let out = "";
|
|
24
|
+
for (const [amount, sign] of ROMAN) {
|
|
25
|
+
while (rest >= amount) {
|
|
26
|
+
out += sign;
|
|
27
|
+
rest -= amount;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
function toLetters(value) {
|
|
33
|
+
const index = (value - 1) % 26;
|
|
34
|
+
const repeat = Math.floor((value - 1) / 26) + 1;
|
|
35
|
+
return String.fromCharCode(65 + index).repeat(repeat);
|
|
36
|
+
}
|
|
37
|
+
var MAX_MARKER_CHARS = 64;
|
|
38
|
+
var MAX_SPELLED_VALUE = {
|
|
39
|
+
decimal: Number.POSITIVE_INFINITY,
|
|
40
|
+
bullet: Number.POSITIVE_INFINITY,
|
|
41
|
+
lowerLetter: 26 * MAX_MARKER_CHARS,
|
|
42
|
+
upperLetter: 26 * MAX_MARKER_CHARS,
|
|
43
|
+
lowerRoman: 1e3 * MAX_MARKER_CHARS
|
|
44
|
+
};
|
|
45
|
+
function formatNumber(value, format) {
|
|
46
|
+
if (value < 1 || value > MAX_SPELLED_VALUE[format]) return `${value}`;
|
|
47
|
+
switch (format) {
|
|
48
|
+
case "lowerLetter":
|
|
49
|
+
return toLetters(value).toLowerCase();
|
|
50
|
+
case "upperLetter":
|
|
51
|
+
return toLetters(value);
|
|
52
|
+
case "lowerRoman":
|
|
53
|
+
return toRoman(value).toLowerCase();
|
|
54
|
+
default:
|
|
55
|
+
return `${value}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function fillLevels(text, list, counters) {
|
|
59
|
+
return text.replaceAll(/%([1-9])/g, (_, digit) => {
|
|
60
|
+
const ilvl = Number(digit) - 1;
|
|
61
|
+
const level = list.levels.get(ilvl);
|
|
62
|
+
if (!level) return "";
|
|
63
|
+
return formatNumber(counters.get(ilvl) ?? level.start, level.format);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function advance(counters, list, ilvl, start) {
|
|
67
|
+
const current = counters.get(ilvl);
|
|
68
|
+
counters.set(ilvl, current === void 0 ? start : current + 1);
|
|
69
|
+
for (const deeper of [...counters.keys(), ...list.levels.keys()]) {
|
|
70
|
+
if (deeper > ilvl) counters.delete(deeper);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function computeMarkers(paragraphs, numbering) {
|
|
74
|
+
const countersByList = /* @__PURE__ */ new Map();
|
|
75
|
+
return paragraphs.map((ref) => {
|
|
76
|
+
if (!ref) return null;
|
|
77
|
+
const list = listFor(numbering, ref.numId);
|
|
78
|
+
const level = list.levels.get(ref.ilvl);
|
|
79
|
+
if (!level) return null;
|
|
80
|
+
let counters = countersByList.get(ref.numId);
|
|
81
|
+
if (!counters) {
|
|
82
|
+
counters = /* @__PURE__ */ new Map();
|
|
83
|
+
countersByList.set(ref.numId, counters);
|
|
84
|
+
}
|
|
85
|
+
advance(counters, list, ref.ilvl, level.start);
|
|
86
|
+
const shape = level.format === "bullet" ? level.text : fillLevels(level.text, list, counters);
|
|
87
|
+
const text = shape.slice(0, MAX_MARKER_CHARS);
|
|
88
|
+
return text ? { text, indent: levelIndentPt(level.indent) } : null;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
computeMarkers
|
|
93
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads numbering.xml to build up "what shape does level N of list M have".
|
|
3
|
+
*
|
|
4
|
+
* The values produced here are used only for drawing the numbers on screen.
|
|
5
|
+
* numbering.xml itself goes out as the original bytes on export, so this reading never
|
|
6
|
+
* disturbs the file.
|
|
7
|
+
*/
|
|
8
|
+
import type { TabStopDirective } from "../model/tabStops";
|
|
9
|
+
/** The number formats actually used across every fixture */
|
|
10
|
+
declare const NUMBER_FORMATS: readonly ["decimal", "bullet", "lowerLetter", "upperLetter", "lowerRoman"];
|
|
11
|
+
export type NumberFormat = (typeof NUMBER_FORMATS)[number];
|
|
12
|
+
/**
|
|
13
|
+
* The indent a level defines. The unit is twips (1/20 of a point), and a slot that is
|
|
14
|
+
* not recorded is null
|
|
15
|
+
*/
|
|
16
|
+
export interface LevelIndent {
|
|
17
|
+
startTwips: number | null;
|
|
18
|
+
endTwips: number | null;
|
|
19
|
+
hangingTwips: number | null;
|
|
20
|
+
firstLineTwips: number | null;
|
|
21
|
+
}
|
|
22
|
+
export interface NumberingLevel {
|
|
23
|
+
format: NumberFormat;
|
|
24
|
+
/**
|
|
25
|
+
* The pattern holding the number slots, such as `%1.` or `(%2)`. For a bullet it is
|
|
26
|
+
* the bullet glyph itself
|
|
27
|
+
*/
|
|
28
|
+
text: string;
|
|
29
|
+
start: number;
|
|
30
|
+
/** The indent the paragraphs of this level use. Null when the level defines none */
|
|
31
|
+
indent: LevelIndent | null;
|
|
32
|
+
/** Custom stops contributed by this level's paragraph properties. */
|
|
33
|
+
tabStops?: readonly TabStopDirective[];
|
|
34
|
+
}
|
|
35
|
+
export interface NumberingList {
|
|
36
|
+
/** The shape for each level (ilvl) */
|
|
37
|
+
levels: Map<number, NumberingLevel>;
|
|
38
|
+
}
|
|
39
|
+
export interface Numbering {
|
|
40
|
+
/** The list for each numId */
|
|
41
|
+
lists: Map<number, NumberingList>;
|
|
42
|
+
}
|
|
43
|
+
export declare const EMPTY_NUMBERING: Numbering;
|
|
44
|
+
/**
|
|
45
|
+
* The indent a level defines, converted into the on-screen unit (points). A slot the
|
|
46
|
+
* level does not define is null
|
|
47
|
+
*/
|
|
48
|
+
export interface LevelIndentPt {
|
|
49
|
+
startPt: number | null;
|
|
50
|
+
endPt: number | null;
|
|
51
|
+
/**
|
|
52
|
+
* Negative for a hanging indent, positive for a first-line indent. Null when there is
|
|
53
|
+
* neither
|
|
54
|
+
*/
|
|
55
|
+
textIndentPt: number | null;
|
|
56
|
+
}
|
|
57
|
+
export declare const NO_LEVEL_INDENT: LevelIndentPt;
|
|
58
|
+
/**
|
|
59
|
+
* The indent a level passes down to its paragraphs.
|
|
60
|
+
* As with paragraph formatting, a hanging indent overrides a first-line indent (the
|
|
61
|
+
* OOXML rule).
|
|
62
|
+
*/
|
|
63
|
+
export declare function levelIndentPt(indent: LevelIndent | null): LevelIndentPt;
|
|
64
|
+
export declare function parseNumbering(xml: string | null): Numbering;
|
|
65
|
+
export {};
|