@docen/docx 0.3.4 → 0.4.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.
Files changed (102) hide show
  1. package/README.md +1 -1
  2. package/dist/{blockquote-DY80QC06.d.mts → blockquote-D-1aSxEn.d.mts} +5 -1
  3. package/dist/converters/docx.d.mts +40 -66
  4. package/dist/converters/docx.mjs +251 -666
  5. package/dist/converters/html.d.mts +1 -1
  6. package/dist/converters/html.mjs +3 -4
  7. package/dist/converters/markdown.d.mts +1 -1
  8. package/dist/converters/markdown.mjs +1 -1
  9. package/dist/converters/patch.d.mts +1 -1
  10. package/dist/converters/prepare.d.mts +1 -1
  11. package/dist/converters/styles.d.mts +58 -14
  12. package/dist/converters/styles.mjs +124 -16
  13. package/dist/{core-DC0_-WcE.d.mts → core-BqyLL84S.d.mts} +34 -13
  14. package/dist/{core-BnF8XhVE.mjs → core-wNNPJiKr.mjs} +357 -25
  15. package/dist/core.d.mts +1 -1
  16. package/dist/core.mjs +1 -1
  17. package/dist/details-DsJhDP5K.d.mts +31 -0
  18. package/dist/editor.d.mts +1 -1
  19. package/dist/editor.mjs +1 -1
  20. package/dist/extensions/blockquote.d.mts +2 -3
  21. package/dist/extensions/blockquote.mjs +50 -2
  22. package/dist/extensions/bullet-list.mjs +1 -1
  23. package/dist/extensions/code-block.d.mts +2 -2
  24. package/dist/extensions/code-block.mjs +51 -5
  25. package/dist/extensions/column-break.d.mts +2 -2
  26. package/dist/extensions/column-break.mjs +2 -2
  27. package/dist/extensions/details.d.mts +2 -3
  28. package/dist/extensions/details.mjs +48 -2
  29. package/dist/extensions/document.mjs +1 -1
  30. package/dist/extensions/extensions.d.mts +13 -9
  31. package/dist/extensions/extensions.mjs +7 -3
  32. package/dist/extensions/formatting-marks.d.mts +1 -1
  33. package/dist/extensions/formatting-marks.mjs +1 -1
  34. package/dist/extensions/heading.d.mts +2 -2
  35. package/dist/extensions/heading.mjs +61 -5
  36. package/dist/extensions/image.d.mts +2 -2
  37. package/dist/extensions/image.mjs +23 -4
  38. package/dist/extensions/index.d.mts +14 -10
  39. package/dist/extensions/index.mjs +8 -4
  40. package/dist/extensions/link.d.mts +2 -2
  41. package/dist/extensions/link.mjs +30 -2
  42. package/dist/extensions/list-aggregator.d.mts +8 -0
  43. package/dist/extensions/list-aggregator.mjs +2 -0
  44. package/dist/extensions/marks.d.mts +2 -0
  45. package/dist/extensions/marks.mjs +41 -0
  46. package/dist/extensions/mention.d.mts +2 -3
  47. package/dist/extensions/mention.mjs +16 -2
  48. package/dist/extensions/ordered-list.mjs +1 -1
  49. package/dist/extensions/page-break.d.mts +2 -2
  50. package/dist/extensions/page-break.mjs +2 -2
  51. package/dist/extensions/paragraph.mjs +3 -3
  52. package/dist/extensions/passthrough.d.mts +1 -1
  53. package/dist/extensions/passthrough.mjs +1 -1
  54. package/dist/extensions/scroll.d.mts +1 -1
  55. package/dist/extensions/scroll.mjs +30 -5
  56. package/dist/extensions/section-break.d.mts +1 -1
  57. package/dist/extensions/section-break.mjs +1 -1
  58. package/dist/extensions/strike.d.mts +2 -2
  59. package/dist/extensions/strike.mjs +5 -24
  60. package/dist/extensions/tab.d.mts +2 -2
  61. package/dist/extensions/tab.mjs +2 -2
  62. package/dist/extensions/table-cell.mjs +2 -2
  63. package/dist/extensions/table-header.mjs +2 -2
  64. package/dist/extensions/table-row.mjs +2 -2
  65. package/dist/extensions/table.d.mts +2 -2
  66. package/dist/extensions/table.mjs +122 -11
  67. package/dist/extensions/task-item.d.mts +2 -3
  68. package/dist/extensions/task-item.mjs +2 -2
  69. package/dist/extensions/text-style.d.mts +2 -2
  70. package/dist/extensions/text-style.mjs +27 -28
  71. package/dist/extensions/toc-field.d.mts +2 -2
  72. package/dist/extensions/toc-field.mjs +2 -2
  73. package/dist/extensions/track-change.d.mts +2 -0
  74. package/dist/extensions/track-change.mjs +2 -0
  75. package/dist/extensions/types.d.mts +127 -8
  76. package/dist/extensions/utils.d.mts +2 -2
  77. package/dist/extensions/utils.mjs +74 -1
  78. package/dist/extensions/wpg-group.d.mts +2 -2
  79. package/dist/extensions/wpg-group.mjs +2 -2
  80. package/dist/extensions/wps-shape.d.mts +2 -2
  81. package/dist/extensions/wps-shape.mjs +2 -2
  82. package/dist/heading-Bwpa8iZY.d.mts +24 -0
  83. package/dist/index.d.mts +29 -11
  84. package/dist/index.mjs +9 -5
  85. package/dist/{link-BawPjQZR.d.mts → link-gUqW45mE.d.mts} +3 -1
  86. package/dist/marks-Dz9Vb22Q.d.mts +10 -0
  87. package/dist/{mention-BGLzLVYw.d.mts → mention-CkONDrw9.d.mts} +5 -1
  88. package/dist/{scroll-ZNeThJsJ.d.mts → scroll-BARiZ5Gm.d.mts} +9 -3
  89. package/dist/strike-Brn9sWFy.d.mts +16 -0
  90. package/dist/table-CdcjR6HD.d.mts +18 -0
  91. package/dist/{task-item-B0ntvQ1Y.d.mts → task-item-CCAC4QLi.d.mts} +3 -1
  92. package/dist/text-style-BzfcbufI.d.mts +4 -0
  93. package/dist/{utils-BJwDQts7.d.mts → utils-CfwwOowz.d.mts} +25 -1
  94. package/package.json +3 -3
  95. package/dist/details-Dd5MqqmR.d.mts +0 -17
  96. package/dist/extensions/tiptap.d.mts +0 -2
  97. package/dist/extensions/tiptap.mjs +0 -31
  98. package/dist/heading-BvqBD2zX.d.mts +0 -8
  99. package/dist/strike-BgWGvjKr.d.mts +0 -33
  100. package/dist/table-BFkfeRp9.d.mts +0 -9
  101. package/dist/text-style-BHdtXkMb.d.mts +0 -8
  102. package/dist/tiptap-BKqn41uT.d.mts +0 -31
@@ -1,2 +1,2 @@
1
- import { x as PageBreak } from "../core-BnF8XhVE.mjs";
2
- export { PageBreak };
1
+ import { I as PageBreak, L as parseDocxInline } from "../core-wNNPJiKr.mjs";
2
+ export { PageBreak, parseDocxInline };
@@ -1,5 +1,5 @@
1
- import { Paragraph as Paragraph$1 } from "./tiptap.mjs";
2
1
  import { alignmentFromElement, attrNative, bordersFromElement, indentFromElement, renderParagraphStyles, shadingFromElement, spacingFromElement } from "./utils.mjs";
2
+ import { Paragraph as Paragraph$1 } from "@tiptap/extension-paragraph";
3
3
  //#region src/extensions/paragraph.ts
4
4
  /**
5
5
  * Paragraph extension with nested office-open attrs.
@@ -9,7 +9,7 @@ import { alignmentFromElement, attrNative, bordersFromElement, indentFromElement
9
9
  * near-identity: renderDocx/parseDocx pass attrs through; CSS conversion happens
10
10
  * only in renderHTML via utils mappers.
11
11
  */
12
- const SECTION_ATTR_KEYS = new Set([
12
+ const SECTION_ATTR_KEYS = /* @__PURE__ */ new Set([
13
13
  "sectionProperties",
14
14
  "sectionHeaders",
15
15
  "sectionFooters"
@@ -46,7 +46,7 @@ function renderDocx(node) {
46
46
  * paragraph's default run properties: font/size/color) is kept as an attr for
47
47
  * lossless round-trip (e.g. header/footer paragraphs whose styling lives there).
48
48
  */
49
- const SKIP_KEYS = new Set([
49
+ const SKIP_KEYS = /* @__PURE__ */ new Set([
50
50
  "heading",
51
51
  "style",
52
52
  "bullet",
@@ -1,2 +1,2 @@
1
- import { g as Passthrough, h as InlinePassthrough } from "../core-DC0_-WcE.mjs";
1
+ import { D as Passthrough, E as InlinePassthrough } from "../core-BqyLL84S.mjs";
2
2
  export { InlinePassthrough, Passthrough };
@@ -1,2 +1,2 @@
1
- import { b as Passthrough, y as InlinePassthrough } from "../core-BnF8XhVE.mjs";
1
+ import { F as Passthrough, P as InlinePassthrough } from "../core-wNNPJiKr.mjs";
2
2
  export { InlinePassthrough, Passthrough };
@@ -1,2 +1,2 @@
1
- import { n as scrollContainerOf, t as scrollCaretToTop } from "../scroll-ZNeThJsJ.mjs";
1
+ import { n as scrollContainerOf, t as scrollCaretToTop } from "../scroll-BARiZ5Gm.mjs";
2
2
  export { scrollCaretToTop, scrollContainerOf };
@@ -3,7 +3,7 @@
3
3
  * Scroll helpers shared by the editor and the docx engine's link-click handler,
4
4
  * so every "jump then scroll" path (outline heading, search result, find, TOC
5
5
  * Ctrl+Click, post-reflow caret follow) scrolls the SAME way — to the top of the
6
- * viewport, Word-style. ProseMirror's default `tr.scrollIntoView()` parks the
6
+ * viewport, Office-style. ProseMirror's default `tr.scrollIntoView()` parks the
7
7
  * caret at the bottom edge, which reads wrong for a page/heading/TOC jump.
8
8
  */
9
9
  /** Nearest scrollable ancestor of the editor surface (e.g. the docen-canvas). */
@@ -18,16 +18,41 @@ function scrollContainerOf(view) {
18
18
  }
19
19
  return null;
20
20
  }
21
+ /** Resolve the `.docen-page` block holding `pos` (C-route pagination), or null
22
+ * when the position isn't inside a page wrapper (non-C-route). At doc start/end
23
+ * the caret maps to the editor root rather than a page, so fall back to the
24
+ * page whose vertical band contains the caret (last page at/after doc end). */
25
+ function pageElementAt(view, pos) {
26
+ const { node } = view.domAtPos(pos);
27
+ const direct = (node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement)?.closest(".docen-page");
28
+ if (direct) return direct;
29
+ const pages = view.dom.querySelectorAll(".docen-page");
30
+ if (pages.length === 0) return null;
31
+ const caretTop = view.coordsAtPos(pos).top;
32
+ for (const p of pages) if (caretTop <= p.getBoundingClientRect().bottom) return p;
33
+ return pages[pages.length - 1];
34
+ }
21
35
  /** Scroll the caret to the TOP of the viewport when it has left the visible area
22
- * (Word-style page follow). No-op while the caret stays in view, so normal
23
- * typing doesn't fight the user's scroll. Replaces PM's default scrollIntoView. */
36
+ * (Office-style page follow). No-op while the caret stays in view, so normal
37
+ * typing doesn't fight the user's scroll. Replaces PM's default scrollIntoView.
38
+ *
39
+ * Follows the caret's PAGE, not the caret itself: a caret near a page's bottom
40
+ * edge (e.g. after a select-all delete leaves the caret at the end of an
41
+ * otherwise-empty page) would otherwise park that page's lower half in view,
42
+ * which reads as "scrolled to the bottom." Anchoring on the page top keeps the
43
+ * page's start in view. Falls back to the caret position outside C-route. */
24
44
  function scrollCaretToTop(view) {
25
45
  const scroller = scrollContainerOf(view);
26
46
  if (!scroller) return;
27
47
  const margin = 64;
28
- const caretTop = view.coordsAtPos(view.state.selection.head).top;
48
+ const head = view.state.selection.head;
49
+ const caretTop = view.coordsAtPos(head).top;
29
50
  const rect = scroller.getBoundingClientRect();
30
- if (caretTop < rect.top + margin || caretTop > rect.bottom - margin) scroller.scrollTop += caretTop - rect.top - margin;
51
+ if (caretTop < rect.top + margin || caretTop > rect.bottom - margin) {
52
+ const pageEl = pageElementAt(view, head);
53
+ const anchorTop = pageEl ? pageEl.getBoundingClientRect().top : caretTop;
54
+ scroller.scrollTop += anchorTop - rect.top - margin;
55
+ }
31
56
  }
32
57
  //#endregion
33
58
  export { scrollCaretToTop, scrollContainerOf };
@@ -1,2 +1,2 @@
1
- import { P as SectionBreak } from "../core-DC0_-WcE.mjs";
1
+ import { Z as SectionBreak } from "../core-BqyLL84S.mjs";
2
2
  export { SectionBreak };
@@ -1,2 +1,2 @@
1
- import { v as SectionBreak } from "../core-BnF8XhVE.mjs";
1
+ import { N as SectionBreak } from "../core-wNNPJiKr.mjs";
2
2
  export { SectionBreak };
@@ -1,2 +1,2 @@
1
- import { n as parseDocx, r as renderDocx, t as Strike } from "../strike-BgWGvjKr.mjs";
2
- export { Strike, parseDocx, renderDocx };
1
+ import { t as Strike } from "../strike-Brn9sWFy.mjs";
2
+ export { Strike };
@@ -1,5 +1,5 @@
1
- import { Strike as Strike$1 } from "./tiptap.mjs";
2
1
  import { attrNative } from "./utils.mjs";
2
+ import { Strike as Strike$1 } from "@tiptap/extension-strike";
3
3
  //#region src/extensions/strike.ts
4
4
  /**
5
5
  * Strike mark extension with nested office-open attrs.
@@ -8,30 +8,11 @@ import { attrNative } from "./utils.mjs";
8
8
  * `strike` (single) and `doubleStrike` (double). The mark itself is "single
9
9
  * strikethrough"; the `doubleStrike` attr flips it to double. DOCX round-trip
10
10
  * is near-identity for the doubleStrike flag; `strike` itself is implied by the
11
- * mark's presence and handled in renderDocx/parseDocx.
11
+ * mark's presence.
12
12
  *
13
13
  * Mark attribute-level renderHTML is delegated to the base Strike extension
14
14
  * (renders `<s>`); only the DOCX flag needs custom handling.
15
15
  */
16
- /**
17
- * attrs → run properties.
18
- *
19
- * The mark presence itself means single strikethrough. When `doubleStrike` is
20
- * set, emit the OOXML double-strike flag instead (the two are mutually
21
- * exclusive in OOXML). DocxManager calls this with `mark.attrs`.
22
- */
23
- function renderDocx(attrs) {
24
- return attrs.doubleStrike ? { doubleStrike: true } : { strike: true };
25
- }
26
- /**
27
- * run properties → attrs.
28
- *
29
- * Only the `doubleStrike` flag needs to round-trip; single strike is implied by
30
- * the mark's existence. `strike` is structural/semantic (the mark) and skipped.
31
- */
32
- function parseDocx(runOpts) {
33
- return { doubleStrike: runOpts.doubleStrike ?? null };
34
- }
35
16
  const Strike = Strike$1.extend({
36
17
  addAttributes() {
37
18
  return {
@@ -39,8 +20,8 @@ const Strike = Strike$1.extend({
39
20
  doubleStrike: attrNative()
40
21
  };
41
22
  },
42
- renderDocx,
43
- parseDocx
23
+ renderDocx: (attrs) => attrs.doubleStrike ? { doubleStrike: true } : { strike: true },
24
+ parseDocx: (runOpts) => runOpts.strike ? { doubleStrike: runOpts.doubleStrike ?? null } : null
44
25
  });
45
26
  //#endregion
46
- export { Strike, parseDocx, renderDocx };
27
+ export { Strike };
@@ -1,2 +1,2 @@
1
- import { p as Tab } from "../core-DC0_-WcE.mjs";
2
- export { Tab };
1
+ import { C as parseDocxInline, S as Tab } from "../core-BqyLL84S.mjs";
2
+ export { Tab, parseDocxInline };
@@ -1,2 +1,2 @@
1
- import { _ as Tab } from "../core-BnF8XhVE.mjs";
2
- export { Tab };
1
+ import { M as parseDocxInline, j as Tab } from "../core-wNNPJiKr.mjs";
2
+ export { Tab, parseDocxInline };
@@ -1,5 +1,5 @@
1
- import { TableCell as TableCell$1 } from "./tiptap.mjs";
2
1
  import { attrNative, bordersFromElement, renderTableCellStyles, shadingFromElement } from "./utils.mjs";
2
+ import { TableCell as TableCell$1 } from "@tiptap/extension-table";
3
3
  //#region src/extensions/table-cell.ts
4
4
  /**
5
5
  * Table cell extension with nested office-open attrs.
@@ -13,7 +13,7 @@ import { attrNative, bordersFromElement, renderTableCellStyles, shadingFromEleme
13
13
  * utils.renderTableCellStyles (consuming nested shading/verticalAlign/noWrap).
14
14
  */
15
15
  /** Tiptap structural attrs expressed via OOXML structural fields, not passed through. */
16
- const SKIP_KEYS = new Set([
16
+ const SKIP_KEYS = /* @__PURE__ */ new Set([
17
17
  "colspan",
18
18
  "rowspan",
19
19
  "colwidth",
@@ -1,5 +1,5 @@
1
- import { TableHeader as TableHeader$1 } from "./tiptap.mjs";
2
1
  import { attrNative, bordersFromElement, renderTableCellStyles, shadingFromElement } from "./utils.mjs";
2
+ import { TableHeader as TableHeader$1 } from "@tiptap/extension-table";
3
3
  //#region src/extensions/table-header.ts
4
4
  /**
5
5
  * Table header extension with nested office-open attrs (mirrors TableCell).
@@ -13,7 +13,7 @@ import { attrNative, bordersFromElement, renderTableCellStyles, shadingFromEleme
13
13
  * utils.renderTableCellStyles (consuming nested shading/verticalAlign/noWrap).
14
14
  */
15
15
  /** Tiptap structural attrs expressed via OOXML structural fields, not passed through. */
16
- const SKIP_KEYS = new Set([
16
+ const SKIP_KEYS = /* @__PURE__ */ new Set([
17
17
  "colspan",
18
18
  "rowspan",
19
19
  "colwidth",
@@ -1,5 +1,5 @@
1
- import { TableRow as TableRow$1 } from "./tiptap.mjs";
2
1
  import { attrNative, cssToTwip } from "./utils.mjs";
2
+ import { TableRow as TableRow$1 } from "@tiptap/extension-table";
3
3
  //#region src/extensions/table-row.ts
4
4
  /**
5
5
  * Table row extension with nested office-open attrs.
@@ -12,7 +12,7 @@ import { attrNative, cssToTwip } from "./utils.mjs";
12
12
  * in renderHTML.
13
13
  */
14
14
  /** Structural keys filled by DocxManager (compileTableNode). */
15
- const SKIP_KEYS = new Set(["cells"]);
15
+ const SKIP_KEYS = /* @__PURE__ */ new Set(["cells"]);
16
16
  function renderDocx(node) {
17
17
  const attrs = node.attrs ?? {};
18
18
  const opts = {};
@@ -1,2 +1,2 @@
1
- import { n as parseDocx, r as renderDocx, t as Table } from "../table-BFkfeRp9.mjs";
2
- export { Table, parseDocx, renderDocx };
1
+ import { i as renderDocx, n as parseDocx, r as parseDocxBlock, t as Table } from "../table-CdcjR6HD.mjs";
2
+ export { Table, parseDocx, parseDocxBlock, renderDocx };
@@ -1,5 +1,6 @@
1
- import { Table as Table$1 } from "./tiptap.mjs";
2
- import { alignmentFromElement, alignmentToCss, attrNative, bordersFromElement, renderBorderCSS, shadingFromElement, shadingToCss, twipToCss } from "./utils.mjs";
1
+ import { alignmentFromElement, alignmentToCss, attrNative, bordersFromElement, renderBorderCSS, shadingFromElement, shadingToCss, tableFloatToCss, twipToCss } from "./utils.mjs";
2
+ import { allBordersNone, cleanAttrs, mergeTableStyleProps } from "../converters/styles.mjs";
3
+ import { Table as Table$1 } from "@tiptap/extension-table";
3
4
  //#region src/extensions/table.ts
4
5
  /**
5
6
  * Table extension with nested office-open attrs.
@@ -10,7 +11,7 @@ import { alignmentFromElement, alignmentToCss, attrNative, bordersFromElement, r
10
11
  * rebuilds from the row/cell nodes). CSS conversion happens only in renderHTML.
11
12
  */
12
13
  /** Structural key rebuilt by DocxManager (compileTableNode walks the row nodes). */
13
- const SKIP_KEYS = new Set(["rows", "columnWidthsRevision"]);
14
+ const SKIP_KEYS = /* @__PURE__ */ new Set(["rows", "columnWidthsRevision"]);
14
15
  function renderDocx(node) {
15
16
  const attrs = node.attrs ?? {};
16
17
  const opts = {};
@@ -28,6 +29,111 @@ function parseDocx(opts) {
28
29
  }
29
30
  return attrs;
30
31
  }
32
+ /**
33
+ * Declarative block parse rule: recognize a table SectionChild and rebuild it
34
+ * as a Tiptap table node (rows/cells with colspan/rowspan recovered, the table
35
+ * style's tblBorders/tblCellMar merged in, insideH/V grid lines pushed onto
36
+ * cells, gridAfter as trailing nil-bordered cells). DocxManager dispatches
37
+ * every SectionChild through this rule before the paragraph/passthrough
38
+ * fallbacks. */
39
+ const parseDocxBlock = {
40
+ match: (child) => "table" in child,
41
+ convert: (child, ctx) => resolveTable(child.table, ctx)
42
+ };
43
+ /** Resolve a table SectionChild into a Tiptap table node. A cell is itself a
44
+ * SectionChild[] block stream, resolved recursively via ctx. */
45
+ function resolveTable(tableOpts, ctx) {
46
+ const attrs = ctx.parseNodeAttrs("table", tableOpts);
47
+ const rows = tableOpts.rows ?? [];
48
+ const content = [];
49
+ const styleProps = mergeTableStyleProps(ctx.styles?.tableStyles, tableOpts.style ?? null);
50
+ if (styleProps.borders && allBordersNone(tableOpts.borders)) tableOpts = {
51
+ ...tableOpts,
52
+ borders: styleProps.borders
53
+ };
54
+ if (styleProps.cellMargin && tableOpts.cellMargin == null && tableOpts.margins == null) tableOpts = {
55
+ ...tableOpts,
56
+ cellMargin: styleProps.cellMargin
57
+ };
58
+ const tableCellMargins = tableOpts.cellMargin ?? tableOpts.margins ?? null;
59
+ const tableBorders = tableOpts.borders ?? null;
60
+ const realBorder = (bd) => {
61
+ const b = bd;
62
+ return b && b.style && b.style !== "none" && b.style !== "nil" ? b : null;
63
+ };
64
+ const insideH = realBorder(tableBorders?.insideHorizontal);
65
+ const insideV = realBorder(tableBorders?.insideVertical);
66
+ let activeSpans = /* @__PURE__ */ new Map();
67
+ for (const row of rows) {
68
+ const rowAttrs = ctx.parseNodeAttrs("tableRow", row);
69
+ delete rowAttrs.gridAfter;
70
+ delete rowAttrs.widthAfter;
71
+ const cells = row.cells ?? [];
72
+ const cellNodes = [];
73
+ const nextActiveSpans = /* @__PURE__ */ new Map();
74
+ let colIdx = 0;
75
+ for (const cell of cells) {
76
+ const cellColspan = cell.columnSpan ?? 1;
77
+ const vMerge = cell.verticalMerge;
78
+ if (vMerge === "continue") {
79
+ const owner = activeSpans.get(colIdx);
80
+ if (owner) {
81
+ const ownerAttrs = owner.attrs ??= {};
82
+ ownerAttrs.rowspan = (ownerAttrs.rowspan ?? 1) + 1;
83
+ for (let c = colIdx; c < colIdx + cellColspan; c++) nextActiveSpans.set(c, owner);
84
+ }
85
+ colIdx += cellColspan;
86
+ continue;
87
+ }
88
+ const isHeader = row.tableHeader;
89
+ const cellAttrs = ctx.parseNodeAttrs(isHeader ? "tableHeader" : "tableCell", cell);
90
+ delete cellAttrs.verticalMerge;
91
+ if (!cellAttrs.margins && tableCellMargins) cellAttrs.margins = tableCellMargins;
92
+ if (insideH || insideV) {
93
+ if (!cellAttrs.borders) cellAttrs.borders = {};
94
+ const b = cellAttrs.borders;
95
+ if (insideH && !b.top) b.top = insideH;
96
+ if (insideH && !b.bottom) b.bottom = insideH;
97
+ if (insideV && !b.left) b.left = insideV;
98
+ if (insideV && !b.right) b.right = insideV;
99
+ }
100
+ const cellChildren = cell.children ?? [];
101
+ const cellContent = ctx.resolveBlockStream(cellChildren);
102
+ const cellNode = { type: isHeader ? "tableHeader" : "tableCell" };
103
+ if (Object.keys(cellAttrs).length > 0) cellNode.attrs = cleanAttrs(cellAttrs);
104
+ if (cellContent.length > 0) cellNode.content = cellContent;
105
+ else cellNode.content = [{ type: "paragraph" }];
106
+ if (vMerge === "restart") for (let c = colIdx; c < colIdx + cellColspan; c++) nextActiveSpans.set(c, cellNode);
107
+ cellNodes.push(cellNode);
108
+ colIdx += cellColspan;
109
+ }
110
+ const gridAfter = row.gridAfter ?? 0;
111
+ if (gridAfter > 0) {
112
+ const trailingType = row.tableHeader ? "tableHeader" : "tableCell";
113
+ const nilBorders = {
114
+ top: { style: "nil" },
115
+ right: { style: "nil" },
116
+ bottom: { style: "nil" },
117
+ left: { style: "nil" }
118
+ };
119
+ for (let c = 0; c < gridAfter; c++) cellNodes.push({
120
+ type: trailingType,
121
+ attrs: { borders: nilBorders },
122
+ content: [{ type: "paragraph" }]
123
+ });
124
+ colIdx += gridAfter;
125
+ }
126
+ activeSpans = nextActiveSpans;
127
+ const rowNode = { type: "tableRow" };
128
+ if (Object.keys(rowAttrs).length > 0) rowNode.attrs = cleanAttrs(rowAttrs);
129
+ if (cellNodes.length > 0) rowNode.content = cellNodes;
130
+ content.push(rowNode);
131
+ }
132
+ const node = { type: "table" };
133
+ if (Object.keys(attrs).length > 0) node.attrs = cleanAttrs(attrs);
134
+ if (content.length > 0) node.content = content;
135
+ return node;
136
+ }
31
137
  const Table = Table$1.extend({
32
138
  addAttributes() {
33
139
  return {
@@ -71,10 +177,13 @@ const Table = Table$1.extend({
71
177
  const a = node.attrs;
72
178
  const attrs = { ...HTMLAttributes };
73
179
  const styles = [];
74
- const align = alignmentToCss(a.alignment);
75
- if (align === "center") styles.push("margin-left:auto", "margin-right:auto");
76
- else if (align === "right") styles.push("margin-left:auto", "margin-right:0");
77
- else if (align) styles.push("margin-left:0", "margin-right:auto");
180
+ const floatStyles = tableFloatToCss(a.float);
181
+ if (floatStyles.length === 0) {
182
+ const align = alignmentToCss(a.alignment);
183
+ if (align === "center") styles.push("margin-left:auto", "margin-right:auto");
184
+ else if (align === "right") styles.push("margin-left:auto", "margin-right:0");
185
+ else if (align) styles.push("margin-left:0", "margin-right:auto");
186
+ }
78
187
  if (a.layout === "fixed") styles.push("table-layout:fixed");
79
188
  if (a.width && typeof a.width === "object") {
80
189
  const w = a.width;
@@ -82,12 +191,12 @@ const Table = Table$1.extend({
82
191
  if (w.type === "pct") {
83
192
  if (typeof w.size === "string" && w.size.includes("%")) styles.push(`width:${w.size}`);
84
193
  else if (!Number.isNaN(numSize)) styles.push(`width:${numSize / 50}%`);
85
- } else if (w.type === "auto") styles.push("width:100%");
194
+ } else if (w.type === "auto") styles.push(floatStyles.length ? "width:auto" : "width:100%");
86
195
  else if (numSize != null) {
87
196
  const css = twipToCss(numSize);
88
197
  if (css) styles.push(`width:${css}`);
89
198
  }
90
- } else styles.push("width:100%");
199
+ } else styles.push(floatStyles.length ? "width:auto" : "width:100%");
91
200
  styles.push("max-width:100%");
92
201
  if (a.indent && typeof a.indent === "object") {
93
202
  const ind = a.indent;
@@ -128,6 +237,7 @@ const Table = Table$1.extend({
128
237
  const hasCellWidths = cellPx.some((w) => w > 0);
129
238
  const tblGridPx = (a.columnWidths ?? []).map((w) => Math.round((w || 0) / 15));
130
239
  const gridPx = tblGridPx.some((w) => w > 0) ? tblGridPx : hasCellWidths ? cellPx : tblGridPx;
240
+ for (const s of floatStyles) styles.push(s);
131
241
  if (styles.length > 0) attrs.style = styles.join(";");
132
242
  if (gridPx.some((w) => w > 0)) {
133
243
  const gridTotal = gridPx.reduce((sum, w) => sum + w, 0);
@@ -149,7 +259,8 @@ const Table = Table$1.extend({
149
259
  ];
150
260
  },
151
261
  renderDocx,
152
- parseDocx
262
+ parseDocx,
263
+ parseDocxBlock
153
264
  });
154
265
  //#endregion
155
- export { Table, parseDocx, renderDocx };
266
+ export { Table, parseDocx, parseDocxBlock, renderDocx };
@@ -1,3 +1,2 @@
1
- import { A as TaskItem } from "../tiptap-BKqn41uT.mjs";
2
- import { i as readCheckboxState, n as createTaskCheckbox, r as isTaskCheckbox, t as TASK_CHECKBOX_TAG } from "../task-item-B0ntvQ1Y.mjs";
3
- export { TASK_CHECKBOX_TAG, TaskItem, createTaskCheckbox, isTaskCheckbox, readCheckboxState };
1
+ import { a as readCheckboxState, i as isTaskCheckbox, n as TaskItemBase, r as createTaskCheckbox, t as TASK_CHECKBOX_TAG } from "../task-item-CCAC4QLi.mjs";
2
+ export { TASK_CHECKBOX_TAG, TaskItemBase as TaskItem, createTaskCheckbox, isTaskCheckbox, readCheckboxState };
@@ -1,4 +1,4 @@
1
- import { TaskItem } from "./tiptap.mjs";
1
+ import { TaskItem as TaskItemBase } from "@tiptap/extension-task-item";
2
2
  //#region src/extensions/task-item.ts
3
3
  /**
4
4
  * TaskItem extension — owns the DOCX expression of a task-list checkbox.
@@ -34,4 +34,4 @@ function readCheckboxState(child) {
34
34
  return Boolean(child.sdt?.properties?.checkbox?.checked);
35
35
  }
36
36
  //#endregion
37
- export { TASK_CHECKBOX_TAG, TaskItem, createTaskCheckbox, isTaskCheckbox, readCheckboxState };
37
+ export { TASK_CHECKBOX_TAG, TaskItemBase as TaskItem, createTaskCheckbox, isTaskCheckbox, readCheckboxState };
@@ -1,2 +1,2 @@
1
- import { n as parseDocx, r as renderDocx, t as TextStyle } from "../text-style-BHdtXkMb.mjs";
2
- export { TextStyle, parseDocx, renderDocx };
1
+ import { t as TextStyle } from "../text-style-BzfcbufI.mjs";
2
+ export { TextStyle };
@@ -1,5 +1,5 @@
1
- import { TextStyle as TextStyle$1 } from "./tiptap.mjs";
2
1
  import { attrNative, characterSpacingFromCss, characterSpacingToCss, normalizeColorToHex, resolveFontFamilyCss, shadingFromCss, shadingToCss, sizeFromCss, sizeToCss } from "./utils.mjs";
2
+ import { TextStyle as TextStyle$1 } from "@tiptap/extension-text-style";
3
3
  //#region src/extensions/text-style.ts
4
4
  /**
5
5
  * TextStyle mark with office-open attrs.
@@ -10,7 +10,7 @@ import { attrNative, characterSpacingFromCss, characterSpacingToCss, normalizeCo
10
10
  * CSS conversion happens only in attribute-level renderHTML/parseHTML.
11
11
  */
12
12
  /** Structural/semantic keys expressed elsewhere (run children/text, style name). */
13
- const SKIP_KEYS = new Set([
13
+ const SKIP_KEYS = /* @__PURE__ */ new Set([
14
14
  "children",
15
15
  "text",
16
16
  "style",
@@ -22,29 +22,6 @@ const SKIP_KEYS = new Set([
22
22
  "subScript",
23
23
  "superScript"
24
24
  ]);
25
- function renderDocx(attrs) {
26
- const opts = {};
27
- for (const [key, value] of Object.entries(attrs)) {
28
- if (SKIP_KEYS.has(key)) continue;
29
- if (value === null || value === void 0) continue;
30
- if (key === "styleId") {
31
- opts.style = value;
32
- continue;
33
- }
34
- opts[key] = value;
35
- }
36
- return opts;
37
- }
38
- function parseDocx(opts) {
39
- const resolved = typeof opts === "string" ? { text: opts } : opts;
40
- const attrs = {};
41
- if (resolved.style) attrs.styleId = resolved.style;
42
- for (const [key, value] of Object.entries(resolved)) {
43
- if (SKIP_KEYS.has(key)) continue;
44
- attrs[key] = value ?? null;
45
- }
46
- return attrs;
47
- }
48
25
  const TextStyle = TextStyle$1.extend({
49
26
  addAttributes() {
50
27
  return {
@@ -139,8 +116,30 @@ const TextStyle = TextStyle$1.extend({
139
116
  contentPartRId: attrNative()
140
117
  };
141
118
  },
142
- renderDocx,
143
- parseDocx
119
+ renderDocx: (attrs) => {
120
+ const opts = {};
121
+ for (const [key, value] of Object.entries(attrs)) {
122
+ if (SKIP_KEYS.has(key)) continue;
123
+ if (value === null || value === void 0) continue;
124
+ if (key === "styleId") {
125
+ opts.style = value;
126
+ continue;
127
+ }
128
+ opts[key] = value;
129
+ }
130
+ return opts;
131
+ },
132
+ parseDocx: (opts) => {
133
+ const resolved = typeof opts === "string" ? { text: opts } : opts;
134
+ const attrs = {};
135
+ if (resolved.style && resolved.style !== "CodeChar") attrs.styleId = resolved.style;
136
+ for (const [key, value] of Object.entries(resolved)) {
137
+ if (SKIP_KEYS.has(key)) continue;
138
+ if (resolved.style === "CodeChar" && key === "font") continue;
139
+ attrs[key] = value ?? null;
140
+ }
141
+ return Object.keys(attrs).length ? attrs : null;
142
+ }
144
143
  });
145
144
  //#endregion
146
- export { TextStyle, parseDocx, renderDocx };
145
+ export { TextStyle };
@@ -1,2 +1,2 @@
1
- import { m as TocField } from "../core-DC0_-WcE.mjs";
2
- export { TocField };
1
+ import { T as parseDocxBlock, w as TocField } from "../core-BqyLL84S.mjs";
2
+ export { TocField, parseDocxBlock };
@@ -1,2 +1,2 @@
1
- import { g as TocField } from "../core-BnF8XhVE.mjs";
2
- export { TocField };
1
+ import { A as parseDocxBlock, k as TocField } from "../core-wNNPJiKr.mjs";
2
+ export { TocField, parseDocxBlock };
@@ -0,0 +1,2 @@
1
+ import { U as Deletion, W as Insertion } from "../core-BqyLL84S.mjs";
2
+ export { Deletion, Insertion };
@@ -0,0 +1,2 @@
1
+ import { D as Deletion, O as Insertion } from "../core-wNNPJiKr.mjs";
2
+ export { Deletion, Insertion };