@docen/docx 0.3.1 → 0.3.2

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.
Files changed (109) hide show
  1. package/dist/converters/docx.d.mts +199 -1
  2. package/dist/converters/docx.mjs +1273 -1
  3. package/dist/converters/html.d.mts +28 -1
  4. package/dist/converters/html.mjs +103 -1
  5. package/dist/converters/markdown.d.mts +12 -1
  6. package/dist/converters/markdown.mjs +17 -1
  7. package/dist/converters/patch.d.mts +52 -1
  8. package/dist/converters/patch.mjs +35 -1
  9. package/dist/converters/prepare.d.mts +62 -1
  10. package/dist/converters/prepare.mjs +121 -1
  11. package/dist/converters/styles.d.mts +84 -1
  12. package/dist/converters/styles.mjs +284 -1
  13. package/dist/core-C9VunJ8o.d.mts +174 -0
  14. package/dist/core-DT9IrTzN.mjs +670 -0
  15. package/dist/core.d.mts +1 -1
  16. package/dist/core.mjs +1 -1
  17. package/dist/editor.d.mts +20 -1
  18. package/dist/editor.mjs +20 -1
  19. package/dist/extensions/blockquote.d.mts +1 -1
  20. package/dist/extensions/blockquote.mjs +30 -2
  21. package/dist/extensions/code-block.d.mts +1 -1
  22. package/dist/extensions/code-block.mjs +22 -1
  23. package/dist/extensions/column-break.d.mts +1 -1
  24. package/dist/extensions/column-break.mjs +1 -1
  25. package/dist/extensions/details.d.mts +1 -1
  26. package/dist/extensions/details.mjs +17 -2
  27. package/dist/extensions/document.mjs +49 -1
  28. package/dist/extensions/extensions.d.mts +3 -4
  29. package/dist/extensions/extensions.mjs +13 -14
  30. package/dist/extensions/formatting-marks.d.mts +7 -1
  31. package/dist/extensions/formatting-marks.mjs +1 -1
  32. package/dist/extensions/heading.mjs +165 -1
  33. package/dist/extensions/image.d.mts +1 -1
  34. package/dist/extensions/image.mjs +395 -1
  35. package/dist/extensions/index.d.mts +3 -2
  36. package/dist/extensions/index.mjs +4 -3
  37. package/dist/extensions/mention.d.mts +1 -1
  38. package/dist/extensions/mention.mjs +43 -2
  39. package/dist/extensions/ordered-list.d.mts +1 -1
  40. package/dist/extensions/ordered-list.mjs +40 -2
  41. package/dist/extensions/page-break.d.mts +1 -33
  42. package/dist/extensions/page-break.mjs +1 -1
  43. package/dist/extensions/paragraph.mjs +150 -1
  44. package/dist/extensions/passthrough.d.mts +1 -1
  45. package/dist/extensions/passthrough.mjs +1 -1
  46. package/dist/extensions/section-break.d.mts +19 -2
  47. package/dist/extensions/section-break.mjs +1 -1
  48. package/dist/extensions/strike.mjs +49 -1
  49. package/dist/extensions/table-cell.mjs +111 -1
  50. package/dist/extensions/table-header.mjs +111 -1
  51. package/dist/extensions/table-row.mjs +83 -1
  52. package/dist/extensions/table.mjs +159 -1
  53. package/dist/extensions/task-item.d.mts +1 -1
  54. package/dist/extensions/task-item.mjs +36 -2
  55. package/dist/extensions/text-style.mjs +150 -1
  56. package/dist/extensions/tiptap.d.mts +2 -2
  57. package/dist/extensions/tiptap.mjs +31 -2
  58. package/dist/extensions/utils.d.mts +2 -62
  59. package/dist/extensions/utils.mjs +499 -2
  60. package/dist/extensions/wpg-group.d.mts +2 -0
  61. package/dist/extensions/wpg-group.mjs +2 -0
  62. package/dist/extensions/wps-shape.d.mts +2 -0
  63. package/dist/extensions/wps-shape.mjs +2 -0
  64. package/dist/index.d.mts +86 -27
  65. package/dist/index.mjs +13 -10
  66. package/dist/{tiptap-TErPjuNJ.d.mts → tiptap-pZsNPsvV.d.mts} +1 -3
  67. package/dist/utils-D87vukzp.d.mts +128 -0
  68. package/package.json +39 -40
  69. package/dist/blockquote-Ky9xD_Q-.mjs +0 -31
  70. package/dist/code-block-BgNjhADy.mjs +0 -23
  71. package/dist/core-DEqBHRzE.mjs +0 -406
  72. package/dist/core-fBMCCj4D.d.mts +0 -97
  73. package/dist/details-Dh8luWb2.mjs +0 -18
  74. package/dist/dist-B6B3HnVZ.mjs +0 -1838
  75. package/dist/document-CvTym-FM.mjs +0 -50
  76. package/dist/docx-C5wyjI-0.d.mts +0 -200
  77. package/dist/docx-CONyAedl.mjs +0 -1231
  78. package/dist/editor-Bf3CxQnY.mjs +0 -21
  79. package/dist/editor-DReY3Rb9.d.mts +0 -21
  80. package/dist/emoji-BZ1dJD7d.d.mts +0 -17
  81. package/dist/emoji-C2OsTWR7.mjs +0 -27
  82. package/dist/extensions/emoji.d.mts +0 -2
  83. package/dist/extensions/emoji.mjs +0 -2
  84. package/dist/extensions/image-group.d.mts +0 -6
  85. package/dist/extensions/image-group.mjs +0 -2
  86. package/dist/heading-DAubgJJN.mjs +0 -166
  87. package/dist/html-DCC_DSHv.d.mts +0 -18
  88. package/dist/html-DedDWPoO.mjs +0 -66
  89. package/dist/image-CuEIXoZl.mjs +0 -334
  90. package/dist/markdown-BzJmRsBs.mjs +0 -18
  91. package/dist/markdown-D0k0sRYS.d.mts +0 -13
  92. package/dist/mention-C-dTR6MK.mjs +0 -44
  93. package/dist/ordered-list-V-3xFQmV.mjs +0 -41
  94. package/dist/paragraph-BrWH-BOV.mjs +0 -147
  95. package/dist/patch-Cdp5WKJz.d.mts +0 -53
  96. package/dist/patch-IZ13tXTu.mjs +0 -36
  97. package/dist/prepare-Bdk8Cjkf.mjs +0 -122
  98. package/dist/prepare-CPAvcv6q.d.mts +0 -63
  99. package/dist/strike-hWxShOgb.mjs +0 -50
  100. package/dist/styles-QSX3RhxK.mjs +0 -285
  101. package/dist/styles-ugspkrxz.d.mts +0 -85
  102. package/dist/table-DrA12lxX.mjs +0 -159
  103. package/dist/table-cell-DmkfYwDc.mjs +0 -112
  104. package/dist/table-header-Bwr5GKWg.mjs +0 -112
  105. package/dist/table-row-vew1y7WH.mjs +0 -84
  106. package/dist/task-item-BnlXGrIG.mjs +0 -37
  107. package/dist/text-style-tMeBq5XQ.mjs +0 -151
  108. package/dist/tiptap-D7pl4I5U.mjs +0 -33
  109. package/dist/utils-BPT4tjcn.mjs +0 -333
@@ -1,2 +1,151 @@
1
- import { n as parseDocx, r as renderDocx, t as Paragraph } from "../paragraph-BrWH-BOV.mjs";
1
+ import { Paragraph as Paragraph$1 } from "./tiptap.mjs";
2
+ import { alignmentFromElement, bordersFromElement, indentFromElement, renderParagraphStyles, shadingFromElement, spacingFromElement } from "./utils.mjs";
3
+ //#region src/extensions/paragraph.ts
4
+ /**
5
+ * Paragraph extension with nested office-open attrs.
6
+ *
7
+ * Attrs mirror ParagraphPropertiesOptionsBase (alignment/indent/spacing/border/
8
+ * shading/frame as nested objects + scalar OOXML properties). DOCX round-trip is
9
+ * near-identity: renderDocx/parseDocx pass attrs through; CSS conversion happens
10
+ * only in renderHTML via utils mappers.
11
+ */
12
+ const SECTION_ATTR_KEYS = new Set([
13
+ "sectionProperties",
14
+ "sectionHeaders",
15
+ "sectionFooters"
16
+ ]);
17
+ function renderDocx(node) {
18
+ const attrs = node.attrs ?? {};
19
+ const opts = {};
20
+ for (const [key, value] of Object.entries(attrs)) {
21
+ if (value === null || value === void 0) continue;
22
+ if (SECTION_ATTR_KEYS.has(key)) continue;
23
+ if (key === "styleId") {
24
+ opts.style = value;
25
+ continue;
26
+ }
27
+ opts[key] = value;
28
+ }
29
+ return opts;
30
+ }
31
+ /**
32
+ * Structural/semantic keys handled elsewhere (heading ext, list handling, run/text
33
+ * children). NOTE: `run` is intentionally NOT skipped — ParagraphOptions.run (the
34
+ * paragraph's default run properties: font/size/color) is kept as an attr for
35
+ * lossless round-trip (e.g. header/footer paragraphs whose styling lives there).
36
+ */
37
+ const SKIP_KEYS = new Set([
38
+ "heading",
39
+ "style",
40
+ "bullet",
41
+ "numbering",
42
+ "children",
43
+ "text",
44
+ "thematicBreak"
45
+ ]);
46
+ function parseDocx(opts) {
47
+ const resolved = typeof opts === "string" ? { text: opts } : opts;
48
+ const attrs = {};
49
+ if (resolved.style) attrs.styleId = resolved.style;
50
+ for (const [key, value] of Object.entries(resolved)) {
51
+ if (SKIP_KEYS.has(key)) continue;
52
+ attrs[key] = value ?? null;
53
+ }
54
+ return attrs;
55
+ }
56
+ const attrNative = () => ({
57
+ default: null,
58
+ parseHTML: () => null,
59
+ rendered: false
60
+ });
61
+ const Paragraph = Paragraph$1.extend({
62
+ addAttributes() {
63
+ return {
64
+ ...this.parent?.(),
65
+ styleId: {
66
+ default: null,
67
+ parseHTML: (el) => {
68
+ const m = (el.getAttribute("class") || "").match(/(?:^|\s)docx-style-(\S+)/);
69
+ return m ? m[1] : null;
70
+ }
71
+ },
72
+ alignment: {
73
+ default: null,
74
+ rendered: false,
75
+ parseHTML: (el) => alignmentFromElement(el)
76
+ },
77
+ indent: {
78
+ default: null,
79
+ rendered: false,
80
+ parseHTML: (el) => indentFromElement(el)
81
+ },
82
+ spacing: {
83
+ default: null,
84
+ rendered: false,
85
+ parseHTML: (el) => spacingFromElement(el)
86
+ },
87
+ shading: {
88
+ default: null,
89
+ rendered: false,
90
+ parseHTML: (el) => shadingFromElement(el)
91
+ },
92
+ border: {
93
+ default: null,
94
+ rendered: false,
95
+ parseHTML: (el) => bordersFromElement(el)
96
+ },
97
+ frame: attrNative(),
98
+ run: attrNative(),
99
+ sectionProperties: attrNative(),
100
+ sectionHeaders: attrNative(),
101
+ sectionFooters: attrNative(),
102
+ keepNext: attrNative(),
103
+ keepLines: attrNative(),
104
+ pageBreakBefore: attrNative(),
105
+ widowControl: attrNative(),
106
+ contextualSpacing: attrNative(),
107
+ bidirectional: attrNative(),
108
+ outlineLevel: attrNative(),
109
+ textDirection: attrNative(),
110
+ textAlignment: attrNative(),
111
+ suppressLineNumbers: attrNative(),
112
+ wordWrap: attrNative(),
113
+ overflowPunctuation: attrNative(),
114
+ autoSpaceEastAsianText: attrNative(),
115
+ suppressOverlap: attrNative(),
116
+ suppressAutoHyphens: attrNative(),
117
+ adjustRightInd: attrNative(),
118
+ snapToGrid: attrNative(),
119
+ mirrorIndents: attrNative(),
120
+ kinsoku: attrNative(),
121
+ topLinePunct: attrNative(),
122
+ autoSpaceDE: attrNative(),
123
+ textboxTightWrap: attrNative(),
124
+ rightTabStop: attrNative(),
125
+ leftTabStop: attrNative(),
126
+ divId: attrNative(),
127
+ tabStops: attrNative(),
128
+ cnfStyle: attrNative()
129
+ };
130
+ },
131
+ renderHTML({ node, HTMLAttributes }) {
132
+ let hasContent = false;
133
+ node.forEach?.((child) => {
134
+ if (child.isText || child.type?.name === "hardBreak" || child.type?.name === "image") hasContent = true;
135
+ });
136
+ const styles = renderParagraphStyles(node.attrs, { empty: !hasContent });
137
+ const attrs = { ...HTMLAttributes };
138
+ const styleId = node.attrs.styleId;
139
+ attrs.class = styleId ? `docx-style-${styleId}` : "docx-default";
140
+ if (styles.length > 0) attrs.style = styles.join(";");
141
+ return [
142
+ "p",
143
+ attrs,
144
+ 0
145
+ ];
146
+ },
147
+ renderDocx,
148
+ parseDocx
149
+ });
150
+ //#endregion
2
151
  export { Paragraph, parseDocx, renderDocx };
@@ -1,2 +1,2 @@
1
- import { m as Passthrough } from "../core-fBMCCj4D.mjs";
1
+ import { h as Passthrough } from "../core-C9VunJ8o.mjs";
2
2
  export { Passthrough };
@@ -1,2 +1,2 @@
1
- import { d as Passthrough } from "../core-DEqBHRzE.mjs";
1
+ import { h as Passthrough } from "../core-DT9IrTzN.mjs";
2
2
  export { Passthrough };
@@ -1,4 +1,4 @@
1
- import { r as Extension } from "../core-fBMCCj4D.mjs";
1
+ import { r as Extension } from "../core-C9VunJ8o.mjs";
2
2
 
3
3
  //#region src/extensions/section-break.d.ts
4
4
  /**
@@ -14,12 +14,29 @@ import { r as Extension } from "../core-fBMCCj4D.mjs";
14
14
  * The final section's sectPr rides on doc.attrs.sectionProperties (it lives at
15
15
  * <w:body>'s end in OOXML). Single-section documents have no section-carrying
16
16
  * paragraph at all.
17
+ *
18
+ * Next Page semantics: `setSectionBreak` stamps sectionProperties on the current
19
+ * paragraph (making it the section's last paragraph) AND inserts a fresh empty
20
+ * paragraph after it (the next section's first paragraph), then moves the
21
+ * selection into that new paragraph. The page-plugin's `forcesPageBreakAfter`
22
+ * treats a sectionProperties-bearing paragraph as a page break, so repaginate
23
+ * pushes the new paragraph onto the next page — and the caret follows. This
24
+ * mirrors Word's "Section Break (Next Page)".
25
+ *
26
+ * Split hygiene: pressing Enter inside a section-carrying paragraph must NOT
27
+ * split it. A split would place the new paragraph past the section boundary —
28
+ * forcesPageBreakAfter then pushes it onto the next page (next section), and
29
+ * splitBlock would copy sectionProperties onto it (a second break mark). Word
30
+ * instead inserts a fresh paragraph BEFORE the section's last paragraph, so the
31
+ * new paragraph stays in this section and the stamped paragraph remains last.
32
+ * The Enter shortcut does exactly that; non-section paragraphs fall through to
33
+ * the default Enter unchanged.
17
34
  */
18
35
  declare const SectionBreak: Extension<any, any>;
19
36
  declare module "@tiptap/core" {
20
37
  interface Commands<ReturnType> {
21
38
  sectionBreak: {
22
- /** Stamp sectionProperties on the current paragraph, ending a section. */setSectionBreak: () => ReturnType;
39
+ /** Insert a Next Page section break at the current paragraph. */setSectionBreak: () => ReturnType;
23
40
  };
24
41
  }
25
42
  }
@@ -1,2 +1,2 @@
1
- import { u as SectionBreak } from "../core-DEqBHRzE.mjs";
1
+ import { m as SectionBreak } from "../core-DT9IrTzN.mjs";
2
2
  export { SectionBreak };
@@ -1,2 +1,50 @@
1
- import { n as parseDocx, r as renderDocx, t as Strike } from "../strike-hWxShOgb.mjs";
1
+ import { Strike as Strike$1 } from "./tiptap.mjs";
2
+ //#region src/extensions/strike.ts
3
+ /**
4
+ * Strike mark extension with nested office-open attrs.
5
+ *
6
+ * OOXML represents strikethrough on a run via two mutually exclusive booleans:
7
+ * `strike` (single) and `doubleStrike` (double). The mark itself is "single
8
+ * strikethrough"; the `doubleStrike` attr flips it to double. DOCX round-trip
9
+ * is near-identity for the doubleStrike flag; `strike` itself is implied by the
10
+ * mark's presence and handled in renderDocx/parseDocx.
11
+ *
12
+ * Mark attribute-level renderHTML is delegated to the base Strike extension
13
+ * (renders `<s>`); only the DOCX flag needs custom handling.
14
+ */
15
+ /**
16
+ * attrs → run properties.
17
+ *
18
+ * The mark presence itself means single strikethrough. When `doubleStrike` is
19
+ * set, emit the OOXML double-strike flag instead (the two are mutually
20
+ * exclusive in OOXML). DocxManager calls this with `mark.attrs`.
21
+ */
22
+ function renderDocx(attrs) {
23
+ return attrs.doubleStrike ? { doubleStrike: true } : { strike: true };
24
+ }
25
+ /**
26
+ * run properties → attrs.
27
+ *
28
+ * Only the `doubleStrike` flag needs to round-trip; single strike is implied by
29
+ * the mark's existence. `strike` is structural/semantic (the mark) and skipped.
30
+ */
31
+ function parseDocx(runOpts) {
32
+ return { doubleStrike: runOpts.doubleStrike ?? null };
33
+ }
34
+ const attrNative = () => ({
35
+ default: null,
36
+ parseHTML: () => null,
37
+ rendered: false
38
+ });
39
+ const Strike = Strike$1.extend({
40
+ addAttributes() {
41
+ return {
42
+ ...this.parent?.(),
43
+ doubleStrike: attrNative()
44
+ };
45
+ },
46
+ renderDocx,
47
+ parseDocx
48
+ });
49
+ //#endregion
2
50
  export { Strike, parseDocx, renderDocx };
@@ -1,2 +1,112 @@
1
- import { n as parseDocx, r as renderDocx, t as TableCell } from "../table-cell-DmkfYwDc.mjs";
1
+ import { TableCell as TableCell$1 } from "./tiptap.mjs";
2
+ import { bordersFromElement, renderTableCellStyles, shadingFromElement } from "./utils.mjs";
3
+ //#region src/extensions/table-cell.ts
4
+ /**
5
+ * Table cell extension with nested office-open attrs.
6
+ *
7
+ * Attrs mirror TableCellPropertiesOptionsBase (shading/margins/borders/width as
8
+ * nested objects + scalar OOXML properties) plus the inherited Tiptap structural
9
+ * names colspan/rowspan/colwidth/align (rendered: false for the OOXML-named ones).
10
+ * DOCX round-trip is near-identity: renderDocx/parseDocx pass OOXML-native attrs
11
+ * through and only map the Tiptap structural names colspan/rowspan/colwidth to
12
+ * OOXML columnSpan/rowSpan/width. CSS conversion happens solely in renderHTML via
13
+ * utils.renderTableCellStyles (consuming nested shading/verticalAlign/noWrap).
14
+ */
15
+ /** Tiptap structural attrs expressed via OOXML structural fields, not passed through. */
16
+ const SKIP_KEYS = new Set([
17
+ "colspan",
18
+ "rowspan",
19
+ "colwidth",
20
+ "children"
21
+ ]);
22
+ function renderDocx(node) {
23
+ const attrs = node.attrs ?? {};
24
+ const opts = {};
25
+ const colspan = attrs.colspan;
26
+ if (colspan && colspan > 1) opts.columnSpan = colspan;
27
+ const rowspan = attrs.rowspan;
28
+ if (rowspan && rowspan > 1) opts.rowSpan = rowspan;
29
+ const colwidth = attrs.colwidth;
30
+ if (colwidth && colwidth.length > 0) {
31
+ const totalPx = colwidth.reduce((sum, w) => sum + (w || 0), 0);
32
+ if (totalPx > 0) opts.width = {
33
+ size: totalPx * 15,
34
+ type: "dxa"
35
+ };
36
+ }
37
+ for (const [key, value] of Object.entries(attrs)) {
38
+ if (SKIP_KEYS.has(key)) continue;
39
+ if (value !== null && value !== void 0) opts[key] = value;
40
+ }
41
+ return opts;
42
+ }
43
+ function parseDocx(opts) {
44
+ const resolved = typeof opts === "string" ? { text: opts } : opts;
45
+ const attrs = {};
46
+ if (resolved.columnSpan != null) attrs.colspan = resolved.columnSpan;
47
+ if (resolved.rowSpan != null) attrs.rowspan = resolved.rowSpan;
48
+ if (resolved.width) {
49
+ const twips = resolved.width.size ?? 0;
50
+ if (twips) attrs.colwidth = [Math.round(twips / 15)];
51
+ }
52
+ for (const [key, value] of Object.entries(resolved)) {
53
+ if (key === "columnSpan" || key === "rowSpan" || key === "width" || key === "children") continue;
54
+ attrs[key] = value ?? null;
55
+ }
56
+ return attrs;
57
+ }
58
+ const attrNative = () => ({
59
+ default: null,
60
+ parseHTML: () => null,
61
+ rendered: false
62
+ });
63
+ const TableCell = TableCell$1.extend({
64
+ addAttributes() {
65
+ return {
66
+ ...this.parent?.(),
67
+ shading: {
68
+ default: null,
69
+ rendered: false,
70
+ parseHTML: (el) => shadingFromElement(el)
71
+ },
72
+ borders: {
73
+ default: null,
74
+ rendered: false,
75
+ parseHTML: (el) => bordersFromElement(el)
76
+ },
77
+ verticalAlign: {
78
+ default: null,
79
+ rendered: false,
80
+ parseHTML: (el) => el.style.verticalAlign || null
81
+ },
82
+ textDirection: attrNative(),
83
+ width: attrNative(),
84
+ margins: attrNative(),
85
+ noWrap: {
86
+ default: null,
87
+ rendered: false,
88
+ parseHTML: (el) => el.style.whiteSpace === "nowrap" ? true : null
89
+ },
90
+ verticalMerge: attrNative(),
91
+ horizontalMerge: attrNative(),
92
+ fitText: attrNative(),
93
+ hideMark: attrNative(),
94
+ headers: attrNative(),
95
+ cnfStyle: attrNative()
96
+ };
97
+ },
98
+ renderHTML({ node, HTMLAttributes }) {
99
+ const styles = renderTableCellStyles(node.attrs);
100
+ const attrs = { ...HTMLAttributes };
101
+ if (styles.length > 0) attrs.style = styles.join(";");
102
+ return [
103
+ "td",
104
+ attrs,
105
+ 0
106
+ ];
107
+ },
108
+ renderDocx,
109
+ parseDocx
110
+ });
111
+ //#endregion
2
112
  export { TableCell, parseDocx, renderDocx };
@@ -1,2 +1,112 @@
1
- import { n as parseDocx, r as renderDocx, t as TableHeader } from "../table-header-Bwr5GKWg.mjs";
1
+ import { TableHeader as TableHeader$1 } from "./tiptap.mjs";
2
+ import { bordersFromElement, renderTableCellStyles, shadingFromElement } from "./utils.mjs";
3
+ //#region src/extensions/table-header.ts
4
+ /**
5
+ * Table header extension with nested office-open attrs (mirrors TableCell).
6
+ *
7
+ * Attrs mirror TableCellPropertiesOptionsBase (shading/margins/borders/width as
8
+ * nested objects + scalar OOXML properties) plus the inherited Tiptap structural
9
+ * names colspan/rowspan/colwidth/align (rendered: false for the OOXML-named ones).
10
+ * DOCX round-trip is near-identity: renderDocx/parseDocx pass OOXML-native attrs
11
+ * through and only map the Tiptap structural names colspan/rowspan/colwidth to
12
+ * OOXML columnSpan/rowSpan/width. CSS conversion happens solely in renderHTML via
13
+ * utils.renderTableCellStyles (consuming nested shading/verticalAlign/noWrap).
14
+ */
15
+ /** Tiptap structural attrs expressed via OOXML structural fields, not passed through. */
16
+ const SKIP_KEYS = new Set([
17
+ "colspan",
18
+ "rowspan",
19
+ "colwidth",
20
+ "children"
21
+ ]);
22
+ function renderDocx(node) {
23
+ const attrs = node.attrs ?? {};
24
+ const opts = {};
25
+ const colspan = attrs.colspan;
26
+ if (colspan && colspan > 1) opts.columnSpan = colspan;
27
+ const rowspan = attrs.rowspan;
28
+ if (rowspan && rowspan > 1) opts.rowSpan = rowspan;
29
+ const colwidth = attrs.colwidth;
30
+ if (colwidth && colwidth.length > 0) {
31
+ const totalPx = colwidth.reduce((sum, w) => sum + (w || 0), 0);
32
+ if (totalPx > 0) opts.width = {
33
+ size: totalPx * 15,
34
+ type: "dxa"
35
+ };
36
+ }
37
+ for (const [key, value] of Object.entries(attrs)) {
38
+ if (SKIP_KEYS.has(key)) continue;
39
+ if (value !== null && value !== void 0) opts[key] = value;
40
+ }
41
+ return opts;
42
+ }
43
+ function parseDocx(opts) {
44
+ const resolved = typeof opts === "string" ? { text: opts } : opts;
45
+ const attrs = {};
46
+ if (resolved.columnSpan != null) attrs.colspan = resolved.columnSpan;
47
+ if (resolved.rowSpan != null) attrs.rowspan = resolved.rowSpan;
48
+ if (resolved.width) {
49
+ const twips = resolved.width.size ?? 0;
50
+ if (twips) attrs.colwidth = [Math.round(twips / 15)];
51
+ }
52
+ for (const [key, value] of Object.entries(resolved)) {
53
+ if (key === "columnSpan" || key === "rowSpan" || key === "width" || key === "children") continue;
54
+ attrs[key] = value ?? null;
55
+ }
56
+ return attrs;
57
+ }
58
+ const attrNative = () => ({
59
+ default: null,
60
+ parseHTML: () => null,
61
+ rendered: false
62
+ });
63
+ const TableHeader = TableHeader$1.extend({
64
+ addAttributes() {
65
+ return {
66
+ ...this.parent?.(),
67
+ shading: {
68
+ default: null,
69
+ rendered: false,
70
+ parseHTML: (el) => shadingFromElement(el)
71
+ },
72
+ borders: {
73
+ default: null,
74
+ rendered: false,
75
+ parseHTML: (el) => bordersFromElement(el)
76
+ },
77
+ verticalAlign: {
78
+ default: null,
79
+ rendered: false,
80
+ parseHTML: (el) => el.style.verticalAlign || null
81
+ },
82
+ textDirection: attrNative(),
83
+ width: attrNative(),
84
+ margins: attrNative(),
85
+ noWrap: {
86
+ default: null,
87
+ rendered: false,
88
+ parseHTML: (el) => el.style.whiteSpace === "nowrap" ? true : null
89
+ },
90
+ verticalMerge: attrNative(),
91
+ horizontalMerge: attrNative(),
92
+ fitText: attrNative(),
93
+ hideMark: attrNative(),
94
+ headers: attrNative(),
95
+ cnfStyle: attrNative()
96
+ };
97
+ },
98
+ renderHTML({ node, HTMLAttributes }) {
99
+ const styles = renderTableCellStyles(node.attrs);
100
+ const attrs = { ...HTMLAttributes };
101
+ if (styles.length > 0) attrs.style = styles.join(";");
102
+ return [
103
+ "th",
104
+ attrs,
105
+ 0
106
+ ];
107
+ },
108
+ renderDocx,
109
+ parseDocx
110
+ });
111
+ //#endregion
2
112
  export { TableHeader, parseDocx, renderDocx };
@@ -1,2 +1,84 @@
1
- import { n as parseDocx, r as renderDocx, t as TableRow } from "../table-row-vew1y7WH.mjs";
1
+ import { TableRow as TableRow$1 } from "./tiptap.mjs";
2
+ import { cssToTwip } from "./utils.mjs";
3
+ //#region src/extensions/table-row.ts
4
+ /**
5
+ * Table row extension with nested office-open attrs.
6
+ *
7
+ * Attrs mirror TableRowPropertiesOptionsBase (cantSplit/tableHeader/hidden as
8
+ * booleans; height as a nested { value, rule } object; cellSpacing as a native
9
+ * value; widthBefore/widthAfter as TableWidthProperties; etc.). DOCX round-trip
10
+ * is near-identity: renderDocx/parseDocx pass attrs through (omitting the
11
+ * `cells` structural key that DocxManager owns). CSS conversion happens only
12
+ * in renderHTML.
13
+ */
14
+ /** Structural keys filled by DocxManager (compileTableNode). */
15
+ const SKIP_KEYS = new Set(["cells"]);
16
+ function renderDocx(node) {
17
+ const attrs = node.attrs ?? {};
18
+ const opts = {};
19
+ for (const [key, value] of Object.entries(attrs)) {
20
+ if (SKIP_KEYS.has(key)) continue;
21
+ if (value !== null && value !== void 0) opts[key] = value;
22
+ }
23
+ return opts;
24
+ }
25
+ function parseDocx(opts) {
26
+ const attrs = {};
27
+ for (const [key, value] of Object.entries(opts)) {
28
+ if (SKIP_KEYS.has(key)) continue;
29
+ attrs[key] = value ?? null;
30
+ }
31
+ return attrs;
32
+ }
33
+ const attrNative = () => ({
34
+ default: null,
35
+ parseHTML: () => null,
36
+ rendered: false
37
+ });
38
+ const TableRow = TableRow$1.extend({
39
+ addAttributes() {
40
+ return {
41
+ ...this.parent?.(),
42
+ height: {
43
+ default: null,
44
+ rendered: false,
45
+ parseHTML: (el) => {
46
+ const twips = cssToTwip(el.style.height || el.getAttribute("height") || "");
47
+ return twips != null ? {
48
+ value: twips,
49
+ rule: "atLeast"
50
+ } : null;
51
+ }
52
+ },
53
+ cantSplit: attrNative(),
54
+ tableHeader: attrNative(),
55
+ hidden: attrNative(),
56
+ divId: attrNative(),
57
+ gridBefore: attrNative(),
58
+ gridAfter: attrNative(),
59
+ rowAlignment: attrNative(),
60
+ cnfStyle: attrNative(),
61
+ cellSpacing: attrNative(),
62
+ widthBefore: attrNative(),
63
+ widthAfter: attrNative()
64
+ };
65
+ },
66
+ renderHTML({ node, HTMLAttributes }) {
67
+ const attrs = { ...HTMLAttributes };
68
+ const styles = [];
69
+ if (node.attrs.height && typeof node.attrs.height === "object") {
70
+ const h = node.attrs.height;
71
+ if (h.value != null) styles.push(`height:${h.value / 20}pt`);
72
+ }
73
+ if (styles.length > 0) attrs.style = styles.join(";");
74
+ return [
75
+ "tr",
76
+ attrs,
77
+ 0
78
+ ];
79
+ },
80
+ renderDocx,
81
+ parseDocx
82
+ });
83
+ //#endregion
2
84
  export { TableRow, parseDocx, renderDocx };