@docen/docx 0.3.0 → 0.3.1

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 (110) hide show
  1. package/README.md +2 -3
  2. package/dist/blockquote-Ky9xD_Q-.mjs +31 -0
  3. package/dist/code-block-BgNjhADy.mjs +23 -0
  4. package/dist/converters/docx.d.mts +1 -109
  5. package/dist/converters/docx.mjs +1 -623
  6. package/dist/converters/html.d.mts +1 -13
  7. package/dist/converters/html.mjs +1 -17
  8. package/dist/converters/markdown.d.mts +1 -12
  9. package/dist/converters/markdown.mjs +1 -17
  10. package/dist/converters/patch.d.mts +1 -52
  11. package/dist/converters/patch.mjs +1 -36
  12. package/dist/converters/prepare.d.mts +2 -51
  13. package/dist/converters/prepare.mjs +2 -76
  14. package/dist/converters/styles.d.mts +2 -0
  15. package/dist/converters/styles.mjs +2 -0
  16. package/dist/core-DEqBHRzE.mjs +406 -0
  17. package/dist/core-fBMCCj4D.d.mts +97 -0
  18. package/dist/core.d.mts +1 -1
  19. package/dist/core.mjs +1 -1
  20. package/dist/details-Dh8luWb2.mjs +18 -0
  21. package/dist/dist-B6B3HnVZ.mjs +1838 -0
  22. package/dist/document-BH1y4qHM.d.mts +6 -0
  23. package/dist/document-CvTym-FM.mjs +50 -0
  24. package/dist/docx-C5wyjI-0.d.mts +200 -0
  25. package/dist/docx-CONyAedl.mjs +1231 -0
  26. package/dist/editor-Bf3CxQnY.mjs +21 -0
  27. package/dist/editor-DReY3Rb9.d.mts +21 -0
  28. package/dist/editor.d.mts +1 -20
  29. package/dist/editor.mjs +1 -19
  30. package/dist/emoji-BZ1dJD7d.d.mts +17 -0
  31. package/dist/emoji-C2OsTWR7.mjs +27 -0
  32. package/dist/extensions/blockquote.d.mts +23 -0
  33. package/dist/extensions/blockquote.mjs +3 -0
  34. package/dist/extensions/code-block.d.mts +19 -0
  35. package/dist/extensions/code-block.mjs +2 -0
  36. package/dist/extensions/column-break.d.mts +31 -0
  37. package/dist/extensions/column-break.mjs +2 -0
  38. package/dist/extensions/details.d.mts +19 -0
  39. package/dist/extensions/details.mjs +3 -0
  40. package/dist/extensions/document.d.mts +2 -0
  41. package/dist/extensions/document.mjs +2 -0
  42. package/dist/extensions/emoji.d.mts +2 -0
  43. package/dist/extensions/emoji.mjs +2 -0
  44. package/dist/extensions/extensions.d.mts +6 -5
  45. package/dist/extensions/extensions.mjs +14 -12
  46. package/dist/extensions/formatting-marks.d.mts +32 -0
  47. package/dist/extensions/formatting-marks.mjs +2 -0
  48. package/dist/extensions/heading.mjs +1 -144
  49. package/dist/extensions/image-group.d.mts +6 -0
  50. package/dist/extensions/image-group.mjs +2 -0
  51. package/dist/extensions/image.d.mts +2 -2
  52. package/dist/extensions/image.mjs +1 -200
  53. package/dist/extensions/index.d.mts +3 -2
  54. package/dist/extensions/index.mjs +3 -2
  55. package/dist/extensions/mention.d.mts +25 -0
  56. package/dist/extensions/mention.mjs +3 -0
  57. package/dist/extensions/ordered-list.d.mts +25 -0
  58. package/dist/extensions/ordered-list.mjs +3 -0
  59. package/dist/extensions/page-break.d.mts +34 -0
  60. package/dist/extensions/page-break.mjs +2 -0
  61. package/dist/extensions/paragraph.d.mts +1 -1
  62. package/dist/extensions/paragraph.mjs +1 -115
  63. package/dist/extensions/passthrough.d.mts +2 -0
  64. package/dist/extensions/passthrough.mjs +2 -0
  65. package/dist/extensions/section-break.d.mts +27 -0
  66. package/dist/extensions/section-break.mjs +2 -0
  67. package/dist/extensions/strike.mjs +1 -49
  68. package/dist/extensions/table-cell.mjs +1 -111
  69. package/dist/extensions/table-header.mjs +1 -111
  70. package/dist/extensions/table-row.mjs +1 -83
  71. package/dist/extensions/table.mjs +1 -133
  72. package/dist/extensions/task-item.d.mts +27 -0
  73. package/dist/extensions/task-item.mjs +3 -0
  74. package/dist/extensions/text-style.mjs +1 -133
  75. package/dist/extensions/tiptap.mjs +1 -32
  76. package/dist/extensions/types.d.mts +7 -5
  77. package/dist/extensions/utils.d.mts +16 -3
  78. package/dist/extensions/utils.mjs +2 -289
  79. package/dist/heading-DAubgJJN.mjs +166 -0
  80. package/dist/html-DCC_DSHv.d.mts +18 -0
  81. package/dist/html-DedDWPoO.mjs +66 -0
  82. package/dist/image-CuEIXoZl.mjs +334 -0
  83. package/dist/index.d.mts +68 -18
  84. package/dist/index.mjs +10 -8
  85. package/dist/markdown-BzJmRsBs.mjs +18 -0
  86. package/dist/markdown-D0k0sRYS.d.mts +13 -0
  87. package/dist/mention-C-dTR6MK.mjs +44 -0
  88. package/dist/ordered-list-V-3xFQmV.mjs +41 -0
  89. package/dist/paragraph-BrWH-BOV.mjs +147 -0
  90. package/dist/paragraph-D8mpHo_o.d.mts +8 -0
  91. package/dist/patch-Cdp5WKJz.d.mts +53 -0
  92. package/dist/patch-IZ13tXTu.mjs +36 -0
  93. package/dist/prepare-Bdk8Cjkf.mjs +122 -0
  94. package/dist/prepare-CPAvcv6q.d.mts +63 -0
  95. package/dist/strike-hWxShOgb.mjs +50 -0
  96. package/dist/styles-QSX3RhxK.mjs +285 -0
  97. package/dist/styles-ugspkrxz.d.mts +85 -0
  98. package/dist/table-DrA12lxX.mjs +159 -0
  99. package/dist/table-cell-DmkfYwDc.mjs +112 -0
  100. package/dist/table-header-Bwr5GKWg.mjs +112 -0
  101. package/dist/table-row-vew1y7WH.mjs +84 -0
  102. package/dist/task-item-BnlXGrIG.mjs +37 -0
  103. package/dist/text-style-tMeBq5XQ.mjs +151 -0
  104. package/dist/tiptap-D7pl4I5U.mjs +33 -0
  105. package/dist/utils-BPT4tjcn.mjs +333 -0
  106. package/package.json +3 -2
  107. package/dist/core-CFIQVRfx.mjs +0 -88
  108. package/dist/core-omBKMRtl.d.mts +0 -34
  109. package/dist/image-Ge1y6uam.d.mts +0 -47
  110. package/dist/paragraph-fhEXtAN2.d.mts +0 -16
@@ -1,289 +1,2 @@
1
- //#region src/extensions/utils.ts
2
- /** Common CSS named colors hex */
3
- const CSS_COLORS = {
4
- black: "#000000",
5
- white: "#FFFFFF",
6
- red: "#FF0000",
7
- green: "#008000",
8
- blue: "#0000FF",
9
- yellow: "#FFFF00",
10
- cyan: "#00FFFF",
11
- magenta: "#FF00FF",
12
- gray: "#808080",
13
- grey: "#808080",
14
- orange: "#FFA500",
15
- purple: "#800080",
16
- pink: "#FFC0CB",
17
- brown: "#A52A2A",
18
- lime: "#00FF00",
19
- navy: "#000080",
20
- teal: "#008080",
21
- silver: "#C0C0C0",
22
- maroon: "#800000",
23
- olive: "#808000",
24
- aqua: "#00FFFF",
25
- fuchsia: "#FF00FF",
26
- indigo: "#4B0082",
27
- violet: "#EE82EE",
28
- coral: "#FF7F50",
29
- gold: "#FFD700",
30
- salmon: "#FA8072",
31
- tomato: "#FF6347"
32
- };
33
- /** Normalize a CSS color value to hex (e.g., "red" → "#FF0000", "#ff0000" → "#FF0000"). */
34
- function normalizeColorToHex(color) {
35
- if (!color) return void 0;
36
- if (color.startsWith("#")) return color.length === 4 ? `#${color[1]}${color[1]}${color[2]}${color[2]}${color[3]}${color[3]}`.toUpperCase() : color.toUpperCase();
37
- if (/^[0-9A-Fa-f]{6}$/.test(color)) return `#${color.toUpperCase()}`;
38
- if (/^[0-9A-Fa-f]{3}$/.test(color)) return `#${color[0]}${color[0]}${color[1]}${color[1]}${color[2]}${color[2]}`.toUpperCase();
39
- return CSS_COLORS[color.toLowerCase()] ?? void 0;
40
- }
41
- /** Resolve a font value (string or OOXML rFonts { ascii, eastAsia, hAnsi, cs }) to a CSS family name. */
42
- function resolveFontName(font) {
43
- if (!font) return null;
44
- if (typeof font === "string") return font;
45
- if (typeof font === "object") {
46
- const f = font;
47
- return f.ascii || f.hAnsi || f.eastAsia || null;
48
- }
49
- return null;
50
- }
51
- /** CSS value (e.g., "18pt") → twip number. 1 pt = 20 twips, 1 px = 15 twips (96 DPI). */
52
- function cssToTwip(value) {
53
- if (!value) return void 0;
54
- const match = value.match(/^([\d.]+)(pt|px|em|cm|in)?$/);
55
- if (!match) return void 0;
56
- const num = parseFloat(match[1]);
57
- switch (match[2] ?? "pt") {
58
- case "pt": return Math.round(num * 20);
59
- case "px": return Math.round(num * 15);
60
- case "in": return Math.round(num * 1440);
61
- case "cm": return Math.round(num * 567);
62
- case "em": return Math.round(num * 240);
63
- default: return Math.round(num * 20);
64
- }
65
- }
66
- /** Twip value → CSS string (e.g., 360 → "18pt"). */
67
- function twipToCss(value) {
68
- if (value == null) return null;
69
- if (typeof value === "string") return value;
70
- return `${value / 20}pt`;
71
- }
72
- const ALIGNMENT_TO_CSS = {
73
- left: "left",
74
- center: "center",
75
- right: "right",
76
- start: "start",
77
- end: "end",
78
- both: "justify",
79
- distribute: "justify"
80
- };
81
- const CSS_TO_ALIGNMENT = {
82
- left: "left",
83
- center: "center",
84
- right: "right",
85
- start: "start",
86
- end: "end",
87
- justify: "both"
88
- };
89
- /** OOXML alignment → CSS text-align. */
90
- function alignmentToCss(alignment) {
91
- if (!alignment) return null;
92
- return ALIGNMENT_TO_CSS[alignment] ?? null;
93
- }
94
- /** CSS text-align → OOXML alignment. */
95
- function alignmentFromCss(css) {
96
- if (!css) return null;
97
- return CSS_TO_ALIGNMENT[css] ?? null;
98
- }
99
- /** Shading.fill → CSS background-color hex. */
100
- function shadingToCss(shading) {
101
- if (!shading?.fill) return null;
102
- return normalizeColorToHex(shading.fill) ?? null;
103
- }
104
- /** CSS background-color → ShadingAttributesProperties (fill normalized to hex). */
105
- function shadingFromCss(css) {
106
- const hex = normalizeColorToHex(css ?? void 0);
107
- return hex ? {
108
- fill: hex,
109
- type: "clear"
110
- } : null;
111
- }
112
- function lineSpacingToCss(spacing) {
113
- if (!spacing?.line) return null;
114
- const rule = spacing.lineRule;
115
- if (rule === "exact" || rule === "exactly" || rule === "atLeast") return `${spacing.line / 20}pt`;
116
- const multiple = Number((spacing.line / 240).toFixed(2));
117
- return String(multiple);
118
- }
119
- function sizeToCss(size) {
120
- if (size == null) return null;
121
- return `${size}pt`;
122
- }
123
- function sizeFromCss(css) {
124
- if (!css) return null;
125
- const m = css.match(/^([\d.]+)(pt|px)?$/);
126
- if (!m) return null;
127
- const num = parseFloat(m[1]);
128
- return (m[2] ?? "pt") === "px" ? num * .75 : num;
129
- }
130
- function characterSpacingToCss(spacing) {
131
- if (spacing == null) return null;
132
- return `${spacing / 20}pt`;
133
- }
134
- function characterSpacingFromCss(css) {
135
- if (!css) return null;
136
- const m = css.match(/^(-?[\d.]+)pt$/);
137
- return m ? Math.round(parseFloat(m[1]) * 20) : null;
138
- }
139
- /** Render a BorderOptions to CSS string. OOXML border.size is in eighths of a point. */
140
- function renderBorderCSS(border) {
141
- if (!border || border.style === "none") return null;
142
- const size = border.size != null ? `${border.size / 8}pt` : "1pt";
143
- const cssStyle = {
144
- single: "solid",
145
- dashed: "dashed",
146
- dotted: "dotted",
147
- double: "double",
148
- dotDash: "dashed",
149
- dotDotDash: "dotted"
150
- }[border.style || "single"] || "solid";
151
- const hex = border.color && border.color !== "auto" ? normalizeColorToHex(border.color) : null;
152
- return hex ? `${cssStyle} ${size} ${hex}` : `${cssStyle} ${size}`;
153
- }
154
- /**
155
- * Compute all paragraph-level CSS styles from nested attrs.
156
- * Shared by Paragraph and Heading extensions for node-level renderHTML.
157
- * Attrs store office-open native values; mappers here convert to CSS.
158
- */
159
- function renderParagraphStyles(attrs) {
160
- const a = attrs;
161
- const styles = [];
162
- const align = alignmentToCss(a.alignment);
163
- if (align) styles.push(`text-align:${align}`);
164
- if (a.indent) {
165
- const left = twipToCss(a.indent.left);
166
- if (left) styles.push(`margin-left:${left}`);
167
- const right = twipToCss(a.indent.right);
168
- if (right) styles.push(`margin-right:${right}`);
169
- if (a.indent.firstLine != null) {
170
- const fl = twipToCss(a.indent.firstLine);
171
- if (fl) styles.push(`text-indent:${fl}`);
172
- } else if (a.indent.hanging != null) {
173
- const h = twipToCss(a.indent.hanging);
174
- if (h) styles.push(`text-indent:-${h}`);
175
- } else if (a.indent.firstLineChars != null) styles.push(`text-indent:${a.indent.firstLineChars / 100}em`);
176
- }
177
- if (a.spacing) {
178
- const before = twipToCss(a.spacing.before);
179
- if (before) styles.push(`margin-top:${before}`);
180
- const after = twipToCss(a.spacing.after);
181
- if (after) styles.push(`margin-bottom:${after}`);
182
- const lh = lineSpacingToCss(a.spacing);
183
- if (lh) styles.push(`line-height:${lh}`);
184
- }
185
- const bg = shadingToCss(a.shading);
186
- if (bg) styles.push(`background-color:${bg}`);
187
- if (a.border) {
188
- const sides = [
189
- ["top", a.border.top],
190
- ["bottom", a.border.bottom],
191
- ["left", a.border.left],
192
- ["right", a.border.right]
193
- ];
194
- for (const [side, b] of sides) {
195
- const css = b ? renderBorderCSS(b) : null;
196
- if (css) styles.push(`border-${side}:${css}`);
197
- }
198
- }
199
- return styles;
200
- }
201
- /**
202
- * Compute table cell CSS styles from nested attrs.
203
- * Shared by TableCell and TableHeader extensions.
204
- */
205
- function renderTableCellStyles(attrs) {
206
- const a = attrs;
207
- const styles = [];
208
- if (a.noWrap) styles.push("white-space:nowrap");
209
- const bg = shadingToCss(a.shading);
210
- if (bg) styles.push(`background-color:${bg}`);
211
- if (a.verticalAlign) styles.push(`vertical-align:${a.verticalAlign}`);
212
- return styles;
213
- }
214
- /** Parse text-align → OOXML alignment. */
215
- function alignmentFromElement(el) {
216
- return alignmentFromCss(el.style.textAlign || null);
217
- }
218
- /** Parse margin-left/right + text-indent → OOXML indent (twips). */
219
- function indentFromElement(el) {
220
- const indent = {};
221
- const left = cssToTwip(el.style.marginLeft);
222
- if (left) indent.left = left;
223
- const right = cssToTwip(el.style.marginRight);
224
- if (right) indent.right = right;
225
- const ti = el.style.textIndent;
226
- if (ti) if (ti.startsWith("-")) {
227
- const h = cssToTwip(ti.slice(1));
228
- if (h) indent.hanging = h;
229
- } else {
230
- const f = cssToTwip(ti);
231
- if (f) indent.firstLine = f;
232
- }
233
- return Object.keys(indent).length > 0 ? indent : null;
234
- }
235
- /** Parse margin-top/bottom + line-height → OOXML spacing (twips). */
236
- function spacingFromElement(el) {
237
- const spacing = {};
238
- const before = cssToTwip(el.style.marginTop);
239
- if (before) spacing.before = before;
240
- const after = cssToTwip(el.style.marginBottom);
241
- if (after) spacing.after = after;
242
- const lh = el.style.lineHeight;
243
- if (lh) {
244
- const m = lh.match(/^([\d.]+)(pt|px)?$/);
245
- if (m) {
246
- const num = parseFloat(m[1]);
247
- if (m[2]) {
248
- spacing.line = Math.round(num * (m[2] === "px" ? 15 : 20));
249
- spacing.lineRule = "exact";
250
- } else {
251
- spacing.line = Math.round(num * 240);
252
- spacing.lineRule = "auto";
253
- }
254
- }
255
- }
256
- return Object.keys(spacing).length > 0 ? spacing : null;
257
- }
258
- /** Parse border-* → OOXML BordersOptions. */
259
- function bordersFromElement(el) {
260
- const borders = {};
261
- const sides = [
262
- ["top", el.style.borderTop],
263
- ["bottom", el.style.borderBottom],
264
- ["left", el.style.borderLeft],
265
- ["right", el.style.borderRight]
266
- ];
267
- for (const [side, css] of sides) {
268
- if (!css || css === "initial" || css === "none") continue;
269
- const m = css.match(/^(none|solid|dashed|dotted|double)\s+([\d.]+pt)\s+(.+)$/);
270
- if (!m) continue;
271
- borders[side] = {
272
- style: {
273
- solid: "single",
274
- dashed: "dashed",
275
- dotted: "dotted",
276
- double: "double"
277
- }[m[1]] ?? "single",
278
- size: Math.round(parseFloat(m[2]) * 8),
279
- color: m[3]
280
- };
281
- }
282
- return Object.keys(borders).length > 0 ? borders : null;
283
- }
284
- /** Parse background-color → OOXML shading. */
285
- function shadingFromElement(el) {
286
- return shadingFromCss(el.style.backgroundColor || null);
287
- }
288
- //#endregion
289
- export { alignmentFromCss, alignmentFromElement, alignmentToCss, bordersFromElement, characterSpacingFromCss, characterSpacingToCss, cssToTwip, indentFromElement, lineSpacingToCss, normalizeColorToHex, renderBorderCSS, renderParagraphStyles, renderTableCellStyles, resolveFontName, shadingFromCss, shadingFromElement, shadingToCss, sizeFromCss, sizeToCss, spacingFromElement, twipToCss };
1
+ import { S as twipToCss, _ as shadingFromElement, a as characterSpacingFromCss, b as sizeToCss, c as indentFromElement, d as renderBorderCSS, f as renderParagraphStyles, g as shadingFromCss, h as resolveFontName, i as bordersFromElement, l as lineSpacingToCss, m as renderTableCellStyles, n as alignmentFromElement, o as characterSpacingToCss, p as renderRunStyles, r as alignmentToCss, s as cssToTwip, t as alignmentFromCss, u as normalizeColorToHex, v as shadingToCss, x as spacingFromElement, y as sizeFromCss } from "../utils-BPT4tjcn.mjs";
2
+ export { alignmentFromCss, alignmentFromElement, alignmentToCss, bordersFromElement, characterSpacingFromCss, characterSpacingToCss, cssToTwip, indentFromElement, lineSpacingToCss, normalizeColorToHex, renderBorderCSS, renderParagraphStyles, renderRunStyles, renderTableCellStyles, resolveFontName, shadingFromCss, shadingFromElement, shadingToCss, sizeFromCss, sizeToCss, spacingFromElement, twipToCss };
@@ -0,0 +1,166 @@
1
+ import { m as Heading$1 } from "./tiptap-D7pl4I5U.mjs";
2
+ import { _ as shadingFromElement, c as indentFromElement, f as renderParagraphStyles, i as bordersFromElement, n as alignmentFromElement, x as spacingFromElement } from "./utils-BPT4tjcn.mjs";
3
+ //#region src/extensions/heading.ts
4
+ /**
5
+ * Heading extension with nested office-open attrs (mirrors Paragraph).
6
+ *
7
+ * Attrs mirror ParagraphPropertiesOptionsBase (alignment/indent/spacing/border/
8
+ * shading/frame as nested objects + scalar OOXML properties) plus the inherited
9
+ * Tiptap `level` (1-6, rendered: false). DOCX round-trip is near-identity:
10
+ * renderDocx/parseDocx pass attrs through and only map `level` ↔ OOXML
11
+ * `heading` (HeadingLevel literal). CSS conversion happens solely in
12
+ * renderHTML via utils mappers.
13
+ */
14
+ const HEADING_COMPILE_MAP = {
15
+ 1: "Heading1",
16
+ 2: "Heading2",
17
+ 3: "Heading3",
18
+ 4: "Heading4",
19
+ 5: "Heading5",
20
+ 6: "Heading6"
21
+ };
22
+ const HEADING_PARSE_MAP = {
23
+ Heading1: 1,
24
+ Heading2: 2,
25
+ Heading3: 3,
26
+ Heading4: 4,
27
+ Heading5: 5,
28
+ Heading6: 6,
29
+ Title: 1
30
+ };
31
+ /** HeadingLevel literals that office-open lifts from a pStyle into `heading`.
32
+ * Used to round-trip the literal via styleId (covers "Title", which level 1
33
+ * alone would collapse to "Heading1"). */
34
+ const HEADING_STYLE_IDS = new Set(Object.keys(HEADING_PARSE_MAP));
35
+ /** Runtime-only attrs the TableOfContents extension injects on each heading
36
+ * (`id` / `data-toc-id`). They are regenerated on every load, so never persist
37
+ * them to DOCX — skip them in renderDocx. */
38
+ const TOC_RUNTIME_KEYS = new Set(["id", "data-toc-id"]);
39
+ function renderDocx(node) {
40
+ const attrs = node.attrs ?? {};
41
+ const opts = {};
42
+ const level = attrs.level;
43
+ const styleId = attrs.styleId;
44
+ if (styleId && HEADING_STYLE_IDS.has(styleId)) opts.heading = styleId;
45
+ else if (level) opts.heading = HEADING_COMPILE_MAP[level] ?? "Heading1";
46
+ for (const [key, value] of Object.entries(attrs)) {
47
+ if (key === "level" || key === "styleId" || TOC_RUNTIME_KEYS.has(key)) continue;
48
+ if (value !== null && value !== void 0) opts[key] = value;
49
+ }
50
+ return opts;
51
+ }
52
+ /** Structural/semantic keys expressed elsewhere (heading handled separately, list handling, run children). */
53
+ const SKIP_KEYS = new Set([
54
+ "heading",
55
+ "style",
56
+ "bullet",
57
+ "numbering",
58
+ "run",
59
+ "children",
60
+ "text",
61
+ "thematicBreak"
62
+ ]);
63
+ function parseDocx(opts) {
64
+ const resolved = typeof opts === "string" ? { text: opts } : opts;
65
+ const attrs = {};
66
+ if (resolved.heading) {
67
+ const level = HEADING_PARSE_MAP[resolved.heading];
68
+ if (level) attrs.level = level;
69
+ attrs.styleId = resolved.heading;
70
+ }
71
+ if (resolved.style) attrs.styleId = resolved.style;
72
+ for (const [key, value] of Object.entries(resolved)) {
73
+ if (SKIP_KEYS.has(key)) continue;
74
+ attrs[key] = value ?? null;
75
+ }
76
+ return attrs;
77
+ }
78
+ const attrNative = () => ({
79
+ default: null,
80
+ parseHTML: () => null,
81
+ rendered: false
82
+ });
83
+ const Heading = Heading$1.extend({
84
+ addAttributes() {
85
+ return {
86
+ ...this.parent?.(),
87
+ styleId: {
88
+ default: null,
89
+ parseHTML: (el) => {
90
+ const m = (el.getAttribute("class") || "").match(/(?:^|\s)docx-style-(\S+)/);
91
+ return m ? m[1] : null;
92
+ }
93
+ },
94
+ alignment: {
95
+ default: null,
96
+ rendered: false,
97
+ parseHTML: (el) => alignmentFromElement(el)
98
+ },
99
+ indent: {
100
+ default: null,
101
+ rendered: false,
102
+ parseHTML: (el) => indentFromElement(el)
103
+ },
104
+ spacing: {
105
+ default: null,
106
+ rendered: false,
107
+ parseHTML: (el) => spacingFromElement(el)
108
+ },
109
+ shading: {
110
+ default: null,
111
+ rendered: false,
112
+ parseHTML: (el) => shadingFromElement(el)
113
+ },
114
+ border: {
115
+ default: null,
116
+ rendered: false,
117
+ parseHTML: (el) => bordersFromElement(el)
118
+ },
119
+ frame: attrNative(),
120
+ keepNext: attrNative(),
121
+ keepLines: attrNative(),
122
+ pageBreakBefore: attrNative(),
123
+ widowControl: attrNative(),
124
+ contextualSpacing: attrNative(),
125
+ bidirectional: attrNative(),
126
+ outlineLevel: attrNative(),
127
+ textDirection: attrNative(),
128
+ textAlignment: attrNative(),
129
+ suppressLineNumbers: attrNative(),
130
+ wordWrap: attrNative(),
131
+ overflowPunctuation: attrNative(),
132
+ autoSpaceEastAsianText: attrNative(),
133
+ suppressOverlap: attrNative(),
134
+ suppressAutoHyphens: attrNative(),
135
+ adjustRightInd: attrNative(),
136
+ snapToGrid: attrNative(),
137
+ mirrorIndents: attrNative(),
138
+ kinsoku: attrNative(),
139
+ topLinePunct: attrNative(),
140
+ autoSpaceDE: attrNative(),
141
+ textboxTightWrap: attrNative(),
142
+ rightTabStop: attrNative(),
143
+ leftTabStop: attrNative(),
144
+ divId: attrNative(),
145
+ tabStops: attrNative(),
146
+ cnfStyle: attrNative()
147
+ };
148
+ },
149
+ renderHTML({ node, HTMLAttributes }) {
150
+ const styles = renderParagraphStyles(node.attrs);
151
+ const level = node.attrs?.level ?? 1;
152
+ const attrs = { ...HTMLAttributes };
153
+ const styleId = node.attrs.styleId;
154
+ if (styleId) attrs.class = `docx-style-${styleId}`;
155
+ if (styles.length > 0) attrs.style = styles.join(";");
156
+ return [
157
+ `h${level}`,
158
+ attrs,
159
+ 0
160
+ ];
161
+ },
162
+ renderDocx,
163
+ parseDocx
164
+ });
165
+ //#endregion
166
+ export { parseDocx as n, renderDocx as r, Heading as t };
@@ -0,0 +1,18 @@
1
+ import { a as JSONContent, i as Extensions } from "./core-fBMCCj4D.mjs";
2
+ import { ParseOptions } from "@tiptap/pm/model";
3
+
4
+ //#region src/converters/html.d.ts
5
+ /**
6
+ * Parse HTML string to Tiptap JSON. Reads back the page background base color
7
+ * from a generateHTML wrapper div (pattern image is lost — OOXML patterns have
8
+ * no HTML equivalent; the DOCX round-trip preserves the full background).
9
+ */
10
+ declare function parseHTML(html: string, extensions?: Extensions, options?: ParseOptions): JSONContent;
11
+ /**
12
+ * Generate HTML string from Tiptap JSON. Wraps the content in a div carrying
13
+ * the page background (color + pattern image) so the document background is
14
+ * visible — Tiptap's DOMSerializer only serializes content nodes, not doc attrs.
15
+ */
16
+ declare function generateHTML(doc: JSONContent, extensions?: Extensions): string;
17
+ //#endregion
18
+ export { parseHTML as n, generateHTML as t };
@@ -0,0 +1,66 @@
1
+ import { s as docxExtensions } from "./core-DEqBHRzE.mjs";
2
+ import { t as encodeBase64 } from "./dist-B6B3HnVZ.mjs";
3
+ import { generateHTML, generateJSON } from "@tiptap/html";
4
+ //#region src/converters/html.ts
5
+ const defaultExtensions = docxExtensions;
6
+ /**
7
+ * Normalize a media payload to Uint8Array — JSON round-trips byte arrays as
8
+ * plain objects ({0:byte,...}), so rebuild before base64-encoding.
9
+ */
10
+ function toBytes(d) {
11
+ if (!d) return null;
12
+ if (d instanceof Uint8Array) return d;
13
+ return new Uint8Array(Object.values(d));
14
+ }
15
+ /**
16
+ * Build a CSS background style from DocumentBackgroundOptions. VML/rawXml page
17
+ * backgrounds (base fill + pattern image) reduce to a solid color (the w:color
18
+ * base fill) plus a tiled image (rawMedia) — OOXML pattern semantics can't be
19
+ * expressed in CSS, but base color + tile gives a visually close result.
20
+ */
21
+ function extractBackgroundStyle(bg) {
22
+ if (!bg || typeof bg !== "object") return void 0;
23
+ const b = bg;
24
+ let color;
25
+ if (b.color) color = b.color;
26
+ else if (b.rawXml) {
27
+ const m = b.rawXml.match(/w:color="([0-9A-Fa-f]{6})"/);
28
+ if (m) color = m[1];
29
+ }
30
+ const media = b.image?.data ?? b.rawMedia?.[0];
31
+ const bytes = toBytes(media?.data);
32
+ const styles = [];
33
+ if (color) styles.push(`background-color:#${color}`);
34
+ if (bytes) {
35
+ const type = media?.type ?? "png";
36
+ styles.push(`background-image:url(data:image/${type};base64,${encodeBase64(bytes)})`, "background-repeat:repeat");
37
+ }
38
+ return styles.length ? styles.join(";") : void 0;
39
+ }
40
+ /**
41
+ * Parse HTML string to Tiptap JSON. Reads back the page background base color
42
+ * from a generateHTML wrapper div (pattern image is lost — OOXML patterns have
43
+ * no HTML equivalent; the DOCX round-trip preserves the full background).
44
+ */
45
+ function parseHTML(html, extensions, options) {
46
+ const doc = generateJSON(html, extensions ?? defaultExtensions, options);
47
+ const m = html.match(/<div style="background-color:#([0-9A-Fa-f]{6})/);
48
+ if (m) {
49
+ if (!doc.attrs) doc.attrs = {};
50
+ doc.attrs.background = { color: m[1] };
51
+ }
52
+ return doc;
53
+ }
54
+ /**
55
+ * Generate HTML string from Tiptap JSON. Wraps the content in a div carrying
56
+ * the page background (color + pattern image) so the document background is
57
+ * visible — Tiptap's DOMSerializer only serializes content nodes, not doc attrs.
58
+ */
59
+ function generateHTML$1(doc, extensions) {
60
+ const html = generateHTML(doc, extensions ?? defaultExtensions);
61
+ const style = extractBackgroundStyle(doc.attrs?.background);
62
+ if (style) return `<div style="${style}">${html}</div>`;
63
+ return html;
64
+ }
65
+ //#endregion
66
+ export { parseHTML as n, generateHTML$1 as t };