@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,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads table formatting for display. Table borders and margins are folded into cell values so CSS
|
|
3
|
+
* collapsed-border resolution matches OOXML inheritance without changing exported XML.
|
|
4
|
+
*/
|
|
5
|
+
import type { CellFormat, CellMargins, InsideBorders, RowFormat, TableFormat, TableWidth } from "../../model/format";
|
|
6
|
+
export type { CellMargins, InsideBorders } from "../../model/format";
|
|
7
|
+
/**
|
|
8
|
+
* The width written down by `<w:tblW>` or `<w:tcW>`.
|
|
9
|
+
* If we cannot make out what it means it is null, and such a width goes back out unchanged on export.
|
|
10
|
+
*
|
|
11
|
+
* `auto` and `nil` leave the width to the layout, so whatever number stands beside them says nothing.
|
|
12
|
+
* A percentage may be written in fiftieths of a percent, as in `w:w="2500"`, or as `w:w="50%"`.
|
|
13
|
+
* Both have to be gathered into the same unit, or the table collapses into a thin strip on screen.
|
|
14
|
+
*/
|
|
15
|
+
export declare function readTableWidth(parent: Element | null, name: "tblW" | "tcW"): TableWidth | null;
|
|
16
|
+
/** The sequence of column widths (dxa) set by `<w:tblGrid>`. Revision markup (tblGridChange) is skipped */
|
|
17
|
+
export declare function readGridCols(tblGrid: Element | null): number[];
|
|
18
|
+
export declare const NO_INSIDE_BORDERS: InsideBorders;
|
|
19
|
+
export declare function readInsideBorders(tblPr: Element | null): InsideBorders;
|
|
20
|
+
/**
|
|
21
|
+
* Lays the inside lines a table wrote down on top of the ones its style laid down.
|
|
22
|
+
* A side the table wrote as `none` wins as well: a document that switched a line off is not to have
|
|
23
|
+
* the style's line come back.
|
|
24
|
+
*/
|
|
25
|
+
export declare function layerInsideBorders(style: InsideBorders, direct: InsideBorders): InsideBorders;
|
|
26
|
+
export declare const NO_CELL_MARGINS: CellMargins;
|
|
27
|
+
/** The margins `w:tblCellMar` (in a tblPr) or `w:tcMar` (in a tcPr) writes down, one side at a time */
|
|
28
|
+
export declare function readCellMarginsOf(parent: Element | null, name: "tblCellMar" | "tcMar"): CellMargins;
|
|
29
|
+
/**
|
|
30
|
+
* Lays the margins a table wrote down on top of the ones its style laid down.
|
|
31
|
+
* A side the table says nothing about keeps the style's margin, which is where most documents get
|
|
32
|
+
* their cell padding from.
|
|
33
|
+
*/
|
|
34
|
+
export declare function layerCellMargins(style: CellMargins, direct: CellMargins): CellMargins;
|
|
35
|
+
/** The lines a cell falls back on, one per side, already resolved for its spot in the grid */
|
|
36
|
+
export interface CellBorderDefaults {
|
|
37
|
+
top: string | null;
|
|
38
|
+
bottom: string | null;
|
|
39
|
+
left: string | null;
|
|
40
|
+
right: string | null;
|
|
41
|
+
}
|
|
42
|
+
export declare const NO_BORDER_DEFAULTS: CellBorderDefaults;
|
|
43
|
+
/** Which sides of a cell lie on the edge of the table's grid */
|
|
44
|
+
export interface GridEdges {
|
|
45
|
+
top: boolean;
|
|
46
|
+
bottom: boolean;
|
|
47
|
+
left: boolean;
|
|
48
|
+
right: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** A block of grid coordinates. `bottom` and `right` point one past the last cell, not at it */
|
|
51
|
+
export interface GridRect {
|
|
52
|
+
top: number;
|
|
53
|
+
bottom: number;
|
|
54
|
+
left: number;
|
|
55
|
+
right: number;
|
|
56
|
+
}
|
|
57
|
+
export interface GridSize {
|
|
58
|
+
rows: number;
|
|
59
|
+
cols: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Which sides of the block a cell covers lie on the edge of the grid, merges included.
|
|
63
|
+
* Everything that works out a cell's lines asks this first, whether the cell is being imported,
|
|
64
|
+
* created fresh, or looked up again in a table on screen.
|
|
65
|
+
*/
|
|
66
|
+
export declare function gridEdgesOf(rect: GridRect, grid: GridSize): GridEdges;
|
|
67
|
+
/**
|
|
68
|
+
* The lines the four sides of one cell fall back on.
|
|
69
|
+
*
|
|
70
|
+
* A side on the edge of the grid falls on the table's outer border, and one facing another cell on
|
|
71
|
+
* the table's inside line. An outer side the document wrote as `none` is passed through as it is:
|
|
72
|
+
* the table switched that line off, and nothing is to bring it back.
|
|
73
|
+
*/
|
|
74
|
+
export declare function cellBorderDefaults(edges: GridEdges, outer: TableFormat | null, inside: InsideBorders): CellBorderDefaults;
|
|
75
|
+
/** The name of the table style `w:tblStyle` points at. null if it points at none */
|
|
76
|
+
export declare function tblStyleIdOf(tblPr: Element | null): string | null;
|
|
77
|
+
export declare function readTableFormat(tblPr: Element | null): TableFormat | null;
|
|
78
|
+
export declare function readRowFormat(trPr: Element | null): RowFormat | null;
|
|
79
|
+
/**
|
|
80
|
+
* Cell formatting.
|
|
81
|
+
* A side for which the cell has not written down its own border uses the line that side falls on,
|
|
82
|
+
* which is the table's outer border or its inside line depending on where the cell sits.
|
|
83
|
+
* The padding works the same way: what the cell wrote down wins, and the table's cell margins lie
|
|
84
|
+
* underneath it. null if there is nothing at all to draw.
|
|
85
|
+
*/
|
|
86
|
+
export declare function readCellFormat(tcPr: Element | null, defaults: CellBorderDefaults, margins?: CellMargins): CellFormat | null;
|
|
87
|
+
/** The inside lines the table lays down, read from the table's own formatting XML */
|
|
88
|
+
export declare function insideBordersOf(tblPr: string | null): InsideBorders;
|
|
89
|
+
/** The cell margins the table lays down, read from the table's own formatting XML */
|
|
90
|
+
export declare function cellMarginsOf(tblPr: string | null): CellMargins;
|
|
91
|
+
/**
|
|
92
|
+
* Reads a cell formatting fragment we operated on back into display values, along the same path
|
|
93
|
+
* the import takes. The same fragment always yields the same display values.
|
|
94
|
+
*/
|
|
95
|
+
export declare function readCellProps(tcPr: string | null, defaults: CellBorderDefaults, margins?: CellMargins): CellFormat | null;
|
|
96
|
+
/** The formatting a cell holds. The original XML and the display values read out of it form a pair */
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// src/docx/tableFormatting/reading.ts
|
|
2
|
+
import {
|
|
3
|
+
ALIGN_BY_JC,
|
|
4
|
+
borderSide,
|
|
5
|
+
childValue,
|
|
6
|
+
isOn,
|
|
7
|
+
shadingOf,
|
|
8
|
+
toNumber,
|
|
9
|
+
twipsToPt,
|
|
10
|
+
wAttr
|
|
11
|
+
} from "../../ooxml/units.js";
|
|
12
|
+
import { childByLocalName } from "../../ooxml/xml.js";
|
|
13
|
+
import { parsePropsXml } from "../propsXml.js";
|
|
14
|
+
function readTableWidth(parent, name) {
|
|
15
|
+
const el = parent ? childByLocalName(parent, name) : null;
|
|
16
|
+
if (!el) return null;
|
|
17
|
+
const type = wAttr(el, "type") ?? "dxa";
|
|
18
|
+
if (type === "auto") return { type: "auto" };
|
|
19
|
+
if (type === "nil") return { type: "nil" };
|
|
20
|
+
const raw = wAttr(el, "w");
|
|
21
|
+
const value = toNumber(raw);
|
|
22
|
+
if (value === null) return null;
|
|
23
|
+
if (type === "dxa") return { type: "dxa", twips: value };
|
|
24
|
+
if (type === "pct") {
|
|
25
|
+
const isPercentText = raw?.endsWith("%") === true;
|
|
26
|
+
return {
|
|
27
|
+
type: "pct",
|
|
28
|
+
fiftieths: isPercentText ? Math.round(value * 50) : value
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
function readGridCols(tblGrid) {
|
|
34
|
+
if (!tblGrid) return [];
|
|
35
|
+
const cols = [];
|
|
36
|
+
for (const child of Array.from(tblGrid.children)) {
|
|
37
|
+
if (child.localName !== "gridCol") continue;
|
|
38
|
+
const w = toNumber(wAttr(child, "w"));
|
|
39
|
+
if (w !== null) cols.push(w);
|
|
40
|
+
}
|
|
41
|
+
return cols;
|
|
42
|
+
}
|
|
43
|
+
var NO_INSIDE_BORDERS = {
|
|
44
|
+
horizontal: null,
|
|
45
|
+
vertical: null
|
|
46
|
+
};
|
|
47
|
+
function readInsideBorders(tblPr) {
|
|
48
|
+
const borders = tblPr ? childByLocalName(tblPr, "tblBorders") : null;
|
|
49
|
+
return {
|
|
50
|
+
horizontal: borderSide(borders, "insideH"),
|
|
51
|
+
vertical: borderSide(borders, "insideV")
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function layerInsideBorders(style, direct) {
|
|
55
|
+
return {
|
|
56
|
+
horizontal: direct.horizontal ?? style.horizontal,
|
|
57
|
+
vertical: direct.vertical ?? style.vertical
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
var NO_CELL_MARGINS = {
|
|
61
|
+
topPt: null,
|
|
62
|
+
rightPt: null,
|
|
63
|
+
bottomPt: null,
|
|
64
|
+
leftPt: null
|
|
65
|
+
};
|
|
66
|
+
function marginSide(margins, names) {
|
|
67
|
+
for (const name of names) {
|
|
68
|
+
const el = childByLocalName(margins, name);
|
|
69
|
+
if (!el) continue;
|
|
70
|
+
const type = wAttr(el, "type") ?? "dxa";
|
|
71
|
+
if (type === "nil") return 0;
|
|
72
|
+
return type === "dxa" ? twipsToPt(wAttr(el, "w")) : null;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
function readCellMarginsOf(parent, name) {
|
|
77
|
+
const el = parent ? childByLocalName(parent, name) : null;
|
|
78
|
+
if (!el) return NO_CELL_MARGINS;
|
|
79
|
+
return {
|
|
80
|
+
topPt: marginSide(el, ["top"]),
|
|
81
|
+
rightPt: marginSide(el, ["end", "right"]),
|
|
82
|
+
bottomPt: marginSide(el, ["bottom"]),
|
|
83
|
+
leftPt: marginSide(el, ["start", "left"])
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function layerCellMargins(style, direct) {
|
|
87
|
+
return {
|
|
88
|
+
topPt: direct.topPt ?? style.topPt,
|
|
89
|
+
rightPt: direct.rightPt ?? style.rightPt,
|
|
90
|
+
bottomPt: direct.bottomPt ?? style.bottomPt,
|
|
91
|
+
leftPt: direct.leftPt ?? style.leftPt
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
var NO_BORDER_DEFAULTS = {
|
|
95
|
+
top: null,
|
|
96
|
+
bottom: null,
|
|
97
|
+
left: null,
|
|
98
|
+
right: null
|
|
99
|
+
};
|
|
100
|
+
function gridEdgesOf(rect, grid) {
|
|
101
|
+
return {
|
|
102
|
+
top: rect.top === 0,
|
|
103
|
+
bottom: rect.bottom === grid.rows,
|
|
104
|
+
left: rect.left === 0,
|
|
105
|
+
right: rect.right === grid.cols
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function cellBorderDefaults(edges, outer, inside) {
|
|
109
|
+
return {
|
|
110
|
+
top: edges.top ? outer?.borderTop ?? null : inside.horizontal,
|
|
111
|
+
bottom: edges.bottom ? outer?.borderBottom ?? null : inside.horizontal,
|
|
112
|
+
left: edges.left ? outer?.borderLeft ?? null : inside.vertical,
|
|
113
|
+
right: edges.right ? outer?.borderRight ?? null : inside.vertical
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function tblStyleIdOf(tblPr) {
|
|
117
|
+
return tblPr ? childValue(tblPr, "tblStyle") : null;
|
|
118
|
+
}
|
|
119
|
+
function readTableFormat(tblPr) {
|
|
120
|
+
if (!tblPr) return null;
|
|
121
|
+
const format = {};
|
|
122
|
+
const borders = childByLocalName(tblPr, "tblBorders");
|
|
123
|
+
const top = borderSide(borders, "top");
|
|
124
|
+
if (top) format.borderTop = top;
|
|
125
|
+
const bottom = borderSide(borders, "bottom");
|
|
126
|
+
if (bottom) format.borderBottom = bottom;
|
|
127
|
+
const left = borderSide(borders, "left") ?? borderSide(borders, "start");
|
|
128
|
+
if (left) format.borderLeft = left;
|
|
129
|
+
const right = borderSide(borders, "right") ?? borderSide(borders, "end");
|
|
130
|
+
if (right) format.borderRight = right;
|
|
131
|
+
const background = shadingOf(tblPr);
|
|
132
|
+
if (background) format.background = background;
|
|
133
|
+
const align = ALIGN_BY_JC[childValue(tblPr, "jc") ?? ""];
|
|
134
|
+
if (align) format.align = align;
|
|
135
|
+
const tblInd = childByLocalName(tblPr, "tblInd");
|
|
136
|
+
const indentLeftPt = tblInd ? twipsToPt(wAttr(tblInd, "w")) : null;
|
|
137
|
+
if (indentLeftPt !== null) format.indentLeftPt = indentLeftPt;
|
|
138
|
+
return format;
|
|
139
|
+
}
|
|
140
|
+
function readRowHeight(trHeight) {
|
|
141
|
+
const pt = twipsToPt(wAttr(trHeight, "val"));
|
|
142
|
+
if (pt === null || pt <= 0) return null;
|
|
143
|
+
const rule = wAttr(trHeight, "hRule") === "exact" ? "exact" : "atLeast";
|
|
144
|
+
return { rule, pt };
|
|
145
|
+
}
|
|
146
|
+
function readRowFormat(trPr) {
|
|
147
|
+
if (!trPr) return null;
|
|
148
|
+
const trHeight = childByLocalName(trPr, "trHeight");
|
|
149
|
+
const height = trHeight ? readRowHeight(trHeight) : null;
|
|
150
|
+
const format = {};
|
|
151
|
+
if (height) format.height = height;
|
|
152
|
+
if (isOn(trPr, "tblHeader")) format.repeatHeader = true;
|
|
153
|
+
if (isOn(trPr, "cantSplit")) format.cantSplit = true;
|
|
154
|
+
return format;
|
|
155
|
+
}
|
|
156
|
+
var CELL_VERTICAL_ALIGN_BY_VAL = {
|
|
157
|
+
top: "top",
|
|
158
|
+
center: "center",
|
|
159
|
+
bottom: "bottom"
|
|
160
|
+
};
|
|
161
|
+
function readCellPadding(tcPr, margins) {
|
|
162
|
+
const padding = layerCellMargins(margins, readCellMarginsOf(tcPr, "tcMar"));
|
|
163
|
+
const format = {};
|
|
164
|
+
if (padding.topPt !== null) format.paddingTopPt = padding.topPt;
|
|
165
|
+
if (padding.rightPt !== null) format.paddingRightPt = padding.rightPt;
|
|
166
|
+
if (padding.bottomPt !== null) format.paddingBottomPt = padding.bottomPt;
|
|
167
|
+
if (padding.leftPt !== null) format.paddingLeftPt = padding.leftPt;
|
|
168
|
+
return format;
|
|
169
|
+
}
|
|
170
|
+
function readCellFormat(tcPr, defaults, margins = NO_CELL_MARGINS) {
|
|
171
|
+
const borders = tcPr ? childByLocalName(tcPr, "tcBorders") : null;
|
|
172
|
+
const format = {};
|
|
173
|
+
const top = borderSide(borders, "top") ?? defaults.top;
|
|
174
|
+
if (top) format.borderTop = top;
|
|
175
|
+
const bottom = borderSide(borders, "bottom") ?? defaults.bottom;
|
|
176
|
+
if (bottom) format.borderBottom = bottom;
|
|
177
|
+
const left = borderSide(borders, "left") ?? borderSide(borders, "start") ?? defaults.left;
|
|
178
|
+
if (left) format.borderLeft = left;
|
|
179
|
+
const right = borderSide(borders, "right") ?? borderSide(borders, "end") ?? defaults.right;
|
|
180
|
+
if (right) format.borderRight = right;
|
|
181
|
+
if (tcPr) {
|
|
182
|
+
const background = shadingOf(tcPr);
|
|
183
|
+
if (background) format.background = background;
|
|
184
|
+
const verticalAlign = CELL_VERTICAL_ALIGN_BY_VAL[childValue(tcPr, "vAlign") ?? ""];
|
|
185
|
+
if (verticalAlign) format.verticalAlign = verticalAlign;
|
|
186
|
+
}
|
|
187
|
+
const padded = { ...format, ...readCellPadding(tcPr, margins) };
|
|
188
|
+
return Object.keys(padded).length > 0 ? padded : null;
|
|
189
|
+
}
|
|
190
|
+
function insideBordersOf(tblPr) {
|
|
191
|
+
const el = tblPr === null ? null : parsePropsXml(tblPr);
|
|
192
|
+
return readInsideBorders(el);
|
|
193
|
+
}
|
|
194
|
+
function cellMarginsOf(tblPr) {
|
|
195
|
+
const el = tblPr === null ? null : parsePropsXml(tblPr);
|
|
196
|
+
return readCellMarginsOf(el, "tblCellMar");
|
|
197
|
+
}
|
|
198
|
+
function readCellProps(tcPr, defaults, margins = NO_CELL_MARGINS) {
|
|
199
|
+
const el = tcPr === null ? null : parsePropsXml(tcPr);
|
|
200
|
+
return readCellFormat(el, defaults, margins);
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
NO_BORDER_DEFAULTS,
|
|
204
|
+
NO_CELL_MARGINS,
|
|
205
|
+
NO_INSIDE_BORDERS,
|
|
206
|
+
cellBorderDefaults,
|
|
207
|
+
cellMarginsOf,
|
|
208
|
+
gridEdgesOf,
|
|
209
|
+
insideBordersOf,
|
|
210
|
+
layerCellMargins,
|
|
211
|
+
layerInsideBorders,
|
|
212
|
+
readCellFormat,
|
|
213
|
+
readCellMarginsOf,
|
|
214
|
+
readCellProps,
|
|
215
|
+
readGridCols,
|
|
216
|
+
readInsideBorders,
|
|
217
|
+
readRowFormat,
|
|
218
|
+
readTableFormat,
|
|
219
|
+
readTableWidth,
|
|
220
|
+
tblStyleIdOf
|
|
221
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a single new table as a document model.
|
|
3
|
+
*
|
|
4
|
+
* The editor knows nothing about XML, so the `w:tblPr` and `w:tcPr` the new table will use are
|
|
5
|
+
* written out as text here too. The fragments we write are then read back with the same reading
|
|
6
|
+
* functions used when opening a document, to derive the display values.
|
|
7
|
+
* That way a freshly inserted table looks on screen exactly as it does after saving and reopening.
|
|
8
|
+
*/
|
|
9
|
+
import type { Node as PMNode } from "prosemirror-model";
|
|
10
|
+
import { type PageGeometry } from "./pageGeometry";
|
|
11
|
+
/** Whether the value can be used as a row count or a cell count */
|
|
12
|
+
export declare function isTableSide(value: number): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* A single table made up of nothing but empty cells.
|
|
15
|
+
*
|
|
16
|
+
* The table is as wide as one line of body text on the paper the document names, its column
|
|
17
|
+
* widths divide that width evenly, and the borders are black 0.5pt solid lines. A document that
|
|
18
|
+
* names no paper gets the A4 body width, which is what every document used to get.
|
|
19
|
+
* Being a new table with no original fragment, it is rewritten in full by `serializeTable` on export.
|
|
20
|
+
* The row and cell counts must be values that have passed through `isTableSide`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createTableNode(rows: number, cols: number, geometry?: PageGeometry): PMNode;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// src/docx/tableTemplate.ts
|
|
2
|
+
import { docxSchema } from "../schema/index.js";
|
|
3
|
+
import { A4_PORTRAIT, bodyWidth } from "./pageGeometry.js";
|
|
4
|
+
import { parsePropsXml } from "./propsXml.js";
|
|
5
|
+
import {
|
|
6
|
+
cellBorderDefaults,
|
|
7
|
+
gridEdgesOf,
|
|
8
|
+
NO_CELL_MARGINS,
|
|
9
|
+
readCellFormat,
|
|
10
|
+
readInsideBorders,
|
|
11
|
+
readTableFormat,
|
|
12
|
+
readTableWidth
|
|
13
|
+
} from "./tableFormatting.js";
|
|
14
|
+
var MAX_TABLE_SIDE = 50;
|
|
15
|
+
function isTableSide(value) {
|
|
16
|
+
return Number.isInteger(value) && value >= 1 && value <= MAX_TABLE_SIDE;
|
|
17
|
+
}
|
|
18
|
+
var BORDER_EIGHTHS = 4;
|
|
19
|
+
var BORDER_SIDES = [
|
|
20
|
+
"top",
|
|
21
|
+
"left",
|
|
22
|
+
"bottom",
|
|
23
|
+
"right",
|
|
24
|
+
"insideH",
|
|
25
|
+
"insideV"
|
|
26
|
+
];
|
|
27
|
+
function borderXml(side) {
|
|
28
|
+
return `<w:${side} w:val="single" w:sz="${BORDER_EIGHTHS}" w:space="0" w:color="000000"/>`;
|
|
29
|
+
}
|
|
30
|
+
function tablePropsXml(width) {
|
|
31
|
+
const borders = BORDER_SIDES.map(borderXml).join("");
|
|
32
|
+
return `<w:tblPr><w:tblW w:w="${width}" w:type="dxa"/><w:tblBorders>${borders}</w:tblBorders><w:tblLayout w:type="fixed"/></w:tblPr>`;
|
|
33
|
+
}
|
|
34
|
+
function cellPropsXml(width) {
|
|
35
|
+
return `<w:tcPr><w:tcW w:w="${width}" w:type="dxa"/></w:tcPr>`;
|
|
36
|
+
}
|
|
37
|
+
function evenGridCols(cols, total) {
|
|
38
|
+
const base = Math.floor(total / cols);
|
|
39
|
+
const extra = total - base * cols;
|
|
40
|
+
return Array.from(
|
|
41
|
+
{ length: cols },
|
|
42
|
+
(_, index) => index < extra ? base + 1 : base
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
function cellTemplate(width, defaults) {
|
|
46
|
+
const tcPr = cellPropsXml(width);
|
|
47
|
+
const el = parsePropsXml(tcPr);
|
|
48
|
+
return {
|
|
49
|
+
tcPr,
|
|
50
|
+
tcW: readTableWidth(el, "tcW"),
|
|
51
|
+
// A new table writes no `tblCellMar`, so its cells take their padding from the stylesheet
|
|
52
|
+
format: readCellFormat(el, defaults, NO_CELL_MARGINS)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function cellNode(props) {
|
|
56
|
+
return docxSchema.nodes.tableCell.create(
|
|
57
|
+
{
|
|
58
|
+
colspan: 1,
|
|
59
|
+
rowspan: 1,
|
|
60
|
+
colwidth: null,
|
|
61
|
+
tcAttrs: null,
|
|
62
|
+
tcPr: props.tcPr,
|
|
63
|
+
tcW: props.tcW,
|
|
64
|
+
format: props.format
|
|
65
|
+
},
|
|
66
|
+
docxSchema.nodes.paragraph.create()
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function rowNode(cells) {
|
|
70
|
+
return docxSchema.nodes.tableRow.create(
|
|
71
|
+
{ trAttrs: null, trPr: null, format: null },
|
|
72
|
+
cells.map(cellNode)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
function createTableNode(rows, cols, geometry = A4_PORTRAIT) {
|
|
76
|
+
const total = bodyWidth(geometry).twips;
|
|
77
|
+
const gridCols = evenGridCols(cols, total);
|
|
78
|
+
const tblPr = tablePropsXml(total);
|
|
79
|
+
const tblPrEl = parsePropsXml(tblPr);
|
|
80
|
+
const inside = readInsideBorders(tblPrEl);
|
|
81
|
+
const outer = readTableFormat(tblPrEl);
|
|
82
|
+
const cellAt = (row, col) => cellTemplate(
|
|
83
|
+
gridCols[col],
|
|
84
|
+
cellBorderDefaults(
|
|
85
|
+
gridEdgesOf(
|
|
86
|
+
{ top: row, bottom: row + 1, left: col, right: col + 1 },
|
|
87
|
+
{ rows, cols }
|
|
88
|
+
),
|
|
89
|
+
outer,
|
|
90
|
+
inside
|
|
91
|
+
)
|
|
92
|
+
);
|
|
93
|
+
return docxSchema.nodes.table.create(
|
|
94
|
+
{
|
|
95
|
+
srcId: null,
|
|
96
|
+
tblAttrs: null,
|
|
97
|
+
tblPr,
|
|
98
|
+
tblW: readTableWidth(tblPrEl, "tblW"),
|
|
99
|
+
gridCols,
|
|
100
|
+
format: outer
|
|
101
|
+
},
|
|
102
|
+
Array.from(
|
|
103
|
+
{ length: rows },
|
|
104
|
+
(_, row) => rowNode(gridCols.map((_width, col) => cellAt(row, col)))
|
|
105
|
+
)
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
createTableNode,
|
|
110
|
+
isTableSide
|
|
111
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fonts a document's theme names, and the references a run makes to them.
|
|
3
|
+
*
|
|
4
|
+
* Instead of naming a font, a `w:rFonts` may point at the theme
|
|
5
|
+
* (`w:asciiTheme="minorHAnsi"`), which is what Word writes for most of what it produces
|
|
6
|
+
* and what a Japanese or Chinese document almost always carries.
|
|
7
|
+
* Resolving those references is what lets such a run be drawn in the font the reader
|
|
8
|
+
* would see in Word. It is used for display only: the theme attributes themselves are
|
|
9
|
+
* carried back out untouched, so nothing read here reaches the file.
|
|
10
|
+
*/
|
|
11
|
+
/** The typefaces one font scheme names, one per script */
|
|
12
|
+
interface ThemeFontScheme {
|
|
13
|
+
latin: string | null;
|
|
14
|
+
eastAsia: string | null;
|
|
15
|
+
complexScript: string | null;
|
|
16
|
+
}
|
|
17
|
+
/** The two font schemes a theme defines: one for headings, one for body text */
|
|
18
|
+
export interface ThemeFonts {
|
|
19
|
+
major: ThemeFontScheme;
|
|
20
|
+
minor: ThemeFontScheme;
|
|
21
|
+
}
|
|
22
|
+
/** What applies to a document with no theme part, or one whose theme names no font */
|
|
23
|
+
export declare const NO_THEME_FONTS: ThemeFonts;
|
|
24
|
+
/**
|
|
25
|
+
* The theme attribute paired with each font slot.
|
|
26
|
+
* A theme reference and a name in the same slot cannot both apply, so the name wins,
|
|
27
|
+
* the way Word reads them.
|
|
28
|
+
*/
|
|
29
|
+
export declare const THEME_ATTRS: Record<string, readonly string[]>;
|
|
30
|
+
/** The font one theme reference stands for. null for a reference we cannot resolve */
|
|
31
|
+
export declare function themeFontName(fonts: ThemeFonts, value: string | null): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Reads the font scheme out of theme1.xml.
|
|
34
|
+
*
|
|
35
|
+
* The per-script fonts (`a:font script="Jpan"`) a theme lists beside those three are the
|
|
36
|
+
* ones Word swaps in when the language of the text changes, which is not something the
|
|
37
|
+
* screen decides, so they are left alone.
|
|
38
|
+
*/
|
|
39
|
+
export declare function readThemeFonts(theme: Document): ThemeFonts;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/docx/theme.ts
|
|
2
|
+
import { childByLocalName } from "../ooxml/xml.js";
|
|
3
|
+
var NO_FONT_SCHEME = {
|
|
4
|
+
latin: null,
|
|
5
|
+
eastAsia: null,
|
|
6
|
+
complexScript: null
|
|
7
|
+
};
|
|
8
|
+
var NO_THEME_FONTS = {
|
|
9
|
+
major: NO_FONT_SCHEME,
|
|
10
|
+
minor: NO_FONT_SCHEME
|
|
11
|
+
};
|
|
12
|
+
var THEME_ATTRS = {
|
|
13
|
+
ascii: ["asciiTheme"],
|
|
14
|
+
hAnsi: ["hAnsiTheme"],
|
|
15
|
+
eastAsia: ["eastAsiaTheme"],
|
|
16
|
+
// This is the slot whose capitalization varies from document to document
|
|
17
|
+
cs: ["cstheme", "csTheme"]
|
|
18
|
+
};
|
|
19
|
+
var THEME_SLOTS = {
|
|
20
|
+
majorascii: { scheme: "major", script: "latin" },
|
|
21
|
+
majorhansi: { scheme: "major", script: "latin" },
|
|
22
|
+
majoreastasia: { scheme: "major", script: "eastAsia" },
|
|
23
|
+
majorbidi: { scheme: "major", script: "complexScript" },
|
|
24
|
+
minorascii: { scheme: "minor", script: "latin" },
|
|
25
|
+
minorhansi: { scheme: "minor", script: "latin" },
|
|
26
|
+
minoreastasia: { scheme: "minor", script: "eastAsia" },
|
|
27
|
+
minorbidi: { scheme: "minor", script: "complexScript" }
|
|
28
|
+
};
|
|
29
|
+
function themeFontName(fonts, value) {
|
|
30
|
+
if (value === null) return null;
|
|
31
|
+
const slot = THEME_SLOTS[value.trim().toLowerCase()];
|
|
32
|
+
return slot ? fonts[slot.scheme][slot.script] : null;
|
|
33
|
+
}
|
|
34
|
+
function typefaceOf(font, name) {
|
|
35
|
+
const el = font ? childByLocalName(font, name) : null;
|
|
36
|
+
const typeface = el?.getAttribute("typeface") ?? null;
|
|
37
|
+
return typeface !== null && typeface.length > 0 ? typeface : null;
|
|
38
|
+
}
|
|
39
|
+
function fontSchemeOf(fontScheme, slot) {
|
|
40
|
+
const font = fontScheme ? childByLocalName(fontScheme, slot) : null;
|
|
41
|
+
if (!font) return NO_FONT_SCHEME;
|
|
42
|
+
return {
|
|
43
|
+
latin: typefaceOf(font, "latin"),
|
|
44
|
+
eastAsia: typefaceOf(font, "ea"),
|
|
45
|
+
complexScript: typefaceOf(font, "cs")
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function readThemeFonts(theme) {
|
|
49
|
+
const elements = childByLocalName(theme.documentElement, "themeElements");
|
|
50
|
+
const fontScheme = elements ? childByLocalName(elements, "fontScheme") : null;
|
|
51
|
+
return {
|
|
52
|
+
major: fontSchemeOf(fontScheme, "majorFont"),
|
|
53
|
+
minor: fontSchemeOf(fontScheme, "minorFont")
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
NO_THEME_FONTS,
|
|
58
|
+
THEME_ATTRS,
|
|
59
|
+
readThemeFonts,
|
|
60
|
+
themeFontName
|
|
61
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping one content control from going out twice under the same name.
|
|
3
|
+
*
|
|
4
|
+
* A control cannot cross a paragraph, so splitting a paragraph in the middle of one leaves that
|
|
5
|
+
* same control standing in two, and dropping unmarked text into the middle of one breaks it in
|
|
6
|
+
* two within the paragraph. Each piece then writes a `w:sdt` of its own (see `docx/sdt` for what
|
|
7
|
+
* a copy must not carry along).
|
|
8
|
+
*
|
|
9
|
+
* A document nobody broke apart comes back node for node as it was, which is what keeps an
|
|
10
|
+
* unedited block going out as its original XML.
|
|
11
|
+
*/
|
|
12
|
+
import { type Node as PMNode } from "prosemirror-model";
|
|
13
|
+
/** The document with every copy of a control opening under a name of its own */
|
|
14
|
+
export declare function withUniqueControls(doc: PMNode): PMNode;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/docx/uniqueControls.ts
|
|
2
|
+
import { Fragment } from "prosemirror-model";
|
|
3
|
+
import { docxSchema } from "../schema/index.js";
|
|
4
|
+
import { copiedControlPrefix, newControlId } from "./sdt.js";
|
|
5
|
+
function sdtMarkOf(node) {
|
|
6
|
+
return node.marks.find((mark) => mark.type === docxSchema.marks.sdt) ?? null;
|
|
7
|
+
}
|
|
8
|
+
function controlName(mark) {
|
|
9
|
+
const key = mark.attrs.sdtKey;
|
|
10
|
+
const prefix = mark.attrs.sdtPrefix;
|
|
11
|
+
return `${typeof key === "number" ? key : 0} ${typeof prefix === "string" ? prefix : ""}`;
|
|
12
|
+
}
|
|
13
|
+
function copiedMark(mark) {
|
|
14
|
+
const prefix = mark.attrs.sdtPrefix;
|
|
15
|
+
if (typeof prefix !== "string") return mark;
|
|
16
|
+
return mark.type.create({
|
|
17
|
+
...mark.attrs,
|
|
18
|
+
sdtPrefix: copiedControlPrefix(prefix, newControlId())
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function claim(mark, written) {
|
|
22
|
+
const name = controlName(mark);
|
|
23
|
+
const copy = written.has(name) ? copiedMark(mark) : null;
|
|
24
|
+
written.add(name);
|
|
25
|
+
return { mark, copy };
|
|
26
|
+
}
|
|
27
|
+
function rewriteParagraph(paragraph, written) {
|
|
28
|
+
const inline = [];
|
|
29
|
+
let running = null;
|
|
30
|
+
let renamed = false;
|
|
31
|
+
paragraph.forEach((child) => {
|
|
32
|
+
const mark = sdtMarkOf(child);
|
|
33
|
+
if (!mark) {
|
|
34
|
+
running = null;
|
|
35
|
+
inline.push(child);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const control = running?.mark.eq(mark) ? running : claim(mark, written);
|
|
39
|
+
running = control;
|
|
40
|
+
if (!control.copy) {
|
|
41
|
+
inline.push(child);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
renamed = true;
|
|
45
|
+
inline.push(
|
|
46
|
+
child.mark(control.copy.addToSet(mark.removeFromSet(child.marks)))
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
return renamed ? paragraph.copy(Fragment.fromArray(inline)) : paragraph;
|
|
50
|
+
}
|
|
51
|
+
function rewriteBlock(node, written) {
|
|
52
|
+
if (node.type.name === "paragraph") return rewriteParagraph(node, written);
|
|
53
|
+
if (node.childCount === 0) return node;
|
|
54
|
+
const children = node.children.map((child) => rewriteBlock(child, written));
|
|
55
|
+
return children.every((child, index) => child === node.child(index)) ? node : node.copy(Fragment.fromArray(children));
|
|
56
|
+
}
|
|
57
|
+
function withUniqueControls(doc) {
|
|
58
|
+
return rewriteBlock(doc, /* @__PURE__ */ new Set());
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
withUniqueControls
|
|
62
|
+
};
|