@harbour-enterprises/superdoc 0.20.0-next.14 → 0.20.0-next.15

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 (107) hide show
  1. package/dist/chunks/{PdfViewer-_NPRPRHl.es.js → PdfViewer-D3gJ5ozH.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-D-erp24R.cjs → PdfViewer-DuEWa8ox.cjs} +1 -1
  3. package/dist/chunks/{index-duHcNiwD.cjs → index-D2h9q27o.cjs} +31 -8
  4. package/dist/chunks/{index-dMbV_syB.es.js → index-DiSIyVKk.es.js} +31 -8
  5. package/dist/chunks/{super-editor.es-BKurmwFy.es.js → super-editor.es-4Ig7dBJr.es.js} +2846 -851
  6. package/dist/chunks/{super-editor.es-ly_a915J.cjs → super-editor.es-lzaBZOn2.cjs} +2846 -851
  7. package/dist/core/SuperDoc.d.ts.map +1 -1
  8. package/dist/stores/comments-store.d.ts.map +1 -1
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-Brf9NxwA.js → converter-BJVy6JMW.js} +1971 -636
  11. package/dist/super-editor/chunks/{docx-zipper-Dld3TtPb.js → docx-zipper-DWDJGX0b.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-N0dhAC41.js → editor-BUCOmU2Y.js} +1026 -410
  13. package/dist/super-editor/chunks/{toolbar-CXinz1gO.js → toolbar-CiBIcgiI.js} +2 -2
  14. package/dist/super-editor/converter.es.js +1 -1
  15. package/dist/super-editor/docx-zipper.es.js +2 -2
  16. package/dist/super-editor/editor.es.js +3 -3
  17. package/dist/super-editor/file-zipper.es.js +1 -1
  18. package/dist/super-editor/src/components/toolbar/format-negation.d.ts +5 -0
  19. package/dist/super-editor/src/core/commands/index.d.ts +1 -0
  20. package/dist/super-editor/src/core/commands/toggleMarkCascade.d.ts +42 -0
  21. package/dist/super-editor/src/core/commands/types/index.d.ts +29 -1
  22. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +5 -0
  23. package/dist/super-editor/src/core/super-converter/exporter.d.ts +8 -0
  24. package/dist/super-editor/src/core/super-converter/helpers.d.ts +2 -0
  25. package/dist/super-editor/src/core/super-converter/v2/importer/markImporter.d.ts +12 -0
  26. package/dist/super-editor/src/core/super-converter/v2/importer/runNodeImporter.d.ts +6 -6
  27. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/east-asian-regex.d.ts +1 -0
  28. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/index.d.ts +1 -0
  29. package/dist/super-editor/src/core/super-converter/v3/handlers/index.d.ts +2 -12
  30. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/index.d.ts +3 -0
  31. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/w-val.d.ts +4 -0
  32. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/b-translator.d.ts +7 -0
  33. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/index.d.ts +1 -0
  34. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/index.d.ts +2 -0
  35. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-color.d.ts +4 -0
  36. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-shade.d.ts +4 -0
  37. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-tint.d.ts +4 -0
  38. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-val.d.ts +4 -0
  39. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/color-translator.d.ts +7 -0
  40. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/index.d.ts +2 -0
  41. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/w-val.d.ts +4 -0
  42. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/highlight-translator.d.ts +4 -0
  43. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/index.d.ts +2 -0
  44. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/w-val.d.ts +4 -0
  45. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/i-translator.d.ts +7 -0
  46. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/index.d.ts +2 -0
  47. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-del.d.ts +4 -0
  48. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r-pr.d.ts +4 -0
  49. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r.d.ts +4 -0
  50. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/helpers.d.ts +40 -0
  51. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/index.d.ts +3 -0
  52. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/split-run-properties.d.ts +9 -0
  53. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/track-change-helpers.d.ts +5 -0
  54. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/index.d.ts +1 -0
  55. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/r-translator.d.ts +4 -0
  56. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/index.d.ts +2 -0
  57. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-ascii.d.ts +4 -0
  58. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-cs.d.ts +4 -0
  59. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-east-asia.d.ts +4 -0
  60. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-hansi.d.ts +4 -0
  61. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-val.d.ts +4 -0
  62. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/index.d.ts +1 -0
  63. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/rFonts-translator.d.ts +5 -0
  64. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/index.d.ts +2 -0
  65. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/w-val.d.ts +4 -0
  66. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/index.d.ts +1 -0
  67. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/rstyle-translator.d.ts +7 -0
  68. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/index.d.ts +1 -0
  69. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/rpr-translator.d.ts +5 -0
  70. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/run-property-translators.d.ts +11 -0
  71. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/index.d.ts +2 -0
  72. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/w-val.d.ts +4 -0
  73. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/strike-translator.d.ts +7 -0
  74. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/index.d.ts +2 -0
  75. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/w-val.d.ts +4 -0
  76. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/sz-translator.d.ts +4 -0
  77. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/index.d.ts +2 -0
  78. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/w-val.d.ts +4 -0
  79. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/szcs-translator.d.ts +4 -0
  80. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/index.d.ts +2 -0
  81. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-color.d.ts +4 -0
  82. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-color.d.ts +4 -0
  83. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-shade.d.ts +4 -0
  84. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-tint.d.ts +4 -0
  85. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-val.d.ts +4 -0
  86. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/u-translator.d.ts +7 -0
  87. package/dist/super-editor/src/extensions/index.d.ts +2 -2
  88. package/dist/super-editor/src/extensions/linked-styles/index.d.ts +1 -0
  89. package/dist/super-editor/src/extensions/linked-styles/underline-css.d.ts +17 -0
  90. package/dist/super-editor/src/extensions/list-item/helpers/listItemTypography.d.ts +62 -0
  91. package/dist/super-editor/src/extensions/run/commands/index.d.ts +1 -0
  92. package/dist/super-editor/src/extensions/run/commands/split-run.d.ts +1 -0
  93. package/dist/super-editor/src/extensions/run/index.d.ts +1 -0
  94. package/dist/super-editor/src/extensions/run/run.d.ts +6 -0
  95. package/dist/super-editor/src/extensions/shared/cascade-toggle.d.ts +8 -0
  96. package/dist/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +12 -0
  97. package/dist/super-editor/src/extensions/tab/tab.d.ts +4 -0
  98. package/dist/super-editor/src/tests/helpers/getParagraphText.d.ts +2 -0
  99. package/dist/super-editor/super-editor.es.js +90 -21
  100. package/dist/super-editor/toolbar.es.js +2 -2
  101. package/dist/super-editor.cjs +1 -1
  102. package/dist/super-editor.es.js +1 -1
  103. package/dist/superdoc.cjs +2 -2
  104. package/dist/superdoc.es.js +2 -2
  105. package/dist/superdoc.umd.js +2877 -859
  106. package/dist/superdoc.umd.js.map +1 -1
  107. package/package.json +1 -1
@@ -1385,7 +1385,7 @@
1385
1385
  shallowReadonlyMap
1386
1386
  );
1387
1387
  }
1388
- function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) {
1388
+ function createReactiveObject(target, isReadonly2, baseHandlers2, collectionHandlers, proxyMap) {
1389
1389
  if (!isObject$3(target)) {
1390
1390
  return target;
1391
1391
  }
@@ -1402,7 +1402,7 @@
1402
1402
  }
1403
1403
  const proxy = new Proxy(
1404
1404
  target,
1405
- targetType === 2 ? collectionHandlers : baseHandlers
1405
+ targetType === 2 ? collectionHandlers : baseHandlers2
1406
1406
  );
1407
1407
  proxyMap.set(target, proxy);
1408
1408
  return proxy;
@@ -22630,25 +22630,47 @@
22630
22630
  const defaults = xmlDoc.querySelectorAll("Default");
22631
22631
  return Array.from(defaults).map((item) => item.getAttribute("Extension"));
22632
22632
  };
22633
+ const DOCX_HIGHLIGHT_KEYWORD_MAP = /* @__PURE__ */ new Map([
22634
+ ["yellow", "FFFF00"],
22635
+ ["green", "00FF00"],
22636
+ ["blue", "0000FF"],
22637
+ ["cyan", "00FFFF"],
22638
+ ["magenta", "FF00FF"],
22639
+ ["red", "FF0000"],
22640
+ ["darkYellow", "808000"],
22641
+ ["darkGreen", "008000"],
22642
+ ["darkBlue", "000080"],
22643
+ ["darkCyan", "008080"],
22644
+ ["darkMagenta", "800080"],
22645
+ ["darkGray", "808080"],
22646
+ ["darkRed", "800000"],
22647
+ ["lightGray", "C0C0C0"],
22648
+ ["black", "000000"],
22649
+ ["white", "FFFFFF"]
22650
+ ]);
22651
+ const normalizeHexColor = (hex2) => {
22652
+ if (!hex2) return null;
22653
+ let value = hex2.replace("#", "").trim();
22654
+ if (!value) return null;
22655
+ value = value.toUpperCase();
22656
+ if (value.length === 3)
22657
+ value = value.split("").map((c2) => c2 + c2).join("");
22658
+ if (value.length === 8) value = value.slice(0, 6);
22659
+ return value;
22660
+ };
22633
22661
  const getHexColorFromDocxSystem = (docxColor) => {
22634
- const colorMap = /* @__PURE__ */ new Map([
22635
- ["yellow", "#ffff00"],
22636
- ["green", "#00ff00"],
22637
- ["blue", "#0000FFFF"],
22638
- ["cyan", "#00ffff"],
22639
- ["magenta", "#ff00ff"],
22640
- ["red", "#ff0000"],
22641
- ["darkYellow", "#808000FF"],
22642
- ["darkGreen", "#008000FF"],
22643
- ["darkBlue", "#000080"],
22644
- ["darkCyan", "#008080FF"],
22645
- ["darkMagenta", "#800080FF"],
22646
- ["darkGray", "#808080FF"],
22647
- ["darkRed", "#800000FF"],
22648
- ["lightGray", "#C0C0C0FF"],
22649
- ["black", "#000"]
22650
- ]);
22651
- return colorMap.get(docxColor) || null;
22662
+ const hex2 = DOCX_HIGHLIGHT_KEYWORD_MAP.get(docxColor);
22663
+ return hex2 ? `#${hex2}` : null;
22664
+ };
22665
+ const getDocxHighlightKeywordFromHex = (hexColor) => {
22666
+ if (!hexColor) return null;
22667
+ if (DOCX_HIGHLIGHT_KEYWORD_MAP.has(hexColor)) return hexColor;
22668
+ const normalized = normalizeHexColor(hexColor);
22669
+ if (!normalized) return null;
22670
+ for (const [keyword, hex2] of DOCX_HIGHLIGHT_KEYWORD_MAP.entries()) {
22671
+ if (hex2 === normalized) return keyword;
22672
+ }
22673
+ return null;
22652
22674
  };
22653
22675
  function isValidHexColor(color) {
22654
22676
  if (!color || typeof color !== "string") return false;
@@ -32036,37 +32058,37 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32036
32058
  };
32037
32059
  __publicField$2(_NodeTranslator, "translatorTypes", TranslatorTypes);
32038
32060
  let NodeTranslator = _NodeTranslator;
32039
- const encode$A = (attributes) => {
32061
+ const encode$17 = (attributes) => {
32040
32062
  return attributes["w:type"];
32041
32063
  };
32042
- const decode$A = (attrs) => {
32064
+ const decode$_ = (attrs) => {
32043
32065
  const { lineBreakType } = attrs;
32044
32066
  return lineBreakType;
32045
32067
  };
32046
- const attrConfig$i = Object.freeze({
32068
+ const attrConfig$F = Object.freeze({
32047
32069
  xmlName: "w:type",
32048
32070
  sdName: "lineBreakType",
32049
- encode: encode$A,
32050
- decode: decode$A
32071
+ encode: encode$17,
32072
+ decode: decode$_
32051
32073
  });
32052
- const encode$z = (attributes) => {
32074
+ const encode$16 = (attributes) => {
32053
32075
  const xmlAttrValue = attributes["w:clear"];
32054
32076
  return xmlAttrValue;
32055
32077
  };
32056
- const decode$z = (attrs) => {
32078
+ const decode$Z = (attrs) => {
32057
32079
  const { clear } = attrs;
32058
32080
  return clear;
32059
32081
  };
32060
- const attrConfig$h = Object.freeze({
32082
+ const attrConfig$E = Object.freeze({
32061
32083
  xmlName: "w:clear",
32062
32084
  sdName: "clear",
32063
- encode: encode$z,
32064
- decode: decode$z
32085
+ encode: encode$16,
32086
+ decode: decode$Z
32065
32087
  });
32066
- const validXmlAttributes$b = [attrConfig$i, attrConfig$h];
32067
- const XML_NODE_NAME$h = "w:br";
32088
+ const validXmlAttributes$l = [attrConfig$F, attrConfig$E];
32089
+ const XML_NODE_NAME$t = "w:br";
32068
32090
  const SD_NODE_NAME$c = "lineBreak";
32069
- const encode$y = (_2, encodedAttrs) => {
32091
+ const encode$15 = (_2, encodedAttrs) => {
32070
32092
  const isPageBreak = encodedAttrs?.lineBreakType === "page";
32071
32093
  const translated = {
32072
32094
  type: isPageBreak ? "hardBreak" : "lineBreak"
@@ -32076,7 +32098,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32076
32098
  }
32077
32099
  return translated;
32078
32100
  };
32079
- const decode$y = (params2, decodedAttrs) => {
32101
+ const decode$Y = (params2, decodedAttrs) => {
32080
32102
  const { node } = params2;
32081
32103
  if (!node) return;
32082
32104
  const wBreak = { name: "w:br" };
@@ -32093,63 +32115,125 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32093
32115
  };
32094
32116
  return translated;
32095
32117
  };
32096
- const config$f = {
32097
- xmlName: XML_NODE_NAME$h,
32118
+ const config$r = {
32119
+ xmlName: XML_NODE_NAME$t,
32098
32120
  sdNodeOrKeyName: SD_NODE_NAME$c,
32099
32121
  type: NodeTranslator.translatorTypes.NODE,
32100
- encode: encode$y,
32101
- decode: decode$y,
32102
- attributes: validXmlAttributes$b
32122
+ encode: encode$15,
32123
+ decode: decode$Y,
32124
+ attributes: validXmlAttributes$l
32125
+ };
32126
+ const translator$15 = NodeTranslator.from(config$r);
32127
+ const encode$14 = (attributes) => attributes?.["w:val"];
32128
+ const decode$X = (attrs) => attrs?.highlight;
32129
+ const attrConfig$D = Object.freeze({
32130
+ xmlName: "w:val",
32131
+ sdName: "highlight",
32132
+ encode: encode$14,
32133
+ decode: decode$X
32134
+ });
32135
+ const validXmlAttributes$k = [attrConfig$D];
32136
+ const XML_NODE_NAME$s = "w:highlight";
32137
+ const SD_ATTR_KEY$f = "highlight";
32138
+ const DISABLED_TOKENS = /* @__PURE__ */ new Set(["transparent", "none", "inherit"]);
32139
+ const encode$13 = (params2, encodedAttrs = {}) => {
32140
+ const { nodes } = params2;
32141
+ const node = nodes?.[0];
32142
+ const value = encodedAttrs.highlight ?? node?.attributes?.["w:val"];
32143
+ return {
32144
+ type: "attr",
32145
+ xmlName: XML_NODE_NAME$s,
32146
+ sdNodeOrKeyName: SD_ATTR_KEY$f,
32147
+ attributes: { "w:val": value ?? null }
32148
+ };
32149
+ };
32150
+ const decode$W = (params2) => {
32151
+ const attrs = params2?.node?.attrs || {};
32152
+ const highlightValue = attrs.highlight ?? attrs.color ?? null;
32153
+ if (!highlightValue) return void 0;
32154
+ const normalizedValue = String(highlightValue).trim().toLowerCase();
32155
+ if (!normalizedValue) return void 0;
32156
+ if (DISABLED_TOKENS.has(normalizedValue)) {
32157
+ return {
32158
+ name: XML_NODE_NAME$s,
32159
+ attributes: { "w:val": "none" }
32160
+ };
32161
+ }
32162
+ const keyword = getDocxHighlightKeywordFromHex(highlightValue);
32163
+ if (keyword) {
32164
+ return {
32165
+ name: XML_NODE_NAME$s,
32166
+ attributes: { "w:val": keyword }
32167
+ };
32168
+ }
32169
+ const fill = normalizeHexColor(highlightValue);
32170
+ if (!fill) return void 0;
32171
+ return {
32172
+ name: "w:shd",
32173
+ attributes: {
32174
+ "w:color": "auto",
32175
+ "w:val": "clear",
32176
+ "w:fill": fill
32177
+ }
32178
+ };
32103
32179
  };
32104
- const translator$V = NodeTranslator.from(config$f);
32105
- const encode$x = (attributes) => {
32180
+ const config$q = {
32181
+ xmlName: XML_NODE_NAME$s,
32182
+ sdNodeOrKeyName: SD_ATTR_KEY$f,
32183
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
32184
+ encode: encode$13,
32185
+ decode: decode$W,
32186
+ attributes: validXmlAttributes$k
32187
+ };
32188
+ const translator$14 = NodeTranslator.from(config$q);
32189
+ const encode$12 = (attributes) => {
32106
32190
  return attributes["w:val"];
32107
32191
  };
32108
- const decode$x = (attrs) => {
32192
+ const decode$V = (attrs) => {
32109
32193
  const { tabSize } = attrs || {};
32110
32194
  return tabSize;
32111
32195
  };
32112
- const attrConfig$g = Object.freeze({
32196
+ const attrConfig$C = Object.freeze({
32113
32197
  xmlName: "w:val",
32114
32198
  sdName: "tabSize",
32115
- encode: encode$x,
32116
- decode: decode$x
32199
+ encode: encode$12,
32200
+ decode: decode$V
32117
32201
  });
32118
- const encode$w = (attributes) => {
32202
+ const encode$11 = (attributes) => {
32119
32203
  return attributes["w:leader"];
32120
32204
  };
32121
- const decode$w = (attrs) => {
32205
+ const decode$U = (attrs) => {
32122
32206
  const { leader } = attrs || {};
32123
32207
  return leader;
32124
32208
  };
32125
- const attrConfig$f = Object.freeze({
32209
+ const attrConfig$B = Object.freeze({
32126
32210
  xmlName: "w:leader",
32127
32211
  sdName: "leader",
32128
- encode: encode$w,
32129
- decode: decode$w
32212
+ encode: encode$11,
32213
+ decode: decode$U
32130
32214
  });
32131
- const encode$v = (attributes) => {
32215
+ const encode$10 = (attributes) => {
32132
32216
  return attributes["w:pos"];
32133
32217
  };
32134
- const decode$v = (attrs) => {
32218
+ const decode$T = (attrs) => {
32135
32219
  const { pos } = attrs || {};
32136
32220
  return pos;
32137
32221
  };
32138
- const attrConfig$e = Object.freeze({
32222
+ const attrConfig$A = Object.freeze({
32139
32223
  xmlName: "w:pos",
32140
32224
  sdName: "pos",
32141
- encode: encode$v,
32142
- decode: decode$v
32225
+ encode: encode$10,
32226
+ decode: decode$T
32143
32227
  });
32144
- const validXmlAttributes$a = [attrConfig$g, attrConfig$e, attrConfig$f];
32145
- const XML_NODE_NAME$g = "w:tab";
32228
+ const validXmlAttributes$j = [attrConfig$C, attrConfig$A, attrConfig$B];
32229
+ const XML_NODE_NAME$r = "w:tab";
32146
32230
  const SD_NODE_NAME$b = "tab";
32147
- const encode$u = (_2, encodedAttrs = {}) => {
32231
+ const encode$$ = (_2, encodedAttrs = {}) => {
32148
32232
  const translated = { type: "tab" };
32149
32233
  if (encodedAttrs) translated.attrs = { ...encodedAttrs };
32150
32234
  return translated;
32151
32235
  };
32152
- const decode$u = (params2, decodedAttrs = {}) => {
32236
+ const decode$S = (params2, decodedAttrs = {}) => {
32153
32237
  const { node } = params2 || {};
32154
32238
  if (!node) return;
32155
32239
  const wTab = { name: "w:tab" };
@@ -32165,15 +32249,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32165
32249
  }
32166
32250
  return translated;
32167
32251
  };
32168
- const config$e = {
32169
- xmlName: XML_NODE_NAME$g,
32252
+ const config$p = {
32253
+ xmlName: XML_NODE_NAME$r,
32170
32254
  sdNodeOrKeyName: SD_NODE_NAME$b,
32171
32255
  type: NodeTranslator.translatorTypes.NODE,
32172
- encode: encode$u,
32173
- decode: decode$u,
32174
- attributes: validXmlAttributes$a
32256
+ encode: encode$$,
32257
+ decode: decode$S,
32258
+ attributes: validXmlAttributes$j
32175
32259
  };
32176
- const translator$U = NodeTranslator.from(config$e);
32260
+ const translator$13 = NodeTranslator.from(config$p);
32177
32261
  const mergeTextNodes = (nodes) => {
32178
32262
  if (!nodes || !Array.isArray(nodes)) {
32179
32263
  return nodes;
@@ -32348,17 +32432,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32348
32432
  function getFontFamilyValue(attributes, docx) {
32349
32433
  const ascii = attributes["w:ascii"];
32350
32434
  const themeAscii = attributes["w:asciiTheme"];
32351
- if (!docx || !themeAscii) return ascii;
32352
- const theme = docx["word/theme/theme1.xml"];
32353
- if (!theme) return ascii;
32354
- const { elements: topElements } = theme;
32355
- const { elements } = topElements[0];
32356
- const themeElements = elements.find((el) => el.name === "a:themeElements");
32357
- const fontScheme = themeElements.elements.find((el) => el.name === "a:fontScheme");
32358
- const majorFont = fontScheme.elements.find((el) => el.name === "a:majorFont");
32359
- const latin = majorFont.elements.find((el) => el.name === "a:latin");
32360
- const typeface = latin.attributes["typeface"];
32361
- return typeface;
32435
+ let resolved = ascii;
32436
+ if (docx && themeAscii) {
32437
+ const theme = docx["word/theme/theme1.xml"];
32438
+ if (theme?.elements?.length) {
32439
+ const { elements: topElements } = theme;
32440
+ const { elements } = topElements[0] || {};
32441
+ const themeElements = elements?.find((el) => el.name === "a:themeElements");
32442
+ const fontScheme = themeElements?.elements?.find((el) => el.name === "a:fontScheme");
32443
+ const majorFont = fontScheme?.elements?.find((el) => el.name === "a:majorFont");
32444
+ const latin = majorFont?.elements?.find((el) => el.name === "a:latin");
32445
+ resolved = latin?.attributes?.typeface || resolved;
32446
+ }
32447
+ }
32448
+ if (!resolved) return null;
32449
+ return SuperConverter.toCssFontFamily(resolved, docx);
32362
32450
  }
32363
32451
  function getIndentValue(attributes) {
32364
32452
  let value = attributes["w:left"];
@@ -32379,7 +32467,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32379
32467
  return getHexColorFromDocxSystem(attributes?.["w:val"]) || null;
32380
32468
  }
32381
32469
  function getStrikeValue(attributes) {
32382
- return attributes?.["w:val"] === "1" ? attributes["w:val"] : null;
32470
+ const raw = attributes?.["w:val"];
32471
+ if (raw === void 0 || raw === null) return "1";
32472
+ const value = String(raw).trim().toLowerCase();
32473
+ if (value === "1" || value === "true" || value === "on") return "1";
32474
+ return null;
32383
32475
  }
32384
32476
  const parseParagraphBorders = (pBdr) => {
32385
32477
  if (!pBdr || !pBdr.elements) return {};
@@ -32409,27 +32501,39 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32409
32501
  right: 0,
32410
32502
  firstLine: 0,
32411
32503
  hanging: 0,
32412
- textIndent: 0
32504
+ textIndent: 0,
32505
+ explicitLeft: false,
32506
+ explicitRight: false,
32507
+ explicitFirstLine: false,
32508
+ explicitHanging: false
32413
32509
  };
32414
32510
  const { indent: pDefaultIndent = {} } = getDefaultParagraphStyle(docx, styleId);
32415
32511
  const pPr = node.elements?.find((el) => el.name === "w:pPr");
32416
32512
  const inLineIndentTag = pPr?.elements?.find((el) => el.name === "w:ind");
32417
32513
  const inLineIndent = inLineIndentTag?.attributes || {};
32418
- const leftIndent = inLineIndent?.["w:left"] || pDefaultIndent?.["w:left"];
32419
- const rightIndent = inLineIndent?.["w:right"] || pDefaultIndent?.["w:right"];
32420
- const firstLine = inLineIndent?.["w:firstLine"] || pDefaultIndent?.["w:firstLine"];
32421
- const hanging = inLineIndent?.["w:hanging"] || pDefaultIndent?.["w:hanging"];
32514
+ const inlineLeft = inLineIndent?.["w:left"];
32515
+ const inlineRight = inLineIndent?.["w:right"];
32516
+ const inlineFirstLine = inLineIndent?.["w:firstLine"];
32517
+ const inlineHanging = inLineIndent?.["w:hanging"];
32518
+ const leftIndent = inlineLeft ?? pDefaultIndent?.["w:left"];
32519
+ const rightIndent = inlineRight ?? pDefaultIndent?.["w:right"];
32520
+ const firstLine = inlineFirstLine ?? pDefaultIndent?.["w:firstLine"];
32521
+ const hanging = inlineHanging ?? pDefaultIndent?.["w:hanging"];
32422
32522
  if (leftIndent) {
32423
32523
  indent.left = twipsToPixels(leftIndent);
32524
+ indent.explicitLeft = inlineLeft !== void 0;
32424
32525
  }
32425
32526
  if (rightIndent) {
32426
32527
  indent.right = twipsToPixels(rightIndent);
32528
+ indent.explicitRight = inlineRight !== void 0;
32427
32529
  }
32428
32530
  if (firstLine) {
32429
32531
  indent.firstLine = twipsToPixels(firstLine);
32532
+ indent.explicitFirstLine = inlineFirstLine !== void 0;
32430
32533
  }
32431
32534
  if (hanging) {
32432
32535
  indent.hanging = twipsToPixels(hanging);
32536
+ indent.explicitHanging = inlineHanging !== void 0;
32433
32537
  }
32434
32538
  const textIndentValue = leftIndent - parseInt(hanging || 0) || 0;
32435
32539
  if (textIndentValue) {
@@ -32768,102 +32872,102 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32768
32872
  }
32769
32873
  return schemaNode;
32770
32874
  };
32771
- const encode$t = (attributes) => {
32875
+ const encode$_ = (attributes) => {
32772
32876
  return attributes["w:rsidDel"];
32773
32877
  };
32774
- const decode$t = (attrs) => {
32878
+ const decode$R = (attrs) => {
32775
32879
  return attrs.rsidDel;
32776
32880
  };
32777
- const attrConfig$d = Object.freeze({
32881
+ const attrConfig$z = Object.freeze({
32778
32882
  xmlName: "w:rsidDel",
32779
32883
  sdName: "rsidDel",
32780
- encode: encode$t,
32781
- decode: decode$t
32884
+ encode: encode$_,
32885
+ decode: decode$R
32782
32886
  });
32783
- const encode$s = (attributes) => {
32887
+ const encode$Z = (attributes) => {
32784
32888
  return attributes["w:rsidP"];
32785
32889
  };
32786
- const decode$s = (attrs) => {
32890
+ const decode$Q = (attrs) => {
32787
32891
  return attrs.rsidP;
32788
32892
  };
32789
- const attrConfig$c = Object.freeze({
32893
+ const attrConfig$y = Object.freeze({
32790
32894
  xmlName: "w:rsidP",
32791
32895
  sdName: "rsidP",
32792
- encode: encode$s,
32793
- decode: decode$s
32896
+ encode: encode$Z,
32897
+ decode: decode$Q
32794
32898
  });
32795
- const encode$r = (attributes) => {
32899
+ const encode$Y = (attributes) => {
32796
32900
  return attributes["w:rsidR"];
32797
32901
  };
32798
- const decode$r = (attrs) => {
32902
+ const decode$P = (attrs) => {
32799
32903
  return attrs.rsidR;
32800
32904
  };
32801
- const attrConfig$b = Object.freeze({
32905
+ const attrConfig$x = Object.freeze({
32802
32906
  xmlName: "w:rsidR",
32803
32907
  sdName: "rsidR",
32804
- encode: encode$r,
32805
- decode: decode$r
32908
+ encode: encode$Y,
32909
+ decode: decode$P
32806
32910
  });
32807
- const encode$q = (attributes) => {
32911
+ const encode$X = (attributes) => {
32808
32912
  return attributes["w:rsidRPr"];
32809
32913
  };
32810
- const decode$q = (attrs) => {
32914
+ const decode$O = (attrs) => {
32811
32915
  return attrs.rsidRPr;
32812
32916
  };
32813
- const attrConfig$a = Object.freeze({
32917
+ const attrConfig$w = Object.freeze({
32814
32918
  xmlName: "w:rsidRPr",
32815
32919
  sdName: "rsidRPr",
32816
- encode: encode$q,
32817
- decode: decode$q
32920
+ encode: encode$X,
32921
+ decode: decode$O
32818
32922
  });
32819
- const encode$p = (attributes) => {
32923
+ const encode$W = (attributes) => {
32820
32924
  return attributes["w:rsidRDefault"];
32821
32925
  };
32822
- const decode$p = (attrs) => {
32926
+ const decode$N = (attrs) => {
32823
32927
  return attrs.rsidRDefault;
32824
32928
  };
32825
- const attrConfig$9 = Object.freeze({
32929
+ const attrConfig$v = Object.freeze({
32826
32930
  xmlName: "w:rsidRDefault",
32827
32931
  sdName: "rsidRDefault",
32828
- encode: encode$p,
32829
- decode: decode$p
32932
+ encode: encode$W,
32933
+ decode: decode$N
32830
32934
  });
32831
- const encode$o = (attributes) => {
32935
+ const encode$V = (attributes) => {
32832
32936
  return attributes["w14:paraId"];
32833
32937
  };
32834
- const decode$o = (attrs) => {
32938
+ const decode$M = (attrs) => {
32835
32939
  return attrs.paraId;
32836
32940
  };
32837
- const attrConfig$8 = Object.freeze({
32941
+ const attrConfig$u = Object.freeze({
32838
32942
  xmlName: "w14:paraId",
32839
32943
  sdName: "paraId",
32840
- encode: encode$o,
32841
- decode: decode$o
32944
+ encode: encode$V,
32945
+ decode: decode$M
32842
32946
  });
32843
- const encode$n = (attributes) => {
32947
+ const encode$U = (attributes) => {
32844
32948
  return attributes["w14:textId"];
32845
32949
  };
32846
- const decode$n = (attrs) => {
32950
+ const decode$L = (attrs) => {
32847
32951
  return attrs.textId;
32848
32952
  };
32849
- const attrConfig$7 = Object.freeze({
32953
+ const attrConfig$t = Object.freeze({
32850
32954
  xmlName: "w14:textId",
32851
32955
  sdName: "textId",
32852
- encode: encode$n,
32853
- decode: decode$n
32956
+ encode: encode$U,
32957
+ decode: decode$L
32854
32958
  });
32855
- const validXmlAttributes$9 = [
32856
- attrConfig$8,
32857
- attrConfig$7,
32858
- attrConfig$b,
32859
- attrConfig$9,
32860
- attrConfig$c,
32861
- attrConfig$a,
32862
- attrConfig$d
32959
+ const validXmlAttributes$i = [
32960
+ attrConfig$u,
32961
+ attrConfig$t,
32962
+ attrConfig$x,
32963
+ attrConfig$v,
32964
+ attrConfig$y,
32965
+ attrConfig$w,
32966
+ attrConfig$z
32863
32967
  ];
32864
- const XML_NODE_NAME$f = "w:p";
32968
+ const XML_NODE_NAME$q = "w:p";
32865
32969
  const SD_NODE_NAME$a = "paragraph";
32866
- const encode$m = (params2, encodedAttrs = {}) => {
32970
+ const encode$T = (params2, encodedAttrs = {}) => {
32867
32971
  const node = handleParagraphNode$1(params2);
32868
32972
  if (!node) return void 0;
32869
32973
  if (encodedAttrs && Object.keys(encodedAttrs).length) {
@@ -32871,7 +32975,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32871
32975
  }
32872
32976
  return node;
32873
32977
  };
32874
- const decode$m = (params2, decodedAttrs = {}) => {
32978
+ const decode$K = (params2, decodedAttrs = {}) => {
32875
32979
  const translated = translateParagraphNode(params2);
32876
32980
  if (!translated) return void 0;
32877
32981
  if (decodedAttrs && Object.keys(decodedAttrs).length) {
@@ -32879,9 +32983,1164 @@ Please report this to https://github.com/markedjs/marked.`, e) {
32879
32983
  }
32880
32984
  return translated;
32881
32985
  };
32986
+ const config$o = {
32987
+ xmlName: XML_NODE_NAME$q,
32988
+ sdNodeOrKeyName: SD_NODE_NAME$a,
32989
+ type: NodeTranslator.translatorTypes.NODE,
32990
+ encode: encode$T,
32991
+ decode: decode$K,
32992
+ attributes: validXmlAttributes$i
32993
+ };
32994
+ const translator$12 = NodeTranslator.from(config$o);
32995
+ const encode$S = (attributes) => {
32996
+ const raw = attributes?.["w:val"];
32997
+ if (raw === void 0 || raw === null) return void 0;
32998
+ if (typeof raw === "boolean") return raw;
32999
+ if (typeof raw === "number") return raw !== 0;
33000
+ const val = String(raw).trim().toLowerCase();
33001
+ if (val === "0" || val === "false" || val === "off") return false;
33002
+ if (val === "1" || val === "true" || val === "on") return true;
33003
+ return void 0;
33004
+ };
33005
+ const decode$J = (runProps) => {
33006
+ if (runProps?.bold === false) return "0";
33007
+ return void 0;
33008
+ };
33009
+ const attrConfig$s = Object.freeze({
33010
+ xmlName: "w:val",
33011
+ sdName: "bold",
33012
+ encode: encode$S,
33013
+ decode: decode$J
33014
+ });
33015
+ const validXmlAttributes$h = [attrConfig$s];
33016
+ const XML_NODE_NAME$p = "w:b";
33017
+ const SD_ATTR_KEY$e = "bold";
33018
+ const encode$R = (params2, encodedAttrs = {}) => {
33019
+ const { nodes } = params2;
33020
+ const node = nodes[0];
33021
+ if (!node) return void 0;
33022
+ const val = encodedAttrs?.[SD_ATTR_KEY$e];
33023
+ let attributes;
33024
+ if (val === false) attributes = { "w:val": "0" };
33025
+ else if (val === true)
33026
+ attributes = {};
33027
+ else attributes = node.attributes || {};
33028
+ return {
33029
+ type: "attr",
33030
+ xmlName: XML_NODE_NAME$p,
33031
+ sdNodeOrKeyName: SD_ATTR_KEY$e,
33032
+ attributes
33033
+ };
33034
+ };
33035
+ const config$n = {
33036
+ xmlName: XML_NODE_NAME$p,
33037
+ sdNodeOrKeyName: SD_ATTR_KEY$e,
33038
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33039
+ encode: encode$R,
33040
+ attributes: validXmlAttributes$h
33041
+ };
33042
+ const translator$11 = NodeTranslator.from(config$n);
33043
+ const XML_NODE_NAME$o = "w:i";
33044
+ const SD_ATTR_KEY$d = "italic";
33045
+ const encode$Q = (params2) => {
33046
+ const { nodes } = params2;
33047
+ const node = nodes?.[0];
33048
+ if (!node) return void 0;
33049
+ return {
33050
+ type: "attr",
33051
+ xmlName: XML_NODE_NAME$o,
33052
+ sdNodeOrKeyName: SD_ATTR_KEY$d,
33053
+ attributes: {
33054
+ "w:val": node.attributes?.["w:val"] ?? null
33055
+ }
33056
+ };
33057
+ };
33058
+ const config$m = {
33059
+ xmlName: XML_NODE_NAME$o,
33060
+ sdNodeOrKeyName: SD_ATTR_KEY$d,
33061
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33062
+ encode: encode$Q
33063
+ };
33064
+ const translator$10 = NodeTranslator.from(config$m);
33065
+ const encode$P = (attributes) => attributes?.["w:val"];
33066
+ const decode$I = (attrs) => attrs?.underline;
33067
+ const attrConfig$r = Object.freeze({
33068
+ xmlName: "w:val",
33069
+ sdName: "underline",
33070
+ encode: encode$P,
33071
+ decode: decode$I
33072
+ });
33073
+ const encode$O = (attributes) => attributes?.["w:color"];
33074
+ const decode$H = (attrs) => attrs?.color;
33075
+ const attrConfig$q = Object.freeze({
33076
+ xmlName: "w:color",
33077
+ sdName: "color",
33078
+ encode: encode$O,
33079
+ decode: decode$H
33080
+ });
33081
+ const encode$N = (attributes) => attributes?.["w:themeColor"];
33082
+ const decode$G = (attrs) => attrs?.themeColor;
33083
+ const attrConfig$p = Object.freeze({
33084
+ xmlName: "w:themeColor",
33085
+ sdName: "themeColor",
33086
+ encode: encode$N,
33087
+ decode: decode$G
33088
+ });
33089
+ const encode$M = (attributes) => attributes?.["w:themeTint"];
33090
+ const decode$F = (attrs) => attrs?.themeTint;
33091
+ const attrConfig$o = Object.freeze({
33092
+ xmlName: "w:themeTint",
33093
+ sdName: "themeTint",
33094
+ encode: encode$M,
33095
+ decode: decode$F
33096
+ });
33097
+ const encode$L = (attributes) => attributes?.["w:themeShade"];
33098
+ const decode$E = (attrs) => attrs?.themeShade;
33099
+ const attrConfig$n = Object.freeze({
33100
+ xmlName: "w:themeShade",
33101
+ sdName: "themeShade",
33102
+ encode: encode$L,
33103
+ decode: decode$E
33104
+ });
33105
+ const validXmlAttributes$g = [attrConfig$r, attrConfig$q, attrConfig$p, attrConfig$o, attrConfig$n];
33106
+ const XML_NODE_NAME$n = "w:u";
33107
+ const SD_ATTR_KEY$c = "underline";
33108
+ const encode$K = (params2, encodedAttrs = {}) => {
33109
+ const { nodes } = params2;
33110
+ const node = nodes?.[0];
33111
+ const sourceAttrs = node?.attributes || {};
33112
+ const underlineType = encodedAttrs.underline ?? sourceAttrs["w:val"];
33113
+ const color = encodedAttrs.color ?? sourceAttrs["w:color"];
33114
+ const themeColor = encodedAttrs.themeColor ?? sourceAttrs["w:themeColor"];
33115
+ const themeTint = encodedAttrs.themeTint ?? sourceAttrs["w:themeTint"];
33116
+ const themeShade = encodedAttrs.themeShade ?? sourceAttrs["w:themeShade"];
33117
+ const attributes = { "w:val": underlineType ?? null };
33118
+ if (color !== void 0 && color !== null) attributes["w:color"] = color;
33119
+ if (themeColor !== void 0 && themeColor !== null) attributes["w:themeColor"] = themeColor;
33120
+ if (themeTint !== void 0 && themeTint !== null) attributes["w:themeTint"] = themeTint;
33121
+ if (themeShade !== void 0 && themeShade !== null) attributes["w:themeShade"] = themeShade;
33122
+ return {
33123
+ type: "attr",
33124
+ xmlName: XML_NODE_NAME$n,
33125
+ sdNodeOrKeyName: SD_ATTR_KEY$c,
33126
+ attributes
33127
+ };
33128
+ };
33129
+ const decode$D = (params2) => {
33130
+ const attrs = params2?.node?.attrs || {};
33131
+ const underlineType = attrs.underlineType ?? attrs.underline ?? null;
33132
+ const color = attrs.underlineColor ?? attrs.color ?? null;
33133
+ const themeColor = attrs.underlineThemeColor ?? attrs.themeColor ?? null;
33134
+ const themeTint = attrs.underlineThemeTint ?? attrs.themeTint ?? null;
33135
+ const themeShade = attrs.underlineThemeShade ?? attrs.themeShade ?? null;
33136
+ if (!underlineType && !color && !themeColor && !themeTint && !themeShade) return void 0;
33137
+ const attributes = {};
33138
+ if (underlineType) attributes["w:val"] = underlineType;
33139
+ if (color) {
33140
+ const normalized = normalizeHexColor(color);
33141
+ if (normalized) attributes["w:color"] = normalized;
33142
+ }
33143
+ if (themeColor) attributes["w:themeColor"] = themeColor;
33144
+ if (themeTint) attributes["w:themeTint"] = themeTint;
33145
+ if (themeShade) attributes["w:themeShade"] = themeShade;
33146
+ return {
33147
+ name: XML_NODE_NAME$n,
33148
+ attributes
33149
+ };
33150
+ };
33151
+ const config$l = {
33152
+ xmlName: XML_NODE_NAME$n,
33153
+ sdNodeOrKeyName: SD_ATTR_KEY$c,
33154
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33155
+ encode: encode$K,
33156
+ decode: decode$D,
33157
+ attributes: validXmlAttributes$g
33158
+ };
33159
+ const translator$$ = NodeTranslator.from(config$l);
33160
+ const encode$J = (attributes) => {
33161
+ const raw = attributes?.["w:val"];
33162
+ if (raw === void 0 || raw === null) return void 0;
33163
+ if (typeof raw === "boolean") return raw;
33164
+ if (typeof raw === "number") return raw !== 0;
33165
+ const val = String(raw).trim().toLowerCase();
33166
+ if (val === "0" || val === "false" || val === "off") return false;
33167
+ if (val === "1" || val === "true" || val === "on") return true;
33168
+ return void 0;
33169
+ };
33170
+ const decode$C = (attrs) => {
33171
+ if (attrs?.strike === false) return "0";
33172
+ return void 0;
33173
+ };
33174
+ const attrConfig$m = Object.freeze({
33175
+ xmlName: "w:val",
33176
+ sdName: "strike",
33177
+ encode: encode$J,
33178
+ decode: decode$C
33179
+ });
33180
+ const validXmlAttributes$f = [attrConfig$m];
33181
+ const XML_NODE_NAME$m = "w:strike";
33182
+ const SD_ATTR_KEY$b = "strike";
33183
+ const encode$I = (params2, encodedAttrs = {}) => {
33184
+ const { nodes } = params2;
33185
+ const node = nodes?.[0];
33186
+ if (!node) return void 0;
33187
+ const val = encodedAttrs?.[SD_ATTR_KEY$b];
33188
+ let attributes;
33189
+ if (val === false) attributes = { "w:val": "0" };
33190
+ else if (val === true) attributes = {};
33191
+ else attributes = { ...node.attributes || {} };
33192
+ if (attributes["w:val"] === void 0 && val !== true) attributes["w:val"] = null;
33193
+ else if (val === true && attributes["w:val"] === void 0) delete attributes["w:val"];
33194
+ return {
33195
+ type: "attr",
33196
+ xmlName: XML_NODE_NAME$m,
33197
+ sdNodeOrKeyName: SD_ATTR_KEY$b,
33198
+ attributes
33199
+ };
33200
+ };
33201
+ const config$k = {
33202
+ xmlName: XML_NODE_NAME$m,
33203
+ sdNodeOrKeyName: SD_ATTR_KEY$b,
33204
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33205
+ encode: encode$I,
33206
+ attributes: validXmlAttributes$f
33207
+ };
33208
+ const translator$_ = NodeTranslator.from(config$k);
33209
+ const encode$H = (attributes) => attributes?.["w:val"];
33210
+ const decode$B = (attrs) => attrs?.color;
33211
+ const attrConfig$l = Object.freeze({
33212
+ xmlName: "w:val",
33213
+ sdName: "color",
33214
+ encode: encode$H,
33215
+ decode: decode$B
33216
+ });
33217
+ const encode$G = (attributes) => attributes?.["w:themeColor"];
33218
+ const decode$A = (attrs) => attrs?.themeColor;
33219
+ const attrConfig$k = Object.freeze({
33220
+ xmlName: "w:themeColor",
33221
+ sdName: "themeColor",
33222
+ encode: encode$G,
33223
+ decode: decode$A
33224
+ });
33225
+ const encode$F = (attributes) => attributes?.["w:themeTint"];
33226
+ const decode$z = (attrs) => attrs?.themeTint;
33227
+ const attrConfig$j = Object.freeze({
33228
+ xmlName: "w:themeTint",
33229
+ sdName: "themeTint",
33230
+ encode: encode$F,
33231
+ decode: decode$z
33232
+ });
33233
+ const encode$E = (attributes) => attributes?.["w:themeShade"];
33234
+ const decode$y = (attrs) => attrs?.themeShade;
33235
+ const attrConfig$i = Object.freeze({
33236
+ xmlName: "w:themeShade",
33237
+ sdName: "themeShade",
33238
+ encode: encode$E,
33239
+ decode: decode$y
33240
+ });
33241
+ const validXmlAttributes$e = [attrConfig$l, attrConfig$k, attrConfig$j, attrConfig$i];
33242
+ const XML_NODE_NAME$l = "w:color";
33243
+ const SD_ATTR_KEY$a = "color";
33244
+ const encode$D = (params2, encodedAttrs = {}) => {
33245
+ const { nodes } = params2;
33246
+ const node = nodes?.[0];
33247
+ const sourceAttrs = node?.attributes || {};
33248
+ const value = encodedAttrs.color ?? sourceAttrs["w:val"];
33249
+ const themeColor = encodedAttrs.themeColor ?? sourceAttrs["w:themeColor"];
33250
+ const themeTint = encodedAttrs.themeTint ?? sourceAttrs["w:themeTint"];
33251
+ const themeShade = encodedAttrs.themeShade ?? sourceAttrs["w:themeShade"];
33252
+ const attributes = {};
33253
+ attributes["w:val"] = value ?? null;
33254
+ if (themeColor !== void 0 && themeColor !== null) attributes["w:themeColor"] = themeColor;
33255
+ if (themeTint !== void 0 && themeTint !== null) attributes["w:themeTint"] = themeTint;
33256
+ if (themeShade !== void 0 && themeShade !== null) attributes["w:themeShade"] = themeShade;
33257
+ return {
33258
+ type: "attr",
33259
+ xmlName: XML_NODE_NAME$l,
33260
+ sdNodeOrKeyName: SD_ATTR_KEY$a,
33261
+ attributes
33262
+ };
33263
+ };
33264
+ const config$j = {
33265
+ xmlName: XML_NODE_NAME$l,
33266
+ sdNodeOrKeyName: SD_ATTR_KEY$a,
33267
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33268
+ encode: encode$D,
33269
+ attributes: validXmlAttributes$e
33270
+ };
33271
+ const translator$Z = NodeTranslator.from(config$j);
33272
+ const encode$C = (attributes) => attributes?.["w:eastAsia"];
33273
+ const decode$x = (attrs) => attrs?.eastAsia;
33274
+ const attrConfig$h = Object.freeze({
33275
+ xmlName: "w:eastAsia",
33276
+ sdName: "eastAsia",
33277
+ encode: encode$C,
33278
+ decode: decode$x
33279
+ });
33280
+ const encode$B = (attributes) => attributes?.["w:ascii"];
33281
+ const decode$w = (attrs) => attrs?.ascii;
33282
+ const attrConfig$g = Object.freeze({
33283
+ xmlName: "w:ascii",
33284
+ sdName: "ascii",
33285
+ encode: encode$B,
33286
+ decode: decode$w
33287
+ });
33288
+ const encode$A = (attributes) => attributes?.["w:hAnsi"];
33289
+ const decode$v = (attrs) => attrs?.hAnsi;
33290
+ const attrConfig$f = Object.freeze({
33291
+ xmlName: "w:hAnsi",
33292
+ sdName: "hAnsi",
33293
+ encode: encode$A,
33294
+ decode: decode$v
33295
+ });
33296
+ const encode$z = (attributes) => attributes?.["w:cs"];
33297
+ const decode$u = (attrs) => attrs?.cs;
33298
+ const attrConfig$e = Object.freeze({
33299
+ xmlName: "w:cs",
33300
+ sdName: "cs",
33301
+ encode: encode$z,
33302
+ decode: decode$u
33303
+ });
33304
+ const encode$y = (attributes) => attributes?.["w:val"];
33305
+ const decode$t = (attrs) => attrs?.value;
33306
+ const attrConfig$d = Object.freeze({
33307
+ xmlName: "w:val",
33308
+ sdName: "value",
33309
+ encode: encode$y,
33310
+ decode: decode$t
33311
+ });
33312
+ const validXmlAttributes$d = [attrConfig$h, attrConfig$g, attrConfig$f, attrConfig$e, attrConfig$d];
33313
+ const XML_NODE_NAME$k = "w:rFonts";
33314
+ const SD_ATTR_KEY$9 = "fontFamily";
33315
+ const encode$x = (params2, encodedAttrs = {}) => {
33316
+ const { nodes } = params2;
33317
+ const node = nodes?.[0];
33318
+ const sourceAttrs = node?.attributes || {};
33319
+ const attributes = {};
33320
+ const setAttr = (xmlName, sdName) => {
33321
+ if (encodedAttrs[sdName] !== void 0 && encodedAttrs[sdName] !== null) {
33322
+ attributes[xmlName] = encodedAttrs[sdName];
33323
+ } else if (sourceAttrs[xmlName] !== void 0) {
33324
+ attributes[xmlName] = sourceAttrs[xmlName];
33325
+ }
33326
+ };
33327
+ setAttr("w:eastAsia", "eastAsia");
33328
+ setAttr("w:ascii", "ascii");
33329
+ setAttr("w:hAnsi", "hAnsi");
33330
+ setAttr("w:cs", "cs");
33331
+ setAttr("w:val", "value");
33332
+ Object.keys(sourceAttrs).forEach((key2) => {
33333
+ if (attributes[key2] === void 0) attributes[key2] = sourceAttrs[key2];
33334
+ });
33335
+ if (attributes["w:val"] === void 0 && attributes["w:eastAsia"]) {
33336
+ attributes["w:val"] = attributes["w:eastAsia"];
33337
+ }
33338
+ if (attributes["w:val"] === void 0) delete attributes["w:val"];
33339
+ return {
33340
+ type: "attr",
33341
+ xmlName: XML_NODE_NAME$k,
33342
+ sdNodeOrKeyName: SD_ATTR_KEY$9,
33343
+ attributes
33344
+ };
33345
+ };
33346
+ const config$i = {
33347
+ xmlName: XML_NODE_NAME$k,
33348
+ sdNodeOrKeyName: SD_ATTR_KEY$9,
33349
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33350
+ encode: encode$x,
33351
+ attributes: validXmlAttributes$d
33352
+ };
33353
+ const translator$Y = NodeTranslator.from(config$i);
33354
+ const encode$w = (attributes) => attributes?.["w:val"];
33355
+ const decode$s = (attrs) => attrs?.styleId;
33356
+ const attrConfig$c = Object.freeze({
33357
+ xmlName: "w:val",
33358
+ sdName: "styleId",
33359
+ encode: encode$w,
33360
+ decode: decode$s
33361
+ });
33362
+ const validXmlAttributes$c = [attrConfig$c];
33363
+ const XML_NODE_NAME$j = "w:rStyle";
33364
+ const SD_ATTR_KEY$8 = "styleId";
33365
+ const encode$v = (params2, encodedAttrs = {}) => {
33366
+ const { nodes } = params2;
33367
+ const node = nodes?.[0];
33368
+ const value = encodedAttrs.styleId ?? node?.attributes?.["w:val"];
33369
+ return {
33370
+ type: "attr",
33371
+ xmlName: XML_NODE_NAME$j,
33372
+ sdNodeOrKeyName: SD_ATTR_KEY$8,
33373
+ attributes: { "w:val": value ?? null }
33374
+ };
33375
+ };
33376
+ const config$h = {
33377
+ xmlName: XML_NODE_NAME$j,
33378
+ sdNodeOrKeyName: SD_ATTR_KEY$8,
33379
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33380
+ encode: encode$v,
33381
+ attributes: validXmlAttributes$c
33382
+ };
33383
+ const translator$X = NodeTranslator.from(config$h);
33384
+ const encode$u = (attributes) => attributes?.["w:val"];
33385
+ const decode$r = (attrs) => attrs?.fontSize;
33386
+ const attrConfig$b = Object.freeze({
33387
+ xmlName: "w:val",
33388
+ sdName: "fontSize",
33389
+ encode: encode$u,
33390
+ decode: decode$r
33391
+ });
33392
+ const validXmlAttributes$b = [attrConfig$b];
33393
+ const XML_NODE_NAME$i = "w:sz";
33394
+ const SD_ATTR_KEY$7 = "fontSize";
33395
+ const encode$t = (params2, encodedAttrs = {}) => {
33396
+ const { nodes } = params2;
33397
+ const node = nodes?.[0];
33398
+ const value = encodedAttrs.fontSize ?? node?.attributes?.["w:val"];
33399
+ return {
33400
+ type: "attr",
33401
+ xmlName: XML_NODE_NAME$i,
33402
+ sdNodeOrKeyName: SD_ATTR_KEY$7,
33403
+ attributes: { "w:val": value ?? null }
33404
+ };
33405
+ };
33406
+ const config$g = {
33407
+ xmlName: XML_NODE_NAME$i,
33408
+ sdNodeOrKeyName: SD_ATTR_KEY$7,
33409
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33410
+ encode: encode$t,
33411
+ attributes: validXmlAttributes$b
33412
+ };
33413
+ const translator$W = NodeTranslator.from(config$g);
33414
+ const encode$s = (attributes) => attributes?.["w:val"];
33415
+ const decode$q = (attrs) => attrs?.fontSizeCs;
33416
+ const attrConfig$a = Object.freeze({
33417
+ xmlName: "w:val",
33418
+ sdName: "fontSizeCs",
33419
+ encode: encode$s,
33420
+ decode: decode$q
33421
+ });
33422
+ const validXmlAttributes$a = [attrConfig$a];
33423
+ const XML_NODE_NAME$h = "w:szCs";
33424
+ const SD_ATTR_KEY$6 = "fontSizeCs";
33425
+ const encode$r = (params2, encodedAttrs = {}) => {
33426
+ const { nodes } = params2;
33427
+ const node = nodes?.[0];
33428
+ const value = encodedAttrs.fontSizeCs ?? node?.attributes?.["w:val"];
33429
+ return {
33430
+ type: "attr",
33431
+ xmlName: XML_NODE_NAME$h,
33432
+ sdNodeOrKeyName: SD_ATTR_KEY$6,
33433
+ attributes: { "w:val": value ?? null }
33434
+ };
33435
+ };
33436
+ const config$f = {
33437
+ xmlName: XML_NODE_NAME$h,
33438
+ sdNodeOrKeyName: SD_ATTR_KEY$6,
33439
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33440
+ encode: encode$r,
33441
+ attributes: validXmlAttributes$a
33442
+ };
33443
+ const translator$V = NodeTranslator.from(config$f);
33444
+ const runPropertyTranslators = Object.freeze({
33445
+ "w:b": translator$11,
33446
+ "w:i": translator$10,
33447
+ "w:u": translator$$,
33448
+ "w:strike": translator$_,
33449
+ "w:color": translator$Z,
33450
+ "w:highlight": translator$14,
33451
+ "w:rFonts": translator$Y,
33452
+ "w:rStyle": translator$X,
33453
+ "w:sz": translator$W,
33454
+ "w:szCs": translator$V
33455
+ });
33456
+ const rawRunPropertyXmlNames = Object.freeze(["w:lang", "w:shd"]);
33457
+ const RAW_CHILD_NAME_SET = new Set(rawRunPropertyXmlNames);
33458
+ const KNOWN_CHILD_XML_NAMES = /* @__PURE__ */ new Set([...Object.keys(runPropertyTranslators), ...RAW_CHILD_NAME_SET]);
33459
+ const toRunPropertyEntry = (candidate) => {
33460
+ if (!candidate || candidate.type !== "attr") return null;
33461
+ const xmlName = candidate.xmlName || candidate.name;
33462
+ if (!xmlName) return null;
33463
+ return {
33464
+ xmlName,
33465
+ attributes: { ...candidate.attributes || {} }
33466
+ };
33467
+ };
33468
+ const XML_NODE_NAME$g = "w:rPr";
33469
+ const SD_ATTR_KEY$5 = "runProperties";
33470
+ const encode$q = (params2) => {
33471
+ const { nodes } = params2;
33472
+ const node = nodes?.[0] || {};
33473
+ const contents = Array.isArray(node.elements) ? node.elements : [];
33474
+ const runPropsArray = contents.reduce(
33475
+ (acc, child) => {
33476
+ if (!child || typeof child !== "object") return acc;
33477
+ const xmlName = child.name;
33478
+ if (!KNOWN_CHILD_XML_NAMES.has(xmlName)) return acc;
33479
+ const translator2 = runPropertyTranslators[xmlName];
33480
+ let entry = null;
33481
+ if (translator2) {
33482
+ const encoded = translator2.encode({ ...params2, nodes: [child] }) || null;
33483
+ entry = toRunPropertyEntry(encoded);
33484
+ } else if (RAW_CHILD_NAME_SET.has(xmlName)) {
33485
+ entry = toRunPropertyEntry({
33486
+ type: "attr",
33487
+ xmlName,
33488
+ attributes: { ...child.attributes || {} }
33489
+ });
33490
+ }
33491
+ if (entry) acc.push(entry);
33492
+ return acc;
33493
+ },
33494
+ /** @type {{ xmlName: string, attributes: Record<string, any> }[]} */
33495
+ []
33496
+ );
33497
+ return {
33498
+ type: "attr",
33499
+ xmlName: "w:rPr",
33500
+ sdNodeOrKeyName: "runProperties",
33501
+ attributes: runPropsArray
33502
+ };
33503
+ };
33504
+ const config$e = {
33505
+ xmlName: XML_NODE_NAME$g,
33506
+ sdNodeOrKeyName: SD_ATTR_KEY$5,
33507
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
33508
+ encode: encode$q
33509
+ };
33510
+ const translator$U = NodeTranslator.from(config$e);
33511
+ const EAST_ASIAN_CHARACTER_REGEX = /[\u1100-\u11FF\u2E80-\u2EFF\u2F00-\u2FDF\u3040-\u30FF\u3100-\u312F\u3130-\u318F\u31A0-\u31BF\u3400-\u4DBF\u4E00-\u9FFF\uA960-\uA97F\uAC00-\uD7AF\uF900-\uFAFF\uFF00-\uFFEF]/u;
33512
+ const containsEastAsianCharacters = (text) => EAST_ASIAN_CHARACTER_REGEX.test(text);
33513
+ const collectRunProperties = (params2, rPrNode, translator2 = translator$U) => {
33514
+ if (!rPrNode) return { entries: [], hadRPr: false, styleChangeMarks: [] };
33515
+ const result = translator2.encode({ ...params2, nodes: [rPrNode] }) || {};
33516
+ let entries = [];
33517
+ if (Array.isArray(result.attributes) && result.attributes.length) {
33518
+ entries = result.attributes.map((attr) => ({
33519
+ xmlName: attr?.xmlName,
33520
+ attributes: { ...attr?.attributes || {} }
33521
+ }));
33522
+ } else if (Array.isArray(rPrNode.elements) && rPrNode.elements.length) {
33523
+ entries = rPrNode.elements.filter((el) => el && typeof el === "object").map((el) => ({
33524
+ xmlName: el.name,
33525
+ attributes: { ...el.attributes || {} }
33526
+ }));
33527
+ }
33528
+ const legacyMarks = parseMarks(rPrNode, [], params2?.docx) || [];
33529
+ const styleChangeMarks = handleStyleChangeMarks(rPrNode, legacyMarks) || [];
33530
+ return { entries, hadRPr: true, styleChangeMarks };
33531
+ };
33532
+ const buildRunAttrs = (encodedAttrs = {}, hadRPr, runProps) => {
33533
+ const base2 = { ...encodedAttrs || {} };
33534
+ if (hadRPr) {
33535
+ base2.runProperties = runProps.length ? runProps : null;
33536
+ }
33537
+ return base2;
33538
+ };
33539
+ const ensureInlineMarks = (marks, inlineMarks = []) => {
33540
+ inlineMarks.forEach(({ type: type2, attrs }) => {
33541
+ if (!type2) return;
33542
+ if (marks.some((mark) => mark?.type === type2)) return;
33543
+ marks.push(attrs ? { type: type2, attrs: { ...attrs } } : { type: type2 });
33544
+ });
33545
+ };
33546
+ const ensureTextStyleMark = (marks, textStyleAttrs) => {
33547
+ if (!textStyleAttrs) return;
33548
+ const existingTextStyle = marks.find((mark) => mark?.type === "textStyle");
33549
+ if (existingTextStyle) {
33550
+ existingTextStyle.attrs = { ...existingTextStyle.attrs || {}, ...textStyleAttrs };
33551
+ return;
33552
+ }
33553
+ marks.push({ type: "textStyle", attrs: { ...textStyleAttrs } });
33554
+ };
33555
+ const normalizeTextStyleAttrsForNode = (textStyleAttrs, node) => {
33556
+ if (!textStyleAttrs || typeof textStyleAttrs !== "object") return null;
33557
+ const normalized = { ...textStyleAttrs };
33558
+ const eastAsiaFont = normalized.eastAsiaFontFamily;
33559
+ if (eastAsiaFont) {
33560
+ delete normalized.eastAsiaFontFamily;
33561
+ const text = typeof node?.text === "string" ? node.text : null;
33562
+ const shouldUseEastAsia = typeof text === "string" && containsEastAsianCharacters(text);
33563
+ if (shouldUseEastAsia) {
33564
+ normalized.fontFamily = eastAsiaFont;
33565
+ }
33566
+ }
33567
+ return Object.keys(normalized).length ? normalized : null;
33568
+ };
33569
+ const applyRunMarks = (node, inlineMarks, textStyleAttrs) => {
33570
+ if (!node || typeof node !== "object") return node;
33571
+ const baseMarks = Array.isArray(node.marks) ? node.marks : [];
33572
+ const marks = baseMarks.map((mark) => cloneMark$1(mark));
33573
+ ensureInlineMarks(marks, inlineMarks);
33574
+ if (node.type === "text") {
33575
+ const normalizedTextStyle = normalizeTextStyleAttrsForNode(textStyleAttrs, node);
33576
+ ensureTextStyleMark(marks, normalizedTextStyle);
33577
+ }
33578
+ return { ...node, marks };
33579
+ };
33580
+ const deriveStyleMarks = ({ docx, paragraphStyleId, runStyleId }) => {
33581
+ const paragraphStyleMarks = collectStyleMarks(paragraphStyleId, docx);
33582
+ const runStyleMarks = collectStyleMarks(runStyleId, docx);
33583
+ const inlineMarks = mergeInlineMarkSets(paragraphStyleMarks.inlineMarks, runStyleMarks.inlineMarks);
33584
+ const textStyleAttrs = mergeTextStyleAttrs(paragraphStyleMarks.textStyleAttrs, runStyleMarks.textStyleAttrs);
33585
+ return { inlineMarks, textStyleAttrs };
33586
+ };
33587
+ const collectStyleMarks = (styleId, docx, seen = /* @__PURE__ */ new Set()) => {
33588
+ if (!styleId || !docx || seen.has(styleId)) return { inlineMarks: [], textStyleAttrs: null };
33589
+ seen.add(styleId);
33590
+ const chain = collectStyleChain(styleId, docx, seen);
33591
+ if (!chain.length) return { inlineMarks: [], textStyleAttrs: null };
33592
+ const inlineMap = /* @__PURE__ */ new Map();
33593
+ let textStyleAttrs = {};
33594
+ chain.forEach((styleTag) => {
33595
+ const marks = extractMarksFromStyle(styleTag, docx);
33596
+ marks.inlineMarks.forEach((mark) => {
33597
+ inlineMap.set(mark.type, mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
33598
+ });
33599
+ if (marks.textStyleAttrs) textStyleAttrs = { ...textStyleAttrs, ...marks.textStyleAttrs };
33600
+ });
33601
+ return {
33602
+ inlineMarks: Array.from(inlineMap.values()),
33603
+ textStyleAttrs: Object.keys(textStyleAttrs).length ? textStyleAttrs : null
33604
+ };
33605
+ };
33606
+ const collectStyleChain = (styleId, docx, seen) => {
33607
+ if (!styleId || !docx) return [];
33608
+ const styleTag = findStyleTag(docx, styleId);
33609
+ if (!styleTag || !styleTag.elements) return [];
33610
+ const basedOn = styleTag.elements?.find((el) => el.name === "w:basedOn")?.attributes?.["w:val"];
33611
+ let chain = [];
33612
+ if (basedOn && !seen.has(basedOn)) {
33613
+ seen.add(basedOn);
33614
+ chain = collectStyleChain(basedOn, docx, seen);
33615
+ }
33616
+ chain.push(styleTag);
33617
+ return chain;
33618
+ };
33619
+ const findStyleTag = (docx, styleId) => {
33620
+ const stylesFile = docx?.["word/styles.xml"];
33621
+ if (!stylesFile?.elements?.length) return null;
33622
+ const candidates = [];
33623
+ stylesFile.elements.forEach((el) => {
33624
+ if (!el) return;
33625
+ if (el.name === "w:styles" && Array.isArray(el.elements)) {
33626
+ el.elements.forEach((child) => {
33627
+ if (child?.name === "w:style") candidates.push(child);
33628
+ });
33629
+ return;
33630
+ }
33631
+ if (el.name === "w:style") {
33632
+ candidates.push(el);
33633
+ return;
33634
+ }
33635
+ if (Array.isArray(el.elements)) {
33636
+ el.elements.forEach((child) => {
33637
+ if (child?.name === "w:style") candidates.push(child);
33638
+ });
33639
+ }
33640
+ });
33641
+ return candidates.find((tag) => tag?.attributes?.["w:styleId"] === styleId) || null;
33642
+ };
33643
+ const extractMarksFromStyle = (styleTag, docx) => {
33644
+ const rPr = styleTag?.elements?.find((el) => el.name === "w:rPr");
33645
+ if (!rPr) return { inlineMarks: [], textStyleAttrs: null };
33646
+ const marks = parseMarks(rPr, [], docx) || [];
33647
+ const inlineMarks = [];
33648
+ let textStyleAttrs = {};
33649
+ marks.forEach((mark) => {
33650
+ if (!mark) return;
33651
+ if (mark.type === "textStyle") {
33652
+ const attrs = mark.attrs || {};
33653
+ if (Object.keys(attrs).length) textStyleAttrs = { ...textStyleAttrs, ...attrs };
33654
+ return;
33655
+ }
33656
+ if (mark.type) inlineMarks.push(mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
33657
+ });
33658
+ return {
33659
+ inlineMarks,
33660
+ textStyleAttrs: Object.keys(textStyleAttrs).length ? textStyleAttrs : null
33661
+ };
33662
+ };
33663
+ const mergeInlineMarkSets = (...markSets) => {
33664
+ const map2 = /* @__PURE__ */ new Map();
33665
+ markSets.filter(Boolean).forEach((marks) => {
33666
+ marks.forEach((mark) => {
33667
+ if (!mark || !mark.type) return;
33668
+ map2.set(mark.type, mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
33669
+ });
33670
+ });
33671
+ return Array.from(map2.values());
33672
+ };
33673
+ const mergeTextStyleAttrs = (...attrsList) => {
33674
+ const merged = attrsList.filter((attrs) => attrs && Object.keys(attrs).length).reduce((acc, attrs) => ({ ...acc, ...attrs }), {});
33675
+ return Object.keys(merged).length ? merged : null;
33676
+ };
33677
+ const cloneRunAttrs = (attrs) => {
33678
+ const clone = { ...attrs };
33679
+ if (Array.isArray(attrs?.runProperties)) {
33680
+ clone.runProperties = attrs.runProperties.map((entry) => ({
33681
+ xmlName: entry?.xmlName,
33682
+ attributes: { ...entry?.attributes || {} }
33683
+ }));
33684
+ }
33685
+ return clone;
33686
+ };
33687
+ const cloneMark$1 = (mark) => {
33688
+ if (!mark || typeof mark !== "object") return mark;
33689
+ const cloned = { ...mark };
33690
+ if (mark.attrs && typeof mark.attrs === "object") {
33691
+ cloned.attrs = { ...mark.attrs };
33692
+ if (Array.isArray(mark.attrs.runProperties)) {
33693
+ cloned.attrs.runProperties = mark.attrs.runProperties.map((entry) => ({
33694
+ xmlName: entry?.xmlName,
33695
+ attributes: { ...entry?.attributes || {} }
33696
+ }));
33697
+ }
33698
+ }
33699
+ return cloned;
33700
+ };
33701
+ const normalizeBool = (value) => {
33702
+ if (value === void 0 || value === null) return true;
33703
+ if (typeof value === "boolean") return value;
33704
+ if (typeof value === "number") return value !== 0;
33705
+ const normalized = String(value).trim().toLowerCase();
33706
+ if (normalized === "0" || normalized === "false" || normalized === "off") return false;
33707
+ if (normalized === "1" || normalized === "true" || normalized === "on") return true;
33708
+ return true;
33709
+ };
33710
+ const createRunPropertiesElement = (entries = []) => {
33711
+ if (!Array.isArray(entries) || !entries.length) return null;
33712
+ const elements = entries.map((entry) => {
33713
+ if (!entry || !entry.xmlName) return null;
33714
+ return {
33715
+ name: entry.xmlName,
33716
+ attributes: { ...entry.attributes || {} }
33717
+ };
33718
+ }).filter(Boolean);
33719
+ if (!elements.length) return null;
33720
+ return {
33721
+ name: "w:rPr",
33722
+ elements
33723
+ };
33724
+ };
33725
+ const cloneXmlNode = (nodeLike) => {
33726
+ if (!nodeLike || typeof nodeLike !== "object") return nodeLike;
33727
+ return {
33728
+ name: nodeLike.name,
33729
+ type: nodeLike.type,
33730
+ attributes: nodeLike.attributes ? { ...nodeLike.attributes } : void 0,
33731
+ elements: Array.isArray(nodeLike.elements) ? nodeLike.elements.map((el) => cloneXmlNode(el)) : void 0,
33732
+ text: nodeLike.text
33733
+ };
33734
+ };
33735
+ const applyRunPropertiesTemplate = (runNode, runPropertiesTemplate) => {
33736
+ if (!runNode || !runPropertiesTemplate) return;
33737
+ if (!Array.isArray(runNode.elements)) runNode.elements = [];
33738
+ let runProps = runNode.elements.find((el) => el?.name === "w:rPr");
33739
+ if (!runProps) {
33740
+ runProps = { name: "w:rPr", elements: [] };
33741
+ runNode.elements.unshift(runProps);
33742
+ }
33743
+ if (!Array.isArray(runProps.elements)) runProps.elements = [];
33744
+ if (runPropertiesTemplate.attributes) {
33745
+ runProps.attributes = {
33746
+ ...runProps.attributes || {},
33747
+ ...runPropertiesTemplate.attributes
33748
+ };
33749
+ }
33750
+ const isValidRunPropName = (name) => typeof name === "string" && name.includes(":");
33751
+ runProps.elements = runProps.elements.filter((entry) => isValidRunPropName(entry?.name));
33752
+ const existingNames = new Set(runProps.elements.map((el) => el?.name));
33753
+ (runPropertiesTemplate.elements || []).forEach((entry) => {
33754
+ if (!isValidRunPropName(entry?.name) || existingNames.has(entry.name)) return;
33755
+ runProps.elements.push(cloneXmlNode(entry));
33756
+ existingNames.add(entry.name);
33757
+ });
33758
+ };
33759
+ const splitRunProperties = (entries = [], docx = null) => {
33760
+ const remainingProps = [];
33761
+ const inlineMarks = [];
33762
+ const textStyleAttrs = {};
33763
+ let hasTextStyle = false;
33764
+ let highlightColor = null;
33765
+ let runStyleId = null;
33766
+ entries.forEach((entry) => {
33767
+ if (!entry || !entry.xmlName) return;
33768
+ const attributes = entry.attributes || {};
33769
+ switch (entry.xmlName) {
33770
+ case "w:b": {
33771
+ const val = normalizeBool(attributes["w:val"]);
33772
+ inlineMarks.push(val ? { type: "bold" } : { type: "bold", attrs: { value: "0" } });
33773
+ break;
33774
+ }
33775
+ case "w:i": {
33776
+ const val = normalizeBool(attributes["w:val"]);
33777
+ inlineMarks.push(val ? { type: "italic" } : { type: "italic", attrs: { value: "0" } });
33778
+ break;
33779
+ }
33780
+ case "w:u": {
33781
+ const rawVal = attributes["w:val"];
33782
+ const underlineType = rawVal == null || rawVal === "" ? "single" : String(rawVal);
33783
+ const attrs = {};
33784
+ if (underlineType.toLowerCase() === "none" || underlineType === "0") {
33785
+ attrs.underlineType = "none";
33786
+ } else {
33787
+ attrs.underlineType = underlineType;
33788
+ const colorRaw = attributes["w:color"];
33789
+ if (typeof colorRaw === "string" && colorRaw.toLowerCase() !== "auto") {
33790
+ const normalizedColor = normalizeHexColor(colorRaw);
33791
+ if (normalizedColor) attrs.underlineColor = `#${normalizedColor}`;
33792
+ }
33793
+ }
33794
+ if (attributes["w:themeColor"]) attrs.underlineThemeColor = attributes["w:themeColor"];
33795
+ if (attributes["w:themeTint"]) attrs.underlineThemeTint = attributes["w:themeTint"];
33796
+ if (attributes["w:themeShade"]) attrs.underlineThemeShade = attributes["w:themeShade"];
33797
+ inlineMarks.push({ type: "underline", attrs });
33798
+ break;
33799
+ }
33800
+ case "w:color": {
33801
+ const raw = attributes["w:val"];
33802
+ if (typeof raw === "string" && raw) {
33803
+ hasTextStyle = true;
33804
+ textStyleAttrs.color = `#${raw.replace("#", "").toUpperCase()}`;
33805
+ }
33806
+ break;
33807
+ }
33808
+ case "w:rFonts": {
33809
+ const asciiFamily = attributes["w:ascii"] || attributes["w:hAnsi"] || (attributes["w:eastAsia"] ? void 0 : attributes["w:val"]);
33810
+ const eastAsiaFamily = attributes["w:eastAsia"];
33811
+ if (asciiFamily) {
33812
+ hasTextStyle = true;
33813
+ textStyleAttrs.fontFamily = SuperConverter.toCssFontFamily(asciiFamily, docx);
33814
+ }
33815
+ if (eastAsiaFamily) {
33816
+ hasTextStyle = true;
33817
+ const eastAsiaCss = SuperConverter.toCssFontFamily(eastAsiaFamily, docx);
33818
+ if (!asciiFamily || eastAsiaCss !== textStyleAttrs.fontFamily) {
33819
+ textStyleAttrs.eastAsiaFontFamily = eastAsiaCss;
33820
+ }
33821
+ }
33822
+ break;
33823
+ }
33824
+ case "w:sz":
33825
+ case "w:szCs": {
33826
+ const rawSize = Number(attributes["w:val"]);
33827
+ if (Number.isFinite(rawSize) && rawSize > 0) {
33828
+ hasTextStyle = true;
33829
+ textStyleAttrs.fontSize = `${rawSize / 2}pt`;
33830
+ }
33831
+ break;
33832
+ }
33833
+ case "w:strike": {
33834
+ const val = normalizeBool(attributes["w:val"]);
33835
+ inlineMarks.push(val ? { type: "strike" } : { type: "strike", attrs: { value: "0" } });
33836
+ break;
33837
+ }
33838
+ case "w:highlight": {
33839
+ const color = attributes["w:val"];
33840
+ if (typeof color === "string" && color) {
33841
+ highlightColor = color.toLowerCase() === "none" ? "transparent" : color;
33842
+ }
33843
+ break;
33844
+ }
33845
+ case "w:shd": {
33846
+ const fill = attributes["w:fill"];
33847
+ const shdVal = attributes["w:val"];
33848
+ if (fill && String(fill).toLowerCase() !== "auto") {
33849
+ highlightColor = `#${String(fill).replace("#", "")}`;
33850
+ } else if (typeof shdVal === "string") {
33851
+ const normalized = shdVal.toLowerCase();
33852
+ if (normalized === "clear" || normalized === "nil" || normalized === "none") {
33853
+ highlightColor = "transparent";
33854
+ }
33855
+ }
33856
+ break;
33857
+ }
33858
+ case "w:rStyle": {
33859
+ if (typeof attributes["w:val"] === "string") runStyleId = attributes["w:val"];
33860
+ remainingProps.push({ xmlName: entry.xmlName, attributes: { ...attributes } });
33861
+ break;
33862
+ }
33863
+ default: {
33864
+ remainingProps.push({ xmlName: entry.xmlName, attributes: { ...attributes } });
33865
+ }
33866
+ }
33867
+ });
33868
+ if (highlightColor) inlineMarks.push({ type: "highlight", attrs: { color: highlightColor } });
33869
+ return {
33870
+ remainingProps,
33871
+ inlineMarks,
33872
+ textStyleAttrs: hasTextStyle ? textStyleAttrs : null,
33873
+ runStyleId
33874
+ };
33875
+ };
33876
+ const cloneMark = (mark) => {
33877
+ if (!mark) return mark;
33878
+ return {
33879
+ ...mark,
33880
+ attrs: mark.attrs ? { ...mark.attrs } : void 0
33881
+ };
33882
+ };
33883
+ const cloneNode = (node) => {
33884
+ if (!node || typeof node !== "object") return node;
33885
+ const cloned = { ...node };
33886
+ if (node.marks) cloned.marks = node.marks.map((mark) => cloneMark(mark));
33887
+ if (node.content) cloned.content = node.content.map((child) => cloneNode(child));
33888
+ if (node.elements) cloned.elements = node.elements.map((el) => cloneNode(el));
33889
+ if (node.attributes) cloned.attributes = { ...node.attributes };
33890
+ return cloned;
33891
+ };
33892
+ const cloneRuns = (runs = []) => runs.map((run2) => cloneNode(run2));
33893
+ const prepareRunTrackingContext = (node = {}) => {
33894
+ const marks = Array.isArray(node.marks) ? node.marks : [];
33895
+ const trackingMarks = marks.filter(
33896
+ (mark) => mark?.type === TrackInsertMarkName || mark?.type === TrackDeleteMarkName
33897
+ );
33898
+ if (!trackingMarks.length) {
33899
+ return { runNode: node, trackingMarksByType: /* @__PURE__ */ new Map() };
33900
+ }
33901
+ const trackingMarksByType = /* @__PURE__ */ new Map();
33902
+ trackingMarks.forEach((mark) => {
33903
+ if (mark?.type) trackingMarksByType.set(mark.type, cloneMark(mark));
33904
+ });
33905
+ const preservedMarks = marks.filter((mark) => mark?.type !== TrackInsertMarkName && mark?.type !== TrackDeleteMarkName).map((mark) => cloneMark(mark));
33906
+ const clonedContent = Array.isArray(node.content) ? node.content.map((child) => {
33907
+ const childClone = cloneNode(child);
33908
+ const childMarks = Array.isArray(childClone.marks) ? childClone.marks.slice() : [];
33909
+ trackingMarks.forEach((mark) => {
33910
+ childMarks.push(cloneMark(mark));
33911
+ });
33912
+ childClone.marks = childMarks;
33913
+ return childClone;
33914
+ }) : [];
33915
+ return {
33916
+ runNode: {
33917
+ ...cloneNode(node),
33918
+ marks: preservedMarks,
33919
+ content: clonedContent
33920
+ },
33921
+ trackingMarksByType
33922
+ };
33923
+ };
33924
+ const mapTrackingAttrs = (mark, attrMap) => {
33925
+ const source = mark?.attrs || {};
33926
+ const mapped = {};
33927
+ attrMap.forEach((targetKey, sourceKey) => {
33928
+ if (source[sourceKey] != null) mapped[targetKey] = source[sourceKey];
33929
+ });
33930
+ return mapped;
33931
+ };
33932
+ const renameTextElementsForDeletion = (node) => {
33933
+ if (!node || typeof node !== "object") return;
33934
+ if (node.name === "w:t") node.name = "w:delText";
33935
+ if (Array.isArray(node.elements)) node.elements.forEach(renameTextElementsForDeletion);
33936
+ };
33937
+ const ensureTrackedWrapper = (runs, trackingMarksByType = /* @__PURE__ */ new Map()) => {
33938
+ if (!Array.isArray(runs) || !runs.length) return runs;
33939
+ const firstRun = runs[0];
33940
+ if (firstRun?.name === "w:ins" || firstRun?.name === "w:del") {
33941
+ return runs;
33942
+ }
33943
+ if (!trackingMarksByType.size) return runs;
33944
+ if (trackingMarksByType.has(TrackInsertMarkName)) {
33945
+ const mark = trackingMarksByType.get(TrackInsertMarkName);
33946
+ const clonedRuns = cloneRuns(runs);
33947
+ const wrapper = {
33948
+ name: "w:ins",
33949
+ attributes: mapTrackingAttrs(
33950
+ mark,
33951
+ /* @__PURE__ */ new Map([
33952
+ ["id", "w:id"],
33953
+ ["author", "w:author"],
33954
+ ["authorEmail", "w:authorEmail"],
33955
+ ["date", "w:date"]
33956
+ ])
33957
+ ),
33958
+ elements: clonedRuns
33959
+ };
33960
+ return [wrapper];
33961
+ }
33962
+ if (trackingMarksByType.has(TrackDeleteMarkName)) {
33963
+ const mark = trackingMarksByType.get(TrackDeleteMarkName);
33964
+ const clonedRuns = cloneRuns(runs);
33965
+ clonedRuns.forEach(renameTextElementsForDeletion);
33966
+ const wrapper = {
33967
+ name: "w:del",
33968
+ attributes: mapTrackingAttrs(mark, /* @__PURE__ */ new Map([["id", "w:id"]])),
33969
+ elements: clonedRuns
33970
+ };
33971
+ return [wrapper];
33972
+ }
33973
+ return runs;
33974
+ };
33975
+ const encode$p = (attributes) => {
33976
+ return attributes["w:rsidR"];
33977
+ };
33978
+ const decode$p = (attrs) => {
33979
+ return attrs.rsidR;
33980
+ };
33981
+ const attrConfig$9 = Object.freeze({
33982
+ xmlName: "w:rsidR",
33983
+ sdName: "rsidR",
33984
+ encode: encode$p,
33985
+ decode: decode$p
33986
+ });
33987
+ const encode$o = (attributes) => {
33988
+ return attributes["w:rsidRPr"];
33989
+ };
33990
+ const decode$o = (attrs) => {
33991
+ return attrs.rsidRPr;
33992
+ };
33993
+ const attrConfig$8 = Object.freeze({
33994
+ xmlName: "w:rsidRPr",
33995
+ sdName: "rsidRPr",
33996
+ encode: encode$o,
33997
+ decode: decode$o
33998
+ });
33999
+ const encode$n = (attributes) => {
34000
+ return attributes["w:rsidDel"];
34001
+ };
34002
+ const decode$n = (attrs) => {
34003
+ return attrs.rsidDel;
34004
+ };
34005
+ const attrConfig$7 = Object.freeze({
34006
+ xmlName: "w:rsidDel",
34007
+ sdName: "rsidDel",
34008
+ encode: encode$n,
34009
+ decode: decode$n
34010
+ });
34011
+ const validXmlAttributes$9 = [attrConfig$9, attrConfig$8, attrConfig$7];
34012
+ const XML_NODE_NAME$f = "w:r";
34013
+ const SD_KEY_NAME = "run";
34014
+ const encode$m = (params2, encodedAttrs = {}) => {
34015
+ const { nodes = [], nodeListHandler } = params2 || {};
34016
+ const runNode = nodes[0];
34017
+ if (!runNode) return void 0;
34018
+ const elements = Array.isArray(runNode.elements) ? runNode.elements : [];
34019
+ const rPrNode = elements.find((child) => child?.name === "w:rPr");
34020
+ const contentElements = rPrNode ? elements.filter((el) => el !== rPrNode) : elements;
34021
+ const { entries: runPropEntries, hadRPr, styleChangeMarks } = collectRunProperties(params2, rPrNode);
34022
+ const { remainingProps, inlineMarks, textStyleAttrs, runStyleId } = splitRunProperties(runPropEntries, params2?.docx);
34023
+ const styleMarks = deriveStyleMarks({
34024
+ docx: params2?.docx,
34025
+ paragraphStyleId: params2?.parentStyleId,
34026
+ runStyleId
34027
+ });
34028
+ const mergedInlineMarks = mergeInlineMarkSets(styleMarks.inlineMarks, inlineMarks);
34029
+ let mergedTextStyleAttrs = mergeTextStyleAttrs(styleMarks.textStyleAttrs, textStyleAttrs);
34030
+ if (runStyleId) {
34031
+ mergedTextStyleAttrs = mergedTextStyleAttrs ? { ...mergedTextStyleAttrs, styleId: runStyleId } : { styleId: runStyleId };
34032
+ }
34033
+ const runAttrs = buildRunAttrs(encodedAttrs, hadRPr, remainingProps);
34034
+ let runLevelMarks = Array.isArray(runNode.marks) ? runNode.marks.map((mark) => cloneMark$1(mark)) : [];
34035
+ if (styleChangeMarks?.length) {
34036
+ runLevelMarks = [...runLevelMarks, ...styleChangeMarks.map((mark) => cloneMark$1(mark))];
34037
+ }
34038
+ const childParams = { ...params2, nodes: contentElements };
34039
+ const content = nodeListHandler?.handler(childParams) || [];
34040
+ const contentWithRunMarks = content.map((child) => {
34041
+ if (!child || typeof child !== "object") return child;
34042
+ const baseMarks = Array.isArray(child.marks) ? child.marks.map((mark) => cloneMark$1(mark)) : [];
34043
+ if (!runLevelMarks.length) return child;
34044
+ return { ...child, marks: [...baseMarks, ...runLevelMarks.map((mark) => cloneMark$1(mark))] };
34045
+ });
34046
+ const marked = contentWithRunMarks.map((child) => applyRunMarks(child, mergedInlineMarks, mergedTextStyleAttrs));
34047
+ const filtered = marked.filter(Boolean);
34048
+ const runNodeResult = {
34049
+ type: SD_KEY_NAME,
34050
+ content: filtered
34051
+ };
34052
+ const attrs = cloneRunAttrs(runAttrs);
34053
+ if (attrs && Object.keys(attrs).length) {
34054
+ if (attrs.runProperties == null) delete attrs.runProperties;
34055
+ if (Object.keys(attrs).length) runNodeResult.attrs = attrs;
34056
+ }
34057
+ if (runLevelMarks.length) {
34058
+ runNodeResult.marks = runLevelMarks.map((mark) => cloneMark$1(mark));
34059
+ }
34060
+ return runNodeResult;
34061
+ };
34062
+ const decode$m = (params2, decodedAttrs = {}) => {
34063
+ const { node } = params2 || {};
34064
+ if (!node) return void 0;
34065
+ const { runNode: runNodeForExport, trackingMarksByType } = prepareRunTrackingContext(node);
34066
+ const runAttrs = runNodeForExport.attrs || {};
34067
+ const runProperties = Array.isArray(runAttrs.runProperties) ? runAttrs.runProperties : [];
34068
+ const exportParams = { ...params2, node: runNodeForExport };
34069
+ if (!exportParams.editor) {
34070
+ exportParams.editor = { extensionService: { extensions: [] } };
34071
+ }
34072
+ const childElements = translateChildNodes(exportParams) || [];
34073
+ let runPropertiesElement = createRunPropertiesElement(runProperties);
34074
+ const markElements = processOutputMarks(Array.isArray(runNodeForExport.marks) ? runNodeForExport.marks : []);
34075
+ if (markElements.length) {
34076
+ if (!runPropertiesElement) {
34077
+ runPropertiesElement = generateRunProps(markElements);
34078
+ } else {
34079
+ if (!Array.isArray(runPropertiesElement.elements)) runPropertiesElement.elements = [];
34080
+ const existingNames = new Set(
34081
+ runPropertiesElement.elements.map((el) => el?.name).filter((name) => typeof name === "string")
34082
+ );
34083
+ markElements.forEach((element) => {
34084
+ if (!element || !element.name || existingNames.has(element.name)) return;
34085
+ runPropertiesElement.elements.push({ ...element, attributes: { ...element.attributes || {} } });
34086
+ existingNames.add(element.name);
34087
+ });
34088
+ }
34089
+ }
34090
+ const runPropsTemplate = runPropertiesElement ? cloneXmlNode(runPropertiesElement) : null;
34091
+ const applyBaseRunProps = (runNode) => applyRunPropertiesTemplate(runNode, runPropsTemplate);
34092
+ const runs = [];
34093
+ childElements.forEach((child) => {
34094
+ if (!child) return;
34095
+ if (child.name === "w:r") {
34096
+ const clonedRun = cloneXmlNode(child);
34097
+ applyBaseRunProps(clonedRun);
34098
+ runs.push(clonedRun);
34099
+ return;
34100
+ }
34101
+ if (child.name === "w:hyperlink") {
34102
+ const hyperlinkClone = cloneXmlNode(child);
34103
+ if (Array.isArray(hyperlinkClone.elements)) {
34104
+ hyperlinkClone.elements.forEach((run2) => applyBaseRunProps(run2));
34105
+ }
34106
+ runs.push(hyperlinkClone);
34107
+ return;
34108
+ }
34109
+ if (child.name === "w:ins" || child.name === "w:del") {
34110
+ const trackedClone = cloneXmlNode(child);
34111
+ if (Array.isArray(trackedClone.elements)) {
34112
+ trackedClone.elements.forEach((element) => {
34113
+ if (element?.name === "w:r") applyBaseRunProps(element);
34114
+ });
34115
+ }
34116
+ runs.push(trackedClone);
34117
+ return;
34118
+ }
34119
+ const runWrapper = { name: XML_NODE_NAME$f, elements: [] };
34120
+ applyBaseRunProps(runWrapper);
34121
+ if (!Array.isArray(runWrapper.elements)) runWrapper.elements = [];
34122
+ runWrapper.elements.push(cloneXmlNode(child));
34123
+ runs.push(runWrapper);
34124
+ });
34125
+ const trackedRuns = ensureTrackedWrapper(runs, trackingMarksByType);
34126
+ if (!trackedRuns.length) {
34127
+ const emptyRun = { name: XML_NODE_NAME$f, elements: [] };
34128
+ applyBaseRunProps(emptyRun);
34129
+ trackedRuns.push(emptyRun);
34130
+ }
34131
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
34132
+ trackedRuns.forEach((run2) => {
34133
+ run2.attributes = { ...run2.attributes || {}, ...decodedAttrs };
34134
+ });
34135
+ }
34136
+ if (trackedRuns.length === 1) {
34137
+ return trackedRuns[0];
34138
+ }
34139
+ return trackedRuns;
34140
+ };
32882
34141
  const config$d = {
32883
34142
  xmlName: XML_NODE_NAME$f,
32884
- sdNodeOrKeyName: SD_NODE_NAME$a,
34143
+ sdNodeOrKeyName: SD_KEY_NAME,
32885
34144
  type: NodeTranslator.translatorTypes.NODE,
32886
34145
  encode: encode$m,
32887
34146
  decode: decode$m,
@@ -34259,17 +35518,52 @@ Please report this to https://github.com/markedjs/marked.`, e) {
34259
35518
  const { nodes, docx, nodeListHandler } = params2;
34260
35519
  const node = nodes[0];
34261
35520
  let href = _resolveHref(docx, encodedAttrs);
34262
- const linkMark = { type: "link", attrs: { ...encodedAttrs, href } };
35521
+ const linkMark = { attrs: { ...encodedAttrs, href } };
34263
35522
  const runNodes = node.elements.filter((el) => el.name === "w:r");
34264
35523
  runNodes.forEach((runNode) => {
34265
- runNode.marks = [...runNode.marks || [], linkMark];
35524
+ const existingRunMarks = Array.isArray(runNode.marks) ? runNode.marks : [];
35525
+ const runMarksWithoutLink = existingRunMarks.filter((mark) => mark?.type !== "link");
35526
+ runNode.marks = runMarksWithoutLink;
34266
35527
  });
34267
35528
  const updatedNode = nodeListHandler.handler({
34268
35529
  ...params2,
34269
35530
  nodes: runNodes,
34270
35531
  path: [...params2.path || [], node]
34271
35532
  });
34272
- return updatedNode;
35533
+ const cloneMark2 = (mark) => {
35534
+ if (!mark || typeof mark !== "object") return mark;
35535
+ if (!mark.attrs) return { ...mark };
35536
+ return { ...mark, attrs: { ...mark.attrs } };
35537
+ };
35538
+ const ensureLinkMark = (child) => {
35539
+ if (!child || typeof child !== "object") return child;
35540
+ if (Array.isArray(child.content)) {
35541
+ const updatedContent = child.content.map((item) => ensureLinkMark(item));
35542
+ if (updatedContent !== child.content) {
35543
+ child = { ...child, content: updatedContent };
35544
+ }
35545
+ }
35546
+ if (child.type === "run") {
35547
+ const existingMarks2 = Array.isArray(child.marks) ? child.marks : [];
35548
+ const filteredMarks = existingMarks2.filter((mark) => mark?.type !== "link").map((mark) => cloneMark2(mark));
35549
+ if (filteredMarks.length !== existingMarks2.length) {
35550
+ if (filteredMarks.length) child = { ...child, marks: filteredMarks };
35551
+ else {
35552
+ const { marks, ...rest } = child;
35553
+ child = rest;
35554
+ }
35555
+ }
35556
+ return child;
35557
+ }
35558
+ if (child.type !== "text") return child;
35559
+ const existingMarks = Array.isArray(child.marks) ? child.marks.map((mark) => cloneMark2(mark)) : [];
35560
+ const hasLink = existingMarks.some((mark) => mark?.type === "link");
35561
+ if (hasLink) return child;
35562
+ const linkClone = { type: "link", attrs: { ...linkMark.attrs } };
35563
+ return { ...child, marks: [...existingMarks, linkClone] };
35564
+ };
35565
+ if (!Array.isArray(updatedNode)) return updatedNode;
35566
+ return updatedNode.map((child) => ensureLinkMark(child));
34273
35567
  };
34274
35568
  const _resolveHref = (docx, encodedAttrs) => {
34275
35569
  const rels = docx["word/_rels/document.xml.rels"];
@@ -35200,176 +36494,30 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35200
36494
  attributes: validXmlAttributes$4
35201
36495
  };
35202
36496
  const translator$4 = NodeTranslator.from(config$4);
35203
- const encode$a = (attributes) => {
35204
- return attributes["w:id"];
35205
- };
35206
- const decode$a = (attrs) => {
35207
- return attrs.id;
35208
- };
35209
- const attrConfig$6 = Object.freeze({
35210
- xmlName: "w:id",
35211
- sdName: "id",
35212
- encode: encode$a,
35213
- decode: decode$a
35214
- });
35215
- const encode$9 = (attributes) => {
35216
- return attributes["w:name"];
35217
- };
35218
- const decode$9 = (attrs) => {
35219
- return attrs.name;
35220
- };
35221
- const attrConfig$5 = Object.freeze({
35222
- xmlName: "w:name",
35223
- sdName: "name",
35224
- encode: encode$9,
35225
- decode: decode$9
35226
- });
35227
- const encode$8 = (attributes) => {
35228
- return attributes["w:colFirst"];
35229
- };
35230
- const decode$8 = (attrs) => {
35231
- return attrs.colFirst;
35232
- };
35233
- const attrConfig$4 = Object.freeze({
35234
- xmlName: "w:colFirst",
35235
- sdName: "colFirst",
35236
- encode: encode$8,
35237
- decode: decode$8
35238
- });
35239
- const encode$7 = (attributes) => {
35240
- return attributes["w:colLast"];
35241
- };
35242
- const decode$7 = (attrs) => {
35243
- return attrs.colLast;
35244
- };
35245
- const attrConfig$3 = Object.freeze({
35246
- xmlName: "w:colLast",
35247
- sdName: "colLast",
35248
- encode: encode$7,
35249
- decode: decode$7
35250
- });
35251
- const encode$6 = (attributes) => {
35252
- return attributes["w:displacedByCustomXml"];
35253
- };
35254
- const decode$6 = (attrs) => {
35255
- return attrs.displacedByCustomXml;
35256
- };
35257
- const attrConfig$2 = Object.freeze({
35258
- xmlName: "w:displacedByCustomXml",
35259
- sdName: "displacedByCustomXml",
35260
- encode: encode$6,
35261
- decode: decode$6
35262
- });
35263
- const validXmlAttributes$3 = [attrConfig$6, attrConfig$5, attrConfig$4, attrConfig$3, attrConfig$2];
35264
- const XML_NODE_NAME$3 = "w:bookmarkStart";
35265
- const SD_NODE_NAME$3 = "bookmarkStart";
35266
- const encode$5 = (params2, encodedAttrs = {}) => {
35267
- return {
35268
- type: "bookmarkStart",
35269
- attrs: encodedAttrs
35270
- };
35271
- };
35272
- const decode$5 = (params2, decodedAttrs = {}) => {
35273
- const result = {
35274
- name: "w:bookmarkStart",
35275
- elements: []
35276
- };
35277
- if (decodedAttrs && Object.keys(decodedAttrs).length) {
35278
- result.attributes = decodedAttrs;
35279
- }
35280
- return result;
35281
- };
35282
- const config$3 = {
35283
- xmlName: XML_NODE_NAME$3,
35284
- sdNodeOrKeyName: SD_NODE_NAME$3,
35285
- type: NodeTranslator.translatorTypes.NODE,
35286
- encode: encode$5,
35287
- decode: decode$5,
35288
- attributes: validXmlAttributes$3
35289
- };
35290
- const translator$3 = NodeTranslator.from(config$3);
35291
- const encode$4 = (attributes) => {
35292
- return attributes["w:id"];
35293
- };
35294
- const decode$4 = (attrs) => {
35295
- return attrs.id;
35296
- };
35297
- const attrConfig$1 = Object.freeze({
35298
- xmlName: "w:id",
35299
- sdName: "id",
35300
- encode: encode$4,
35301
- decode: decode$4
35302
- });
35303
- const encode$3 = (attributes) => {
35304
- return attributes["w:displacedByCustomXml"];
35305
- };
35306
- const decode$3 = (attrs) => {
35307
- return attrs.displacedByCustomXml;
35308
- };
35309
- const attrConfig = Object.freeze({
35310
- xmlName: "w:displacedByCustomXml",
35311
- sdName: "displacedByCustomXml",
35312
- encode: encode$3,
35313
- decode: decode$3
35314
- });
35315
- const validXmlAttributes$2 = [attrConfig$1, attrConfig];
35316
- const XML_NODE_NAME$2 = "w:bookmarkEnd";
35317
- const SD_NODE_NAME$2 = "bookmarkEnd";
35318
- const encode$2 = (params2, encodedAttrs = {}) => {
35319
- return {
35320
- type: "bookmarkEnd",
35321
- attrs: encodedAttrs
35322
- };
35323
- };
35324
- const decode$2 = (params2, decodedAttrs = {}) => {
35325
- const result = {
35326
- name: "w:bookmarkEnd",
35327
- elements: []
35328
- };
35329
- if (decodedAttrs && Object.keys(decodedAttrs).length) {
35330
- result.attributes = decodedAttrs;
35331
- }
35332
- return result;
35333
- };
35334
- const config$2 = {
35335
- xmlName: XML_NODE_NAME$2,
35336
- sdNodeOrKeyName: SD_NODE_NAME$2,
35337
- type: NodeTranslator.translatorTypes.NODE,
35338
- encode: encode$2,
35339
- decode: decode$2,
35340
- attributes: validXmlAttributes$2
35341
- };
35342
- const translator$2 = NodeTranslator.from(config$2);
35343
- const registeredHandlers = Object.freeze({
35344
- "w:br": translator$V,
35345
- "w:tab": translator$U,
35346
- "w:p": translator$T,
35347
- "wp:anchor": translator$5,
35348
- "wp:inline": translator$4,
35349
- "w:bookmarkStart": translator$3,
35350
- "w:bookmarkEnd": translator$2
35351
- });
35352
- const XML_NODE_NAME$1 = "w:drawing";
35353
- const SD_NODE_NAME$1 = [];
35354
- const validXmlAttributes$1 = [];
35355
- function encode$1(params2) {
36497
+ const XML_NODE_NAME$3 = "w:drawing";
36498
+ const SD_NODE_NAME$3 = [];
36499
+ const validXmlAttributes$3 = [];
36500
+ function encode$a(params2) {
35356
36501
  const nodes = params2.nodes;
35357
36502
  const node = nodes[0];
35358
- const validChildTranslators = ["wp:anchor", "wp:inline"];
36503
+ const translatorByChildName = {
36504
+ "wp:anchor": translator$5,
36505
+ "wp:inline": translator$4
36506
+ };
35359
36507
  return node.elements.reduce((acc, child) => {
35360
36508
  if (acc) return acc;
35361
- if (!validChildTranslators.includes(child.name)) return acc;
35362
- const translator2 = registeredHandlers[child.name];
36509
+ const translator2 = translatorByChildName[child.name];
36510
+ if (!translator2) return acc;
35363
36511
  return translator2.encode({ ...params2, extraParams: { node: child } }) || acc;
35364
36512
  }, null);
35365
36513
  }
35366
- function decode$1(params2) {
36514
+ function decode$a(params2) {
35367
36515
  const { node } = params2;
35368
36516
  if (!node || !node.type) {
35369
36517
  return null;
35370
36518
  }
35371
- const handlerName = node.attrs.isAnchor ? "wp:anchor" : "wp:inline";
35372
- const resultNode = registeredHandlers[handlerName].decode(params2);
36519
+ const childTranslator = node.attrs.isAnchor ? translator$5 : translator$4;
36520
+ const resultNode = childTranslator.decode(params2);
35373
36521
  return wrapTextInRun(
35374
36522
  {
35375
36523
  name: "w:drawing",
@@ -35378,15 +36526,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35378
36526
  []
35379
36527
  );
35380
36528
  }
35381
- const config$1 = {
35382
- xmlName: XML_NODE_NAME$1,
35383
- sdNodeOrKeyName: SD_NODE_NAME$1,
36529
+ const config$3 = {
36530
+ xmlName: XML_NODE_NAME$3,
36531
+ sdNodeOrKeyName: SD_NODE_NAME$3,
35384
36532
  type: NodeTranslator.translatorTypes.NODE,
35385
- encode: encode$1,
35386
- decode: decode$1,
35387
- attributes: validXmlAttributes$1
36533
+ encode: encode$a,
36534
+ decode: decode$a,
36535
+ attributes: validXmlAttributes$3
35388
36536
  };
35389
- const translator$1 = NodeTranslator.from(config$1);
36537
+ const translator$3 = NodeTranslator.from(config$3);
35390
36538
  class CommandService {
35391
36539
  /**
35392
36540
  * @param {import('./commands/types/index.js').CommandServiceOptions} props
@@ -36724,7 +37872,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36724
37872
  return getTextNodeForExport(attrs.displayLabel, [...marks, ...marksFromAttrs], params2);
36725
37873
  }
36726
37874
  function prepareImageAnnotation(params2, imageSize) {
36727
- return translator$1.decode({
37875
+ return translator$3.decode({
36728
37876
  ...params2,
36729
37877
  imageSize
36730
37878
  });
@@ -36961,10 +38109,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36961
38109
  };
36962
38110
  return result;
36963
38111
  }
36964
- const XML_NODE_NAME = "w:sdt";
36965
- const SD_NODE_NAME = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
36966
- const validXmlAttributes = [];
36967
- function encode$B(params2) {
38112
+ const XML_NODE_NAME$2 = "w:sdt";
38113
+ const SD_NODE_NAME$2 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
38114
+ const validXmlAttributes$2 = [];
38115
+ function encode$9(params2) {
36968
38116
  const nodes = params2.nodes;
36969
38117
  const node = nodes[0];
36970
38118
  const { type: sdtType, handler: handler2 } = sdtNodeTypeStrategy(node);
@@ -36974,7 +38122,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36974
38122
  const result = handler2(params2);
36975
38123
  return result;
36976
38124
  }
36977
- function decode(params2) {
38125
+ function decode$9(params2) {
36978
38126
  const { node } = params2;
36979
38127
  if (!node || !node.type) {
36980
38128
  return null;
@@ -36990,44 +38138,193 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36990
38138
  const result = decoder();
36991
38139
  return result;
36992
38140
  }
38141
+ const config$2 = {
38142
+ xmlName: XML_NODE_NAME$2,
38143
+ sdNodeOrKeyName: SD_NODE_NAME$2,
38144
+ type: NodeTranslator.translatorTypes.NODE,
38145
+ encode: encode$9,
38146
+ decode: decode$9,
38147
+ attributes: validXmlAttributes$2
38148
+ };
38149
+ const translator$2 = NodeTranslator.from(config$2);
38150
+ const encode$8 = (attributes) => {
38151
+ return attributes["w:id"];
38152
+ };
38153
+ const decode$8 = (attrs) => {
38154
+ return attrs.id;
38155
+ };
38156
+ const attrConfig$6 = Object.freeze({
38157
+ xmlName: "w:id",
38158
+ sdName: "id",
38159
+ encode: encode$8,
38160
+ decode: decode$8
38161
+ });
38162
+ const encode$7 = (attributes) => {
38163
+ return attributes["w:name"];
38164
+ };
38165
+ const decode$7 = (attrs) => {
38166
+ return attrs.name;
38167
+ };
38168
+ const attrConfig$5 = Object.freeze({
38169
+ xmlName: "w:name",
38170
+ sdName: "name",
38171
+ encode: encode$7,
38172
+ decode: decode$7
38173
+ });
38174
+ const encode$6 = (attributes) => {
38175
+ return attributes["w:colFirst"];
38176
+ };
38177
+ const decode$6 = (attrs) => {
38178
+ return attrs.colFirst;
38179
+ };
38180
+ const attrConfig$4 = Object.freeze({
38181
+ xmlName: "w:colFirst",
38182
+ sdName: "colFirst",
38183
+ encode: encode$6,
38184
+ decode: decode$6
38185
+ });
38186
+ const encode$5 = (attributes) => {
38187
+ return attributes["w:colLast"];
38188
+ };
38189
+ const decode$5 = (attrs) => {
38190
+ return attrs.colLast;
38191
+ };
38192
+ const attrConfig$3 = Object.freeze({
38193
+ xmlName: "w:colLast",
38194
+ sdName: "colLast",
38195
+ encode: encode$5,
38196
+ decode: decode$5
38197
+ });
38198
+ const encode$4 = (attributes) => {
38199
+ return attributes["w:displacedByCustomXml"];
38200
+ };
38201
+ const decode$4 = (attrs) => {
38202
+ return attrs.displacedByCustomXml;
38203
+ };
38204
+ const attrConfig$2 = Object.freeze({
38205
+ xmlName: "w:displacedByCustomXml",
38206
+ sdName: "displacedByCustomXml",
38207
+ encode: encode$4,
38208
+ decode: decode$4
38209
+ });
38210
+ const validXmlAttributes$1 = [attrConfig$6, attrConfig$5, attrConfig$4, attrConfig$3, attrConfig$2];
38211
+ const XML_NODE_NAME$1 = "w:bookmarkStart";
38212
+ const SD_NODE_NAME$1 = "bookmarkStart";
38213
+ const encode$3 = (params2, encodedAttrs = {}) => {
38214
+ return {
38215
+ type: "bookmarkStart",
38216
+ attrs: encodedAttrs
38217
+ };
38218
+ };
38219
+ const decode$3 = (params2, decodedAttrs = {}) => {
38220
+ const result = {
38221
+ name: "w:bookmarkStart",
38222
+ elements: []
38223
+ };
38224
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
38225
+ result.attributes = decodedAttrs;
38226
+ }
38227
+ return result;
38228
+ };
38229
+ const config$1 = {
38230
+ xmlName: XML_NODE_NAME$1,
38231
+ sdNodeOrKeyName: SD_NODE_NAME$1,
38232
+ type: NodeTranslator.translatorTypes.NODE,
38233
+ encode: encode$3,
38234
+ decode: decode$3,
38235
+ attributes: validXmlAttributes$1
38236
+ };
38237
+ const translator$1 = NodeTranslator.from(config$1);
38238
+ const encode$2 = (attributes) => {
38239
+ return attributes["w:id"];
38240
+ };
38241
+ const decode$2 = (attrs) => {
38242
+ return attrs.id;
38243
+ };
38244
+ const attrConfig$1 = Object.freeze({
38245
+ xmlName: "w:id",
38246
+ sdName: "id",
38247
+ encode: encode$2,
38248
+ decode: decode$2
38249
+ });
38250
+ const encode$1 = (attributes) => {
38251
+ return attributes["w:displacedByCustomXml"];
38252
+ };
38253
+ const decode$1 = (attrs) => {
38254
+ return attrs.displacedByCustomXml;
38255
+ };
38256
+ const attrConfig = Object.freeze({
38257
+ xmlName: "w:displacedByCustomXml",
38258
+ sdName: "displacedByCustomXml",
38259
+ encode: encode$1,
38260
+ decode: decode$1
38261
+ });
38262
+ const validXmlAttributes = [attrConfig$1, attrConfig];
38263
+ const XML_NODE_NAME = "w:bookmarkEnd";
38264
+ const SD_NODE_NAME = "bookmarkEnd";
38265
+ const encode$18 = (params2, encodedAttrs = {}) => {
38266
+ return {
38267
+ type: "bookmarkEnd",
38268
+ attrs: encodedAttrs
38269
+ };
38270
+ };
38271
+ const decode = (params2, decodedAttrs = {}) => {
38272
+ const result = {
38273
+ name: "w:bookmarkEnd",
38274
+ elements: []
38275
+ };
38276
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
38277
+ result.attributes = decodedAttrs;
38278
+ }
38279
+ return result;
38280
+ };
36993
38281
  const config = {
36994
38282
  xmlName: XML_NODE_NAME,
36995
38283
  sdNodeOrKeyName: SD_NODE_NAME,
36996
38284
  type: NodeTranslator.translatorTypes.NODE,
36997
- encode: encode$B,
38285
+ encode: encode$18,
36998
38286
  decode,
36999
38287
  attributes: validXmlAttributes
37000
38288
  };
37001
38289
  const translator = NodeTranslator.from(config);
38290
+ const isLineBreakOnlyRun = (node) => {
38291
+ if (!node) return false;
38292
+ if (node.type === "lineBreak" || node.type === "hardBreak") return true;
38293
+ if (node.type !== "run") return false;
38294
+ const runContent = Array.isArray(node.content) ? node.content : [];
38295
+ if (!runContent.length) return false;
38296
+ return runContent.every((child) => child?.type === "lineBreak" || child?.type === "hardBreak");
38297
+ };
37002
38298
  function exportSchemaToJson(params2) {
37003
38299
  const { type: type2 } = params2.node || {};
37004
38300
  const router = {
37005
38301
  doc: translateDocumentNode,
37006
38302
  body: translateBodyNode,
37007
38303
  heading: translateHeadingNode,
37008
- paragraph: translator$T,
38304
+ paragraph: translator$12,
38305
+ run: translator$T,
37009
38306
  text: translateTextNode,
37010
38307
  bulletList: translateList,
37011
38308
  orderedList: translateList,
37012
- lineBreak: translator$V,
38309
+ lineBreak: translator$15,
37013
38310
  table: translator$8,
37014
38311
  tableRow: translator$F,
37015
38312
  tableCell: translator$7,
37016
- bookmarkStart: translator$3,
37017
- bookmarkEnd: translator$2,
37018
- fieldAnnotation: translator,
37019
- tab: translator$U,
37020
- image: translator$1,
37021
- hardBreak: translator$V,
38313
+ bookmarkStart: translator$1,
38314
+ bookmarkEnd: translator,
38315
+ fieldAnnotation: translator$2,
38316
+ tab: translator$13,
38317
+ image: translator$3,
38318
+ hardBreak: translator$15,
37022
38319
  commentRangeStart: () => translateCommentNode(params2, "Start"),
37023
38320
  commentRangeEnd: () => translateCommentNode(params2, "End"),
37024
38321
  commentReference: () => null,
37025
38322
  shapeContainer: translateShapeContainer,
37026
38323
  shapeTextbox: translateShapeTextbox,
37027
38324
  contentBlock: translateContentBlock,
37028
- structuredContent: translator,
37029
- structuredContentBlock: translator,
37030
- documentSection: translator,
38325
+ structuredContent: translator$2,
38326
+ structuredContentBlock: translator$2,
38327
+ documentSection: translator$2,
37031
38328
  "page-number": translatePageNumberNode,
37032
38329
  "total-page-number": translateTotalPageNumberNode
37033
38330
  };
@@ -37166,21 +38463,32 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37166
38463
  };
37167
38464
  pPrElements.push(spacingElement);
37168
38465
  }
37169
- if (indent && Object.values(indent).some((v2) => v2 !== 0)) {
37170
- const { left: left2, right: right2, firstLine, hanging } = indent;
38466
+ const hasIndent = !!indent;
38467
+ if (hasIndent) {
38468
+ const { left: left2, right: right2, firstLine, hanging, explicitLeft, explicitRight, explicitFirstLine, explicitHanging } = indent;
37171
38469
  const attributes = {};
37172
- if (left2 || left2 === 0) attributes["w:left"] = pixelsToTwips(left2);
37173
- if (right2 || right2 === 0) attributes["w:right"] = pixelsToTwips(right2);
37174
- if (firstLine || firstLine === 0) attributes["w:firstLine"] = pixelsToTwips(firstLine);
37175
- if (hanging || hanging === 0) attributes["w:hanging"] = pixelsToTwips(hanging);
37176
- if (textIndent && !attributes["w:left"]) {
38470
+ if (left2 !== void 0 && (left2 !== 0 || explicitLeft || textIndent)) {
38471
+ attributes["w:left"] = pixelsToTwips(left2);
38472
+ }
38473
+ if (right2 !== void 0 && (right2 !== 0 || explicitRight)) {
38474
+ attributes["w:right"] = pixelsToTwips(right2);
38475
+ }
38476
+ if (firstLine !== void 0 && (firstLine !== 0 || explicitFirstLine)) {
38477
+ attributes["w:firstLine"] = pixelsToTwips(firstLine);
38478
+ }
38479
+ if (hanging !== void 0 && (hanging !== 0 || explicitHanging)) {
38480
+ attributes["w:hanging"] = pixelsToTwips(hanging);
38481
+ }
38482
+ if (textIndent && attributes["w:left"] === void 0) {
37177
38483
  attributes["w:left"] = getTextIndentExportValue(textIndent);
37178
38484
  }
37179
- const indentElement = {
37180
- name: "w:ind",
37181
- attributes
37182
- };
37183
- pPrElements.push(indentElement);
38485
+ if (Object.keys(attributes).length) {
38486
+ const indentElement = {
38487
+ name: "w:ind",
38488
+ attributes
38489
+ };
38490
+ pPrElements.push(indentElement);
38491
+ }
37184
38492
  } else if (textIndent && textIndent !== "0in") {
37185
38493
  const indentElement = {
37186
38494
  name: "w:ind",
@@ -37230,12 +38538,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37230
38538
  if (sectPr) {
37231
38539
  pPrElements.push(sectPr);
37232
38540
  }
38541
+ const mapTabVal = (value) => {
38542
+ if (!value || value === "start") return "left";
38543
+ if (value === "end") return "right";
38544
+ return value;
38545
+ };
37233
38546
  const { tabStops } = attrs;
37234
38547
  if (tabStops && tabStops.length > 0) {
37235
38548
  const tabElements = tabStops.map((tab) => {
37236
38549
  const posValue = tab.originalPos !== void 0 ? tab.originalPos : pixelsToTwips(tab.pos).toString();
37237
38550
  const tabAttributes = {
37238
- "w:val": tab.val || "start",
38551
+ "w:val": mapTabVal(tab.val),
37239
38552
  "w:pos": posValue
37240
38553
  };
37241
38554
  if (tab.leader) {
@@ -37590,6 +38903,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37590
38903
  collapsedParagraph.content.push(item);
37591
38904
  }
37592
38905
  });
38906
+ collapsedParagraph.content = collapsedParagraph.content.filter((node, index2, nodes) => {
38907
+ if (!isLineBreakOnlyRun(node)) return true;
38908
+ const prevNode = nodes[index2 - 1];
38909
+ return !(prevNode && isLineBreakOnlyRun(prevNode));
38910
+ });
37593
38911
  return collapsedParagraph;
37594
38912
  };
37595
38913
  const restoreIndent = (indent) => {
@@ -37643,13 +38961,27 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37643
38961
  markElement.type = "element";
37644
38962
  break;
37645
38963
  case "italic":
37646
- delete markElement.attributes;
37647
- markElement.type = "element";
37648
- break;
37649
- case "underline":
38964
+ if (attrs?.value && attrs.value !== "1" && attrs.value !== true) {
38965
+ markElement.attributes["w:val"] = attrs.value;
38966
+ } else {
38967
+ delete markElement.attributes;
38968
+ }
37650
38969
  markElement.type = "element";
37651
- markElement.attributes["w:val"] = attrs.underlineType;
37652
38970
  break;
38971
+ case "underline": {
38972
+ const translated = translator$$.decode({
38973
+ node: {
38974
+ attrs: {
38975
+ underlineType: attrs.underlineType ?? attrs.underline ?? null,
38976
+ underlineColor: attrs.underlineColor ?? attrs.color ?? null,
38977
+ underlineThemeColor: attrs.underlineThemeColor ?? attrs.themeColor ?? null,
38978
+ underlineThemeTint: attrs.underlineThemeTint ?? attrs.themeTint ?? null,
38979
+ underlineThemeShade: attrs.underlineThemeShade ?? attrs.themeShade ?? null
38980
+ }
38981
+ }
38982
+ });
38983
+ return translated || {};
38984
+ }
37653
38985
  // Text style cases
37654
38986
  case "fontSize":
37655
38987
  value = attrs.fontSize;
@@ -37667,13 +38999,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37667
38999
  markElement.name = "w:rStyle";
37668
39000
  markElement.attributes["w:val"] = attrs.styleId;
37669
39001
  break;
37670
- case "color":
37671
- let processedColor = attrs.color.replace(/^#/, "").replace(/;$/, "");
39002
+ case "color": {
39003
+ const rawColor = attrs.color;
39004
+ if (!rawColor) break;
39005
+ const normalized = String(rawColor).trim().toLowerCase();
39006
+ if (normalized === "inherit") {
39007
+ markElement.attributes["w:val"] = "auto";
39008
+ break;
39009
+ }
39010
+ let processedColor = String(rawColor).replace(/^#/, "").replace(/;$/, "");
37672
39011
  if (processedColor.startsWith("rgb")) {
37673
39012
  processedColor = rgbToHex(processedColor);
37674
39013
  }
37675
39014
  markElement.attributes["w:val"] = processedColor;
37676
39015
  break;
39016
+ }
37677
39017
  case "textAlign":
37678
39018
  markElement.attributes["w:val"] = attrs.textAlign;
37679
39019
  break;
@@ -37691,12 +39031,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37691
39031
  case "lineHeight":
37692
39032
  markElement.attributes["w:line"] = linesToTwips(attrs.lineHeight);
37693
39033
  break;
37694
- case "highlight":
37695
- markElement.attributes["w:fill"] = attrs.color?.substring(1);
37696
- markElement.attributes["w:color"] = "auto";
37697
- markElement.attributes["w:val"] = "clear";
37698
- markElement.name = "w:shd";
37699
- break;
39034
+ case "highlight": {
39035
+ const highlightValue = attrs.color ?? attrs.highlight ?? null;
39036
+ const translated = translator$14.decode({ node: { attrs: { highlight: highlightValue } } });
39037
+ return translated || {};
39038
+ }
37700
39039
  }
37701
39040
  return markElement;
37702
39041
  }
@@ -37827,8 +39166,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37827
39166
  return final;
37828
39167
  };
37829
39168
  replaceSpecialCharacters_fn = function(text) {
37830
- if (!text) return;
37831
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
39169
+ if (text === void 0 || text === null) return text;
39170
+ return String(text).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
37832
39171
  };
37833
39172
  generateXml_fn = function(node) {
37834
39173
  if (!node) return null;
@@ -37844,7 +39183,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37844
39183
  else tag += ">";
37845
39184
  let tags = [tag];
37846
39185
  if (!name && node.type === "text") {
37847
- return node.text;
39186
+ return __privateMethod$2(this, _DocxExporter_instances, replaceSpecialCharacters_fn).call(this, node.text ?? "");
37848
39187
  }
37849
39188
  if (elements) {
37850
39189
  if (name === "w:instrText") {
@@ -37970,7 +39309,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
37970
39309
  if (mainNode.name === "w:drawing") node = mainNode;
37971
39310
  else node = mainNode.elements.find((el) => el.name === "w:drawing");
37972
39311
  if (!node) return { nodes: [], consumed: 0 };
37973
- const schemaNode = translator$1.encode(params2);
39312
+ const schemaNode = translator$3.encode(params2);
37974
39313
  const newNodes = schemaNode ? [schemaNode] : [];
37975
39314
  return { nodes: newNodes, consumed: 1 };
37976
39315
  };
@@ -38073,81 +39412,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38073
39412
  handler: handleTrackChangeNode
38074
39413
  };
38075
39414
  const hyperlinkNodeHandlerEntity = generateV2HandlerEntity("hyperlinkNodeHandler", translator$6);
38076
- const handleRunNode = (params2) => {
38077
- const { nodes, nodeListHandler, parentStyleId, docx } = params2;
38078
- if (nodes.length === 0 || nodes[0].name !== "w:r") {
38079
- return { nodes: [], consumed: 0 };
38080
- }
38081
- const node = nodes[0];
38082
- const childParams = { ...params2, nodes: node.elements, path: [...params2.path || [], node] };
38083
- let processedRun = nodeListHandler.handler(childParams)?.filter((n) => n) || [];
38084
- const hasRunProperties = node.elements?.some((el) => el.name === "w:rPr");
38085
- const defaultNodeStyles = getMarksFromStyles(docx, parentStyleId);
38086
- if (hasRunProperties) {
38087
- const { marks = [] } = parseProperties(node);
38088
- let runStyleAttributes = [];
38089
- const runStyleElement = node.elements?.find((el) => el.name === "w:rPr")?.elements?.find((el) => el.name === "w:rStyle");
38090
- let runStyleId;
38091
- if (runStyleElement && runStyleElement.attributes?.["w:val"] && docx) {
38092
- runStyleId = runStyleElement.attributes["w:val"];
38093
- const runStyleDefinition = getMarksFromStyles(docx, runStyleId);
38094
- if (runStyleDefinition.marks && runStyleDefinition.marks.length > 0) {
38095
- runStyleAttributes = runStyleDefinition.marks;
38096
- }
38097
- }
38098
- let paragraphStyleAttributes = [];
38099
- if (defaultNodeStyles.marks) {
38100
- paragraphStyleAttributes = defaultNodeStyles.marks.filter((mark) => {
38101
- if (["bold"].includes(mark.type) && marks.find((m2) => m2.type === "bold")?.attrs?.value === "0") {
38102
- return false;
38103
- }
38104
- return true;
38105
- });
38106
- }
38107
- const combinedMarks = [...paragraphStyleAttributes];
38108
- runStyleAttributes.forEach((runStyle) => {
38109
- const exists2 = combinedMarks.some(
38110
- (mark) => mark.type === runStyle.type && JSON.stringify(mark.attrs || {}) === JSON.stringify(runStyle.attrs || {})
38111
- );
38112
- if (!exists2) {
38113
- combinedMarks.push(runStyle);
38114
- }
38115
- });
38116
- marks.forEach((mark) => {
38117
- const exists2 = combinedMarks.some(
38118
- (existing) => existing.type === mark.type && JSON.stringify(existing.attrs || {}) === JSON.stringify(mark.attrs || {})
38119
- );
38120
- if (!exists2) {
38121
- combinedMarks.push(mark);
38122
- }
38123
- });
38124
- if (runStyleId) combinedMarks.push({ type: "textStyle", attrs: { styleId: runStyleId } });
38125
- if (node.marks) combinedMarks.push(...node.marks);
38126
- const newMarks = createImportMarks(combinedMarks);
38127
- processedRun = processedRun.map((n) => {
38128
- const existingMarks = n.marks || [];
38129
- return {
38130
- ...n,
38131
- marks: [...newMarks, ...existingMarks]
38132
- };
38133
- });
38134
- }
38135
- return { nodes: processedRun, consumed: 1 };
38136
- };
38137
- const getMarksFromStyles = (docx, styleId) => {
38138
- const styles = docx?.["word/styles.xml"];
38139
- if (!styles) {
38140
- return {};
38141
- }
38142
- const styleTags = styles.elements[0].elements.filter((style22) => style22.name === "w:style");
38143
- const style2 = styleTags.find((tag) => tag.attributes["w:styleId"] === styleId) || {};
38144
- if (!style2) return {};
38145
- return parseProperties(style2);
38146
- };
38147
- const runNodeHandlerEntity = {
38148
- handlerName: "runNodeHandler",
38149
- handler: handleRunNode
38150
- };
39415
+ const runNodeHandlerEntity = generateV2HandlerEntity("runNodeHandler", translator$T);
38151
39416
  const handleTextNode = (params2) => {
38152
39417
  const { nodes, insideTrackChange } = params2;
38153
39418
  if (nodes.length === 0 || !(nodes[0].name === "w:t" || insideTrackChange && nodes[0].name === "w:delText")) {
@@ -38159,6 +39424,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38159
39424
  let text;
38160
39425
  if (elements.length === 1) {
38161
39426
  text = elements[0].text;
39427
+ const xmlSpace = node.attributes?.["xml:space"] ?? elements[0]?.attributes?.["xml:space"];
39428
+ if (xmlSpace !== "preserve" && typeof text === "string") {
39429
+ text = text.replace(/^\s+/, "").replace(/\s+$/, "");
39430
+ }
38162
39431
  text = text.replace(/\[\[sdspace\]\]/g, "");
38163
39432
  } else if (!elements.length && "attributes" in node && node.attributes["xml:space"] === "preserve") {
38164
39433
  text = " ";
@@ -38184,7 +39453,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38184
39453
  if (nodes.length === 0 || nodes[0].name !== "w:p") {
38185
39454
  return { nodes: [], consumed: 0 };
38186
39455
  }
38187
- const schemaNode = translator$T.encode(params2);
39456
+ const schemaNode = translator$12.encode(params2);
38188
39457
  const newNodes = schemaNode ? [schemaNode] : [];
38189
39458
  return { nodes: newNodes, consumed: 1 };
38190
39459
  };
@@ -38197,7 +39466,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38197
39466
  if (nodes.length === 0 || nodes[0].name !== "w:sdt") {
38198
39467
  return { nodes: [], consumed: 0 };
38199
39468
  }
38200
- const result = translator.encode(params2);
39469
+ const result = translator$2.encode(params2);
38201
39470
  if (!result) {
38202
39471
  return { nodes: [], consumed: 0 };
38203
39472
  }
@@ -38287,7 +39556,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38287
39556
  if (nodes.length === 0 || nodes[0].name !== "w:br") {
38288
39557
  return { nodes: [], consumed: 0 };
38289
39558
  }
38290
- const result = translator$V.encode(params2);
39559
+ const result = translator$15.encode(params2);
38291
39560
  if (!result) return { nodes: [], consumed: 0 };
38292
39561
  return {
38293
39562
  nodes: [result],
@@ -38359,7 +39628,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38359
39628
  if (isCustomMarkBookmark(nodes[0], params2.editor)) {
38360
39629
  return handleBookmarkNode(params2);
38361
39630
  }
38362
- const node = translator$3.encode(params2);
39631
+ const node = translator$1.encode(params2);
38363
39632
  if (!node) return { nodes: [], consumed: 0 };
38364
39633
  return { nodes: [node], consumed: 1 };
38365
39634
  };
@@ -38391,7 +39660,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
38391
39660
  if (!nodes.length || nodes[0].name !== "w:bookmarkEnd") {
38392
39661
  return { nodes: [], consumed: 0 };
38393
39662
  }
38394
- const node = translator$2.encode(params2);
39663
+ const node = translator.encode(params2);
38395
39664
  if (!node) return { nodes: [], consumed: 0 };
38396
39665
  return { nodes: [node], consumed: 1 };
38397
39666
  };
@@ -39003,7 +40272,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39003
40272
  if (!nodes.length || nodes[0].name !== "w:tab") {
39004
40273
  return { nodes: [], consumed: 0 };
39005
40274
  }
39006
- const node = translator$U.encode(params2);
40275
+ const node = translator$13.encode(params2);
39007
40276
  return { nodes: [node], consumed: 1 };
39008
40277
  };
39009
40278
  const tabNodeEntityHandler = {
@@ -39452,6 +40721,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39452
40721
  };
39453
40722
  const HYPERLINK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
39454
40723
  const HEADER_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
40724
+ const FONT_FAMILY_FALLBACKS = Object.freeze({
40725
+ swiss: "Arial, sans-serif",
40726
+ roman: "Times New Roman, serif",
40727
+ modern: "Courier New, monospace",
40728
+ script: "cursive",
40729
+ decorative: "fantasy",
40730
+ system: "system-ui",
40731
+ auto: "sans-serif"
40732
+ });
40733
+ const DEFAULT_GENERIC_FALLBACK = "sans-serif";
39455
40734
  const _SuperConverter = class _SuperConverter2 {
39456
40735
  constructor(params2 = null) {
39457
40736
  __privateAdd$2(this, _SuperConverter_instances);
@@ -39487,6 +40766,31 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39487
40766
  this.documentId = params2?.documentId || null;
39488
40767
  if (this.docx.length || this.xml) this.parseFromXml();
39489
40768
  }
40769
+ static getFontTableEntry(docx, fontName) {
40770
+ if (!docx || !fontName) return null;
40771
+ const fontTable = docx["word/fontTable.xml"];
40772
+ if (!fontTable?.elements?.length) return null;
40773
+ const fontsNode = fontTable.elements.find((el) => el.name === "w:fonts");
40774
+ if (!fontsNode?.elements?.length) return null;
40775
+ return fontsNode.elements.find((el) => el?.attributes?.["w:name"] === fontName) || null;
40776
+ }
40777
+ static getFallbackFromFontTable(docx, fontName) {
40778
+ const fontEntry = _SuperConverter2.getFontTableEntry(docx, fontName);
40779
+ const family = fontEntry?.elements?.find((child) => child.name === "w:family")?.attributes?.["w:val"];
40780
+ if (!family) return null;
40781
+ const mapped = FONT_FAMILY_FALLBACKS[family.toLowerCase()];
40782
+ return mapped || DEFAULT_GENERIC_FALLBACK;
40783
+ }
40784
+ static toCssFontFamily(fontName, docx) {
40785
+ if (!fontName) return fontName;
40786
+ if (fontName.includes(",")) return fontName;
40787
+ const fallback = _SuperConverter2.getFallbackFromFontTable(docx, fontName) || DEFAULT_GENERIC_FALLBACK;
40788
+ const normalizedFallbackParts = fallback.split(",").map((part) => part.trim().toLowerCase()).filter(Boolean);
40789
+ if (normalizedFallbackParts.includes(fontName.trim().toLowerCase())) {
40790
+ return fallback;
40791
+ }
40792
+ return `${fontName}, ${fallback}`;
40793
+ }
39490
40794
  /**
39491
40795
  * Get the DocxHelpers object that contains utility functions for working with docx files.
39492
40796
  * @returns {import('./docx-helpers/docx-helpers.js').DocxHelpers} The DocxHelpers object.
@@ -39583,13 +40887,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
39583
40887
  if (rPrDefaults) {
39584
40888
  const rPr = rPrDefaults.elements?.find((el) => el.name === "w:rPr");
39585
40889
  const fonts = rPr?.elements?.find((el) => el.name === "w:rFonts");
39586
- typeface = fonts?.attributes["w:ascii"];
39587
- const fontSize2 = typeface ?? rPr?.elements?.find((el) => el.name === "w:sz")?.attributes["w:val"];
39588
- fontSizeNormal = !fontSizeNormal && fontSize2 ? Number(fontSize2) / 2 : null;
40890
+ if (fonts?.attributes?.["w:ascii"]) {
40891
+ typeface = fonts.attributes["w:ascii"];
40892
+ }
40893
+ const fontSizeRaw = rPr?.elements?.find((el) => el.name === "w:sz")?.attributes?.["w:val"];
40894
+ if (!fontSizeNormal && fontSizeRaw) {
40895
+ fontSizeNormal = Number(fontSizeRaw) / 2;
40896
+ }
39589
40897
  }
39590
- const fontSizePt = fontSizeNormal || Number(rElements.find((el) => el.name === "w:sz")?.attributes["w:val"]) / 2 || 10;
40898
+ const fallbackSz = Number(rElements.find((el) => el.name === "w:sz")?.attributes?.["w:val"]);
40899
+ const fontSizePt = fontSizeNormal ?? (Number.isFinite(fallbackSz) ? fallbackSz / 2 : void 0) ?? 10;
39591
40900
  const kern = rElements.find((el) => el.name === "w:kern")?.attributes["w:val"];
39592
- return { fontSizePt, kern, typeface, panose };
40901
+ const fontFamilyCss = _SuperConverter2.toCssFontFamily(typeface, this.convertedXml);
40902
+ return { fontSizePt, kern, typeface, panose, fontFamilyCss };
39593
40903
  }
39594
40904
  }
39595
40905
  getDocumentFonts() {
@@ -51426,6 +52736,96 @@ Please report this to https://github.com/markedjs/marked.`, e) {
51426
52736
  if (isActive2) return commands2.unsetMark(type2, { extendEmptyMarkRange });
51427
52737
  return commands2.setMark(type2, attrs);
51428
52738
  };
52739
+ const toggleMarkCascade = (markName, options = {}) => ({ state: state2, chain, editor }) => {
52740
+ const {
52741
+ negationAttrs = { value: "0" },
52742
+ isNegation = (attrs) => attrs?.value === "0",
52743
+ styleDetector = defaultStyleDetector,
52744
+ extendEmptyMarkRange = true
52745
+ } = options;
52746
+ const selectionMarks = getMarksFromSelection(state2) || [];
52747
+ const inlineMarks = selectionMarks.filter((m2) => m2.type?.name === markName);
52748
+ const hasNegation = inlineMarks.some((m2) => isNegation(m2.attrs || {}));
52749
+ const hasInline = inlineMarks.some((m2) => !isNegation(m2.attrs || {}));
52750
+ const styleOn = styleDetector({ state: state2, selectionMarks, markName, editor });
52751
+ const cmdChain = chain();
52752
+ if (hasNegation) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
52753
+ if (hasInline && styleOn) {
52754
+ return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
52755
+ }
52756
+ if (hasInline) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
52757
+ if (styleOn) return cmdChain.setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
52758
+ return cmdChain.setMark(markName, {}, { extendEmptyMarkRange }).run();
52759
+ };
52760
+ function defaultStyleDetector({ state: state2, selectionMarks, markName, editor }) {
52761
+ try {
52762
+ const styleId = getEffectiveStyleId(state2, selectionMarks);
52763
+ if (!styleId || !editor?.converter?.linkedStyles) return false;
52764
+ const styles = editor.converter.linkedStyles;
52765
+ const seen = /* @__PURE__ */ new Set();
52766
+ let current = styleId;
52767
+ const key2 = mapMarkToStyleKey(markName);
52768
+ while (current && !seen.has(current)) {
52769
+ seen.add(current);
52770
+ const style2 = styles.find((s) => s.id === current);
52771
+ const def2 = style2?.definition?.styles || {};
52772
+ if (key2 in def2) {
52773
+ const raw = def2[key2];
52774
+ if (raw === void 0) return true;
52775
+ const val = raw?.value ?? raw;
52776
+ return isStyleTokenEnabled(val);
52777
+ }
52778
+ current = style2?.definition?.attrs?.basedOn || null;
52779
+ }
52780
+ return false;
52781
+ } catch {
52782
+ return false;
52783
+ }
52784
+ }
52785
+ function getEffectiveStyleId(state2, selectionMarks) {
52786
+ const sidFromMarks = getStyleIdFromMarks(selectionMarks);
52787
+ if (sidFromMarks) return sidFromMarks;
52788
+ const $from = state2.selection.$from;
52789
+ const before = $from.nodeBefore;
52790
+ const after = $from.nodeAfter;
52791
+ if (before && before.marks) {
52792
+ const sid = getStyleIdFromMarks(before.marks);
52793
+ if (sid) return sid;
52794
+ }
52795
+ if (after && after.marks) {
52796
+ const sid = getStyleIdFromMarks(after.marks);
52797
+ if (sid) return sid;
52798
+ }
52799
+ const ts = selectionMarks.find((m2) => m2.type?.name === "textStyle" && m2.attrs?.styleId);
52800
+ if (ts) return ts.attrs.styleId;
52801
+ const pos = state2.selection.$from.pos;
52802
+ const $pos = state2.doc.resolve(pos);
52803
+ for (let d2 = $pos.depth; d2 >= 0; d2--) {
52804
+ const n = $pos.node(d2);
52805
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
52806
+ }
52807
+ return null;
52808
+ }
52809
+ function getStyleIdFromMarks(marks) {
52810
+ if (!Array.isArray(marks)) return null;
52811
+ const textStyleMark = marks.find((m2) => m2.type?.name === "textStyle" && m2.attrs?.styleId);
52812
+ if (textStyleMark) return textStyleMark.attrs.styleId;
52813
+ return null;
52814
+ }
52815
+ function mapMarkToStyleKey(markName) {
52816
+ if (markName === "textStyle" || markName === "color") return "color";
52817
+ return markName;
52818
+ }
52819
+ function isStyleTokenEnabled(val) {
52820
+ if (val === false || val === 0) return false;
52821
+ if (typeof val === "string") {
52822
+ const normalized = val.trim().toLowerCase();
52823
+ if (!normalized) return false;
52824
+ if (["0", "false", "none", "inherit", "transparent"].includes(normalized)) return false;
52825
+ return true;
52826
+ }
52827
+ return !!val;
52828
+ }
51429
52829
  const clearNodes = () => ({ state: state2, tr, dispatch }) => {
51430
52830
  const { selection } = tr;
51431
52831
  const { ranges } = selection;
@@ -52771,11 +54171,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
52771
54171
  command,
52772
54172
  createParagraphNear,
52773
54173
  decreaseListIndent,
54174
+ defaultStyleDetector,
52774
54175
  deleteListItem,
52775
54176
  deleteSelection,
52776
54177
  exitCode,
52777
54178
  first,
54179
+ getEffectiveStyleId,
52778
54180
  getParaCtx,
54181
+ getStyleIdFromMarks,
52779
54182
  handleBackspaceNextToList,
52780
54183
  handleDeleteNextToList,
52781
54184
  increaseListIndent,
@@ -52784,12 +54187,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
52784
54187
  insertTabChar,
52785
54188
  insertTabCharacter,
52786
54189
  insertTabNode,
54190
+ isStyleTokenEnabled,
52787
54191
  joinBackward,
52788
54192
  joinDown,
52789
54193
  joinForward,
52790
54194
  joinUp,
52791
54195
  liftEmptyBlock,
52792
54196
  liftListItem,
54197
+ mapMarkToStyleKey,
52793
54198
  nearestListAt,
52794
54199
  newlineInCode,
52795
54200
  rebuildListNodeWithNewNum,
@@ -52809,6 +54214,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
52809
54214
  splitListItem,
52810
54215
  toggleList,
52811
54216
  toggleMark,
54217
+ toggleMarkCascade,
52812
54218
  toggleNode,
52813
54219
  undoInputRule,
52814
54220
  unsetAllMarks,
@@ -52824,6 +54230,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
52824
54230
  });
52825
54231
  const handleEnter = (editor) => {
52826
54232
  return editor.commands.first(({ commands: commands2 }) => [
54233
+ () => commands2.splitRun(),
52827
54234
  () => commands2.newlineInCode(),
52828
54235
  () => commands2.createParagraphNear(),
52829
54236
  () => commands2.liftEmptyBlock(),
@@ -52857,6 +54264,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
52857
54264
  addShortcuts() {
52858
54265
  const baseKeymap = {
52859
54266
  Enter: () => handleEnter(this.editor),
54267
+ "Shift-Enter": () => this.editor.commands.insertLineBreak(),
52860
54268
  "Mod-Enter": () => this.editor.commands.exitCode(),
52861
54269
  Backspace: () => handleBackspace(this.editor),
52862
54270
  "Mod-Backspace": () => handleBackspace(this.editor),
@@ -53934,7 +55342,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
53934
55342
  ydoc = ydoc || editor.options.ydoc;
53935
55343
  if (!ydoc) return;
53936
55344
  const metaMap = ydoc.getMap("meta");
53937
- const docx = [...metaMap.get("docx")];
55345
+ const docxValue = metaMap.get("docx");
55346
+ let docx = [];
55347
+ if (Array.isArray(docxValue)) {
55348
+ docx = [...docxValue];
55349
+ } else if (docxValue && typeof docxValue.toArray === "function") {
55350
+ docx = docxValue.toArray();
55351
+ } else if (docxValue && typeof docxValue[Symbol.iterator] === "function") {
55352
+ docx = Array.from(docxValue);
55353
+ }
55354
+ if (!docx.length && Array.isArray(editor.options.content)) {
55355
+ docx = [...editor.options.content];
55356
+ }
53938
55357
  const newXml = await editor.exportDocx({ getUpdatedDocs: true });
53939
55358
  Object.keys(newXml).forEach((key2) => {
53940
55359
  const fileIndex = docx.findIndex((item) => item.name === key2);
@@ -54012,7 +55431,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
54012
55431
  currentPageNumber
54013
55432
  }) => {
54014
55433
  const parentStyles = editor.converter.getDocumentDefaultStyles();
54015
- const { fontSizePt, typeface } = parentStyles;
55434
+ const { fontSizePt, typeface, fontFamilyCss } = parentStyles;
54016
55435
  const fontSizeInPixles = fontSizePt * 1.3333;
54017
55436
  const lineHeight2 = fontSizeInPixles * 1.2;
54018
55437
  Object.assign(editorContainer.style, {
@@ -54025,7 +55444,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
54025
55444
  left: "0",
54026
55445
  width: "auto",
54027
55446
  maxWidth: "none",
54028
- fontFamily: typeface,
55447
+ fontFamily: fontFamilyCss || typeface,
54029
55448
  fontSize: `${fontSizeInPixles}px`,
54030
55449
  lineHeight: `${lineHeight2}px`
54031
55450
  });
@@ -54855,7 +56274,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
54855
56274
  originalStep,
54856
56275
  originalStepIndex
54857
56276
  });
54858
- console.debug("[track-changes]: replaceStep");
54859
56277
  } else if (step instanceof AddMarkStep) {
54860
56278
  addMarkStep({
54861
56279
  state: state2,
@@ -54865,7 +56283,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
54865
56283
  user,
54866
56284
  date
54867
56285
  });
54868
- console.debug("[track-changes]: addMarkStep");
54869
56286
  } else if (step instanceof RemoveMarkStep) {
54870
56287
  removeMarkStep({
54871
56288
  state: state2,
@@ -54875,10 +56292,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
54875
56292
  user,
54876
56293
  date
54877
56294
  });
54878
- console.debug("[track-changes]: removeMarkStep");
54879
56295
  } else {
54880
56296
  newTr.step(step);
54881
- console.log("[track-changes]: otherStep");
54882
56297
  }
54883
56298
  });
54884
56299
  if (tr.getMeta("inputType")) {
@@ -56948,9 +58363,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
56948
58363
  element.style.isolation = "isolate";
56949
58364
  proseMirror.style.outline = "none";
56950
58365
  proseMirror.style.border = "none";
56951
- const { typeface, fontSizePt } = this.converter.getDocumentDefaultStyles() ?? {};
56952
- if (typeface) {
56953
- element.style.fontFamily = typeface;
58366
+ const { typeface, fontSizePt, fontFamilyCss } = this.converter.getDocumentDefaultStyles() ?? {};
58367
+ const resolvedFontFamily = fontFamilyCss || typeface;
58368
+ if (resolvedFontFamily) {
58369
+ element.style.fontFamily = resolvedFontFamily;
56954
58370
  }
56955
58371
  if (fontSizePt) {
56956
58372
  element.style.fontSize = `${fontSizePt}pt`;
@@ -57238,12 +58654,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
57238
58654
  }
57239
58655
  destroyHeaderFooterEditors() {
57240
58656
  try {
57241
- const editors = [...this.converter.headerEditors, ...this.converter.footerEditors];
58657
+ const headerEditors = this.converter?.headerEditors ?? [];
58658
+ const footerEditors = this.converter?.footerEditors ?? [];
58659
+ if (!headerEditors.length && !footerEditors.length) return;
58660
+ const editors = [...headerEditors, ...footerEditors].filter(Boolean);
57242
58661
  for (let editorData of editors) {
57243
- editorData.editor.destroy();
58662
+ editorData?.editor?.destroy?.();
57244
58663
  }
57245
- this.converter.headerEditors.length = 0;
57246
- this.converter.footerEditors.length = 0;
58664
+ if (headerEditors.length) headerEditors.length = 0;
58665
+ if (footerEditors.length) footerEditors.length = 0;
57247
58666
  } catch (error) {
57248
58667
  this.emit("exception", { error, editor: this });
57249
58668
  console.error(error);
@@ -58317,6 +59736,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
58317
59736
  },
58318
59737
  addCommands() {
58319
59738
  return {
59739
+ toggleMarkCascade,
58320
59740
  /**
58321
59741
  * Clear all formatting (nodes and marks)
58322
59742
  * @category Command
@@ -59296,27 +60716,69 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59296
60716
  return {};
59297
60717
  }
59298
60718
  });
59299
- const RunItem = Node$1.create({
60719
+ const splitRun = () => (props) => {
60720
+ const { state: state2, view, tr } = props;
60721
+ const { $from, empty: empty2 } = state2.selection;
60722
+ if (!empty2) return false;
60723
+ if ($from.parent.type.name !== "run") return false;
60724
+ const handled = splitBlock(state2, (transaction) => {
60725
+ view.dispatch(transaction);
60726
+ });
60727
+ if (handled) {
60728
+ tr.setMeta("preventDispatch", true);
60729
+ }
60730
+ return handled;
60731
+ };
60732
+ const Run = OxmlNode.create({
59300
60733
  name: "run",
60734
+ oXmlName: "w:r",
59301
60735
  group: "inline",
59302
- content: "text*",
59303
60736
  inline: true,
60737
+ content: "inline*",
60738
+ selectable: false,
60739
+ childToAttributes: ["runProperties"],
59304
60740
  addOptions() {
59305
- return {};
59306
- },
59307
- parseDOM() {
59308
- return [{ tag: "run" }];
59309
- },
59310
- renderDOM() {
59311
- return ["run", 0];
60741
+ return {
60742
+ htmlAttributes: {
60743
+ "data-run": "1"
60744
+ }
60745
+ };
59312
60746
  },
59313
60747
  addAttributes() {
59314
60748
  return {
59315
- attributes: {
60749
+ runProperties: {
60750
+ default: null,
60751
+ rendered: false,
60752
+ keepOnSplit: true
60753
+ },
60754
+ rsidR: {
60755
+ default: null,
60756
+ rendered: false,
60757
+ keepOnSplit: true
60758
+ },
60759
+ rsidRPr: {
60760
+ default: null,
59316
60761
  rendered: false,
59317
- "aria-label": "Run node"
60762
+ keepOnSplit: true
60763
+ },
60764
+ rsidDel: {
60765
+ default: null,
60766
+ rendered: false,
60767
+ keepOnSplit: true
59318
60768
  }
59319
60769
  };
60770
+ },
60771
+ addCommands() {
60772
+ return {
60773
+ splitRun
60774
+ };
60775
+ },
60776
+ parseDOM() {
60777
+ return [{ tag: "span[data-run]" }];
60778
+ },
60779
+ renderDOM({ htmlAttributes }) {
60780
+ const base2 = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
60781
+ return ["span", base2, 0];
59320
60782
  }
59321
60783
  });
59322
60784
  const inputRegex$1 = /^\s*([-+*])\s$/;
@@ -59591,6 +61053,115 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59591
61053
  ];
59592
61054
  }
59593
61055
  });
61056
+ const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
61057
+ const handler2 = listIndexMap[listNumberingType];
61058
+ return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
61059
+ };
61060
+ const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
61061
+ const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
61062
+ const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
61063
+ const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
61064
+ const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p2) => intToAlpha(p2));
61065
+ const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
61066
+ const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
61067
+ const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
61068
+ const listIndexMap = {
61069
+ decimal: handleDecimal,
61070
+ lowerRoman: handleLowerRoman,
61071
+ upperRoman: handleRoman,
61072
+ lowerLetter: handleLowerAlpha,
61073
+ upperLetter: handleAlpha,
61074
+ ordinal: handleOrdinal,
61075
+ custom: handleCustom,
61076
+ japaneseCounting: handleJapaneseCounting
61077
+ };
61078
+ const createNumbering = (values, lvlText) => {
61079
+ return values.reduce((acc, value, index2) => {
61080
+ return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
61081
+ }, lvlText);
61082
+ };
61083
+ const generateNumbering = (path, lvlText, formatter) => {
61084
+ const formattedValues = path.map(formatter);
61085
+ return createNumbering(formattedValues, lvlText);
61086
+ };
61087
+ const ordinalFormatter = (level) => {
61088
+ const suffixes = ["th", "st", "nd", "rd"];
61089
+ const value = level % 100;
61090
+ const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
61091
+ const p2 = level + suffix2;
61092
+ return p2;
61093
+ };
61094
+ const generateFromCustom = (path, lvlText, customFormat) => {
61095
+ if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
61096
+ const match = customFormat.match(/(\d+)/);
61097
+ if (!match) throw new Error("Invalid format string: no numeric pattern found");
61098
+ const sample = match[1];
61099
+ const digitCount = sample.length;
61100
+ const index2 = path.pop();
61101
+ return String(index2).padStart(digitCount, "0");
61102
+ };
61103
+ const intToRoman = (num) => {
61104
+ const romanNumeralMap = [
61105
+ { value: 1e3, numeral: "M" },
61106
+ { value: 900, numeral: "CM" },
61107
+ { value: 500, numeral: "D" },
61108
+ { value: 400, numeral: "CD" },
61109
+ { value: 100, numeral: "C" },
61110
+ { value: 90, numeral: "XC" },
61111
+ { value: 50, numeral: "L" },
61112
+ { value: 40, numeral: "XL" },
61113
+ { value: 10, numeral: "X" },
61114
+ { value: 9, numeral: "IX" },
61115
+ { value: 5, numeral: "V" },
61116
+ { value: 4, numeral: "IV" },
61117
+ { value: 1, numeral: "I" }
61118
+ ];
61119
+ let result = "";
61120
+ for (const { value, numeral } of romanNumeralMap) {
61121
+ while (num >= value) {
61122
+ result += numeral;
61123
+ num -= value;
61124
+ }
61125
+ }
61126
+ return result;
61127
+ };
61128
+ const intToAlpha = (num) => {
61129
+ let result = "";
61130
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
61131
+ while (num > 0) {
61132
+ let index2 = (num - 1) % 26;
61133
+ result = alphabet[index2] + result;
61134
+ num = Math.floor((num - 1) / 26);
61135
+ }
61136
+ return result;
61137
+ };
61138
+ const intToJapaneseCounting = (num) => {
61139
+ const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
61140
+ const units = ["", "十", "百", "千"];
61141
+ if (num === 0) return "零";
61142
+ if (num < 10) return digits[num];
61143
+ let result = "";
61144
+ let tempNum = num;
61145
+ let unitIndex = 0;
61146
+ while (tempNum > 0) {
61147
+ const digit = tempNum % 10;
61148
+ if (digit !== 0) {
61149
+ const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
61150
+ result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
61151
+ } else if (result && tempNum > 0) {
61152
+ if (!result.startsWith("零") && tempNum % 100 !== 0) {
61153
+ result = "零" + result;
61154
+ }
61155
+ }
61156
+ tempNum = Math.floor(tempNum / 10);
61157
+ unitIndex++;
61158
+ if (unitIndex > 3) break;
61159
+ }
61160
+ if (num >= 10 && num < 20) {
61161
+ result = result.replace(/^一十/, "十");
61162
+ }
61163
+ return result;
61164
+ };
59594
61165
  const CustomSelectionPluginKey = new PluginKey("CustomSelection");
59595
61166
  const handleClickOutside = (event, editor) => {
59596
61167
  const editorElem = editor?.options?.element;
@@ -59871,6 +61442,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59871
61442
  case "textStyle":
59872
61443
  const { fontFamily: fontFamily2, fontSize: fontSize2 } = attr.attrs;
59873
61444
  styles += `${fontFamily2 ? `font-family: ${fontFamily2};` : ""} ${fontSize2 ? `font-size: ${fontSize2};` : ""}`;
61445
+ break;
59874
61446
  }
59875
61447
  }
59876
61448
  return styles.trim();
@@ -59889,12 +61461,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59889
61461
  const linkedDefinitionStyles = { ...linkedStyle.definition.styles };
59890
61462
  const basedOnDefinitionStyles = { ...basedOnStyle?.definition?.styles };
59891
61463
  const resultStyles = { ...linkedDefinitionStyles };
59892
- if (!linkedDefinitionStyles["font-size"] && basedOnDefinitionStyles["font-size"]) {
59893
- resultStyles["font-size"] = basedOnDefinitionStyles["font-size"];
59894
- }
59895
- if (!linkedDefinitionStyles["text-transform"] && basedOnDefinitionStyles["text-transform"]) {
59896
- resultStyles["text-transform"] = basedOnDefinitionStyles["text-transform"];
59897
- }
61464
+ const inheritKeys = [
61465
+ "font-size",
61466
+ "font-family",
61467
+ "text-transform",
61468
+ "bold",
61469
+ "italic",
61470
+ "underline",
61471
+ "strike",
61472
+ "color",
61473
+ "highlight"
61474
+ ];
61475
+ inheritKeys.forEach((k) => {
61476
+ if (!linkedDefinitionStyles[k] && basedOnDefinitionStyles[k]) {
61477
+ resultStyles[k] = basedOnDefinitionStyles[k];
61478
+ }
61479
+ });
59898
61480
  Object.entries(resultStyles).forEach(([k, value]) => {
59899
61481
  const key2 = kebabCase$2(k);
59900
61482
  const flattenedMarks = [];
@@ -59909,6 +61491,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59909
61491
  }
59910
61492
  flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
59911
61493
  });
61494
+ const underlineNone = node?.marks?.some((m2) => m2.type?.name === "underline" && m2.attrs?.underlineType === "none");
61495
+ if (underlineNone) {
61496
+ markValue["text-decoration"] = "none";
61497
+ }
59912
61498
  const mark = flattenedMarks.find((n) => n.key === key2);
59913
61499
  const hasParentIndent = Object.keys(parent?.attrs?.indent || {});
59914
61500
  const hasParentSpacing = Object.keys(parent?.attrs?.spacing || {});
@@ -59925,10 +61511,28 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59925
61511
  if (rightIndent) markValue["margin-right"] = rightIndent + "px";
59926
61512
  if (firstLine) markValue["text-indent"] = firstLine + "px";
59927
61513
  } else if (key2 === "bold" && node) {
59928
- const val = value?.value;
59929
- if (!listTypes.includes(node.type.name) && val !== "0") {
61514
+ const boldValue = typeof value === "object" && value !== null ? value.value : value;
61515
+ const hasInlineBoldOff = node.marks?.some((m2) => m2.type?.name === "bold" && m2.attrs?.value === "0");
61516
+ const hasInlineBoldOn = node.marks?.some((m2) => m2.type?.name === "bold" && m2.attrs?.value !== "0");
61517
+ if (!listTypes.includes(node.type.name) && !hasInlineBoldOff && !hasInlineBoldOn && boldValue !== "0" && boldValue !== false) {
59930
61518
  markValue["font-weight"] = "bold";
59931
61519
  }
61520
+ } else if (key2 === "italic" && node) {
61521
+ const italicValue = typeof value === "object" && value !== null ? value.value : value;
61522
+ const hasInlineItalicOff = node.marks?.some((m2) => m2.type?.name === "italic" && m2.attrs?.value === "0");
61523
+ const hasInlineItalicOn = node.marks?.some((m2) => m2.type?.name === "italic" && m2.attrs?.value !== "0");
61524
+ if (!listTypes.includes(node.type.name) && !hasInlineItalicOff && !hasInlineItalicOn && italicValue !== "0" && italicValue !== false) {
61525
+ markValue["font-style"] = "italic";
61526
+ }
61527
+ } else if (key2 === "strike" && node) {
61528
+ const strikeValue = typeof value === "object" && value !== null ? value.value : value;
61529
+ const hasInlineStrikeOff = node.marks?.some((m2) => m2.type?.name === "strike" && m2.attrs?.value === "0");
61530
+ const hasInlineStrikeOn = node.marks?.some(
61531
+ (m2) => m2.type?.name === "strike" && (m2.attrs?.value === void 0 || m2.attrs?.value !== "0")
61532
+ );
61533
+ if (!listTypes.includes(node.type.name) && !hasInlineStrikeOff && !hasInlineStrikeOn && strikeValue !== "0" && strikeValue !== false) {
61534
+ markValue["text-decoration"] = "line-through";
61535
+ }
59932
61536
  } else if (key2 === "text-transform" && node) {
59933
61537
  if (!listTypes.includes(node.type.name)) {
59934
61538
  markValue[key2] = value;
@@ -59937,10 +61541,44 @@ Please report this to https://github.com/markedjs/marked.`, e) {
59937
61541
  if (!listTypes.includes(node.type.name)) {
59938
61542
  markValue[key2] = value;
59939
61543
  }
61544
+ } else if (key2 === "font-family" && node) {
61545
+ if (!listTypes.includes(node.type.name)) {
61546
+ markValue[key2] = value;
61547
+ }
59940
61548
  } else if (key2 === "color" && node) {
59941
61549
  if (!listTypes.includes(node.type.name)) {
59942
61550
  markValue[key2] = value;
59943
61551
  }
61552
+ } else if (key2 === "highlight" && node) {
61553
+ const hasInlineHighlight = node.marks?.some((m2) => m2.type?.name === "highlight");
61554
+ if (!listTypes.includes(node.type.name) && !hasInlineHighlight) {
61555
+ const color = typeof value === "string" ? value : value?.color;
61556
+ if (color) markValue["background-color"] = color;
61557
+ }
61558
+ } else if (key2 === "underline" && node) {
61559
+ const styleValRaw = value?.value ?? value ?? "";
61560
+ const styleVal = styleValRaw.toString().toLowerCase();
61561
+ const hasInlineUnderlineOff = node.marks?.some(
61562
+ (m2) => m2.type?.name === "underline" && m2.attrs?.underlineType === "none"
61563
+ );
61564
+ const hasInlineUnderlineOn = node.marks?.some(
61565
+ (m2) => m2.type?.name === "underline" && m2.attrs?.underlineType && m2.attrs.underlineType !== "none"
61566
+ );
61567
+ if (!listTypes.includes(node.type.name) && !hasInlineUnderlineOff && !hasInlineUnderlineOn) {
61568
+ if (styleVal && styleVal !== "none" && styleVal !== "0") {
61569
+ const colorVal = value && typeof value === "object" ? value.color || value.underlineColor || null : null;
61570
+ const css = getUnderlineCssString({ type: styleVal, color: colorVal });
61571
+ css.split(";").forEach((decl) => {
61572
+ const d2 = decl.trim();
61573
+ if (!d2) return;
61574
+ const idx = d2.indexOf(":");
61575
+ if (idx === -1) return;
61576
+ const k2 = d2.slice(0, idx).trim();
61577
+ const v2 = d2.slice(idx + 1).trim();
61578
+ markValue[k2] = v2;
61579
+ });
61580
+ }
61581
+ }
59944
61582
  } else if (typeof value === "string") {
59945
61583
  markValue[key2] = value;
59946
61584
  }
@@ -60073,23 +61711,51 @@ Please report this to https://github.com/markedjs/marked.`, e) {
60073
61711
  };
60074
61712
  const generateDecorations = (state2, styles) => {
60075
61713
  const decorations = [];
60076
- let lastStyleId = null;
60077
61714
  const doc2 = state2?.doc;
61715
+ const getParagraphStyleId = (pos) => {
61716
+ const $pos = state2.doc.resolve(pos);
61717
+ for (let d2 = $pos.depth; d2 >= 0; d2--) {
61718
+ const n = $pos.node(d2);
61719
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
61720
+ }
61721
+ return null;
61722
+ };
60078
61723
  doc2.descendants((node, pos) => {
60079
61724
  const { name } = node.type;
60080
- if (node?.attrs?.styleId) lastStyleId = node.attrs.styleId;
60081
- if (name === "paragraph" && !node.attrs?.styleId) lastStyleId = null;
60082
- if (name !== "text" && name !== "listItem" && name !== "orderedList") return;
61725
+ if (name !== "text") return;
61726
+ const paragraphStyleId = getParagraphStyleId(pos);
61727
+ let runStyleId = null;
61728
+ let inlineTextStyleId = null;
60083
61729
  for (const mark of node.marks) {
60084
- if (mark.type.name === "textStyle" && mark.attrs.styleId) {
60085
- lastStyleId = mark.attrs.styleId;
60086
- }
60087
- }
60088
- const { linkedStyle, basedOnStyle } = getLinkedStyle(lastStyleId, styles);
60089
- if (!linkedStyle) return;
61730
+ if (mark.type.name === "run") {
61731
+ const rp = mark.attrs?.runProperties;
61732
+ if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
61733
+ else if (Array.isArray(rp)) {
61734
+ const ent = rp.find((e) => e?.xmlName === "w:rStyle");
61735
+ const sid = ent?.attributes?.["w:val"];
61736
+ if (sid) runStyleId = sid;
61737
+ }
61738
+ } else if (mark.type.name === "textStyle" && mark.attrs?.styleId) {
61739
+ inlineTextStyleId = mark.attrs.styleId;
61740
+ }
61741
+ }
61742
+ const buildStyleMap = (sid) => {
61743
+ if (!sid) return {};
61744
+ const { linkedStyle, basedOnStyle: basedOnStyle2 } = getLinkedStyle(sid, styles);
61745
+ if (!linkedStyle) return {};
61746
+ const base2 = { ...basedOnStyle2?.definition?.styles || {} };
61747
+ return { ...base2, ...linkedStyle.definition?.styles || {} };
61748
+ };
61749
+ const pMap = buildStyleMap(paragraphStyleId);
61750
+ const tMap = buildStyleMap(inlineTextStyleId);
61751
+ const rMap = buildStyleMap(runStyleId);
61752
+ const finalStyles = { ...pMap, ...tMap, ...rMap };
61753
+ if (Object.keys(finalStyles).length === 0) return;
61754
+ const mergedLinkedStyle = { definition: { styles: finalStyles, attrs: {} } };
61755
+ const basedOnStyle = null;
60090
61756
  const $pos = state2.doc.resolve(pos);
60091
61757
  const parent = $pos.parent;
60092
- const styleString = generateLinkedStyleString(linkedStyle, basedOnStyle, node, parent);
61758
+ const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node, parent);
60093
61759
  if (!styleString) return;
60094
61760
  const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
60095
61761
  decorations.push(decoration);
@@ -60218,115 +61884,298 @@ Please report this to https://github.com/markedjs/marked.`, e) {
60218
61884
  };
60219
61885
  }
60220
61886
  });
60221
- const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
60222
- const handler2 = listIndexMap[listNumberingType];
60223
- return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
60224
- };
60225
- const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
60226
- const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
60227
- const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
60228
- const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
60229
- const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p2) => intToAlpha(p2));
60230
- const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
60231
- const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
60232
- const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
60233
- const listIndexMap = {
60234
- decimal: handleDecimal,
60235
- lowerRoman: handleLowerRoman,
60236
- upperRoman: handleRoman,
60237
- lowerLetter: handleLowerAlpha,
60238
- upperLetter: handleAlpha,
60239
- ordinal: handleOrdinal,
60240
- custom: handleCustom,
60241
- japaneseCounting: handleJapaneseCounting
60242
- };
60243
- const createNumbering = (values, lvlText) => {
60244
- return values.reduce((acc, value, index2) => {
60245
- return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
60246
- }, lvlText);
60247
- };
60248
- const generateNumbering = (path, lvlText, formatter) => {
60249
- const formattedValues = path.map(formatter);
60250
- return createNumbering(formattedValues, lvlText);
60251
- };
60252
- const ordinalFormatter = (level) => {
60253
- const suffixes = ["th", "st", "nd", "rd"];
60254
- const value = level % 100;
60255
- const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
60256
- const p2 = level + suffix2;
60257
- return p2;
60258
- };
60259
- const generateFromCustom = (path, lvlText, customFormat) => {
60260
- if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
60261
- const match = customFormat.match(/(\d+)/);
60262
- if (!match) throw new Error("Invalid format string: no numeric pattern found");
60263
- const sample = match[1];
60264
- const digitCount = sample.length;
60265
- const index2 = path.pop();
60266
- return String(index2).padStart(digitCount, "0");
60267
- };
60268
- const intToRoman = (num) => {
60269
- const romanNumeralMap = [
60270
- { value: 1e3, numeral: "M" },
60271
- { value: 900, numeral: "CM" },
60272
- { value: 500, numeral: "D" },
60273
- { value: 400, numeral: "CD" },
60274
- { value: 100, numeral: "C" },
60275
- { value: 90, numeral: "XC" },
60276
- { value: 50, numeral: "L" },
60277
- { value: 40, numeral: "XL" },
60278
- { value: 10, numeral: "X" },
60279
- { value: 9, numeral: "IX" },
60280
- { value: 5, numeral: "V" },
60281
- { value: 4, numeral: "IV" },
60282
- { value: 1, numeral: "I" }
60283
- ];
60284
- let result = "";
60285
- for (const { value, numeral } of romanNumeralMap) {
60286
- while (num >= value) {
60287
- result += numeral;
60288
- num -= value;
61887
+ function getUnderlineCssString({ type: type2 = "single", color = null, thickness = null, approximate = true } = {}) {
61888
+ const parts = [];
61889
+ const add = (k, v2) => {
61890
+ if (!v2) return;
61891
+ parts.push(`${k}: ${v2}`);
61892
+ };
61893
+ const lower = String(type2 || "single").toLowerCase();
61894
+ if (lower === "none" || lower === "0") {
61895
+ add("text-decoration", "none");
61896
+ return parts.join("; ");
61897
+ }
61898
+ add("text-decoration-line", "underline");
61899
+ const HEAVY = thickness || "0.2em";
61900
+ const THICK = thickness || "0.15em";
61901
+ switch (lower) {
61902
+ case "single":
61903
+ break;
61904
+ case "double":
61905
+ add("text-decoration-style", "double");
61906
+ break;
61907
+ case "thick":
61908
+ add("text-decoration-thickness", THICK);
61909
+ break;
61910
+ case "dotted":
61911
+ add("text-decoration-style", "dotted");
61912
+ break;
61913
+ case "dash":
61914
+ case "dashed":
61915
+ add("text-decoration-style", "dashed");
61916
+ break;
61917
+ case "dotdash":
61918
+ case "dotdotdash":
61919
+ case "dashlong":
61920
+ case "dashlongheavy":
61921
+ if (approximate) {
61922
+ add("text-decoration-style", "dashed");
61923
+ if (lower.includes("heavy")) add("text-decoration-thickness", HEAVY);
61924
+ }
61925
+ break;
61926
+ case "dottedheavy":
61927
+ add("text-decoration-style", "dotted");
61928
+ add("text-decoration-thickness", HEAVY);
61929
+ break;
61930
+ case "dashedheavy":
61931
+ add("text-decoration-style", "dashed");
61932
+ add("text-decoration-thickness", HEAVY);
61933
+ break;
61934
+ case "wavy":
61935
+ add("text-decoration-style", "wavy");
61936
+ break;
61937
+ case "wavyheavy":
61938
+ add("text-decoration-style", "wavy");
61939
+ add("text-decoration-thickness", HEAVY);
61940
+ break;
61941
+ case "wavydouble":
61942
+ if (approximate) {
61943
+ add("text-decoration-style", "wavy");
61944
+ add("text-decoration-thickness", HEAVY);
61945
+ }
61946
+ break;
61947
+ }
61948
+ if (color) add("text-decoration-color", color);
61949
+ return parts.join("; ");
61950
+ }
61951
+ function collectTextStyleMarks(listItem, markType) {
61952
+ const textStyleMarks = [];
61953
+ const seenMarks = /* @__PURE__ */ new Set();
61954
+ const attrs = {};
61955
+ if (!markType) {
61956
+ return {
61957
+ marks: textStyleMarks,
61958
+ attrs
61959
+ };
61960
+ }
61961
+ const collectMarks = (node) => {
61962
+ if (!node) return;
61963
+ const candidateMarks = Array.isArray(node.marks) ? node.marks : [];
61964
+ if (candidateMarks.length && typeof markType.isInSet === "function" && markType.isInSet(candidateMarks)) {
61965
+ candidateMarks.forEach((mark) => {
61966
+ if (mark.type === markType && !seenMarks.has(mark)) {
61967
+ seenMarks.add(mark);
61968
+ textStyleMarks.push(mark);
61969
+ }
61970
+ });
61971
+ }
61972
+ if (!node.isText && node.childCount) {
61973
+ node.forEach((child) => collectMarks(child));
60289
61974
  }
61975
+ };
61976
+ listItem.forEach((childNode) => {
61977
+ if (childNode.type?.name !== "paragraph") return;
61978
+ if (childNode.attrs?.lineHeight !== void 0) {
61979
+ attrs.lineHeight = childNode.attrs.lineHeight;
61980
+ }
61981
+ collectMarks(childNode);
61982
+ });
61983
+ return {
61984
+ marks: textStyleMarks,
61985
+ attrs
61986
+ };
61987
+ }
61988
+ function parseSizeFromRunProperties(listRunProperties) {
61989
+ const val = listRunProperties?.["w:val"] || listRunProperties?.["w:sz"];
61990
+ if (val == null) return null;
61991
+ const numeric = Number(val);
61992
+ if (Number.isNaN(numeric) || numeric <= 0) return null;
61993
+ const sizeInPoints = numeric / 2;
61994
+ return `${sizeInPoints}pt`;
61995
+ }
61996
+ function parseFontFamilyFromRunProperties(listRunProperties) {
61997
+ const ascii = listRunProperties?.["w:ascii"];
61998
+ const hAnsi = listRunProperties?.["w:hAnsi"];
61999
+ const eastAsia = listRunProperties?.["w:eastAsia"];
62000
+ return ascii || hAnsi || eastAsia || null;
62001
+ }
62002
+ function readNodeViewStyles(view) {
62003
+ const fallback = { fontSize: null, fontFamily: null, lineHeight: null };
62004
+ if (!view?.dom) return fallback;
62005
+ const inline = {
62006
+ fontSize: view.dom.style?.fontSize || null,
62007
+ fontFamily: view.dom.style?.fontFamily || null,
62008
+ lineHeight: view.dom.style?.lineHeight || null
62009
+ };
62010
+ if (inline.fontSize && inline.fontFamily && inline.lineHeight) return inline;
62011
+ const globalWindow = typeof window !== "undefined" ? window : void 0;
62012
+ if (globalWindow?.getComputedStyle) {
62013
+ const computed2 = globalWindow.getComputedStyle(view.dom);
62014
+ return {
62015
+ fontSize: inline.fontSize || computed2.fontSize,
62016
+ fontFamily: inline.fontFamily || computed2.fontFamily,
62017
+ lineHeight: inline.lineHeight || computed2.lineHeight
62018
+ };
60290
62019
  }
60291
- return result;
60292
- };
60293
- const intToAlpha = (num) => {
60294
- let result = "";
60295
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
60296
- while (num > 0) {
60297
- let index2 = (num - 1) % 26;
60298
- result = alphabet[index2] + result;
60299
- num = Math.floor((num - 1) / 26);
62020
+ return inline;
62021
+ }
62022
+ function getAdjacentListItemNodeView({ nodeView, pos, direction, activeNodeViews }) {
62023
+ if (!activeNodeViews) return null;
62024
+ let candidate = null;
62025
+ activeNodeViews.forEach((view) => {
62026
+ if (view === nodeView) return;
62027
+ let viewPos;
62028
+ try {
62029
+ viewPos = view.getPos();
62030
+ } catch {
62031
+ return;
62032
+ }
62033
+ if (typeof viewPos !== "number") return;
62034
+ if (viewPos < pos) {
62035
+ if (!candidate || viewPos > candidate.pos) candidate = { view, pos: viewPos };
62036
+ }
62037
+ });
62038
+ return candidate?.view ?? null;
62039
+ }
62040
+ function findSiblingListItem({ editor, pos, direction }) {
62041
+ if (typeof pos !== "number" || !editor?.view) return null;
62042
+ const { state: state2 } = editor.view;
62043
+ const $pos = state2.doc.resolve(pos);
62044
+ const parentDepth = $pos.depth - 1;
62045
+ if (parentDepth < 0) return null;
62046
+ const parent = $pos.node(parentDepth);
62047
+ if (!parent) return null;
62048
+ const indexInsideParent = $pos.index(parentDepth);
62049
+ const siblingIndex = indexInsideParent + direction;
62050
+ if (siblingIndex < 0 || siblingIndex >= parent.childCount) return null;
62051
+ const sibling = parent.child(siblingIndex);
62052
+ return sibling?.type?.name === "listItem" ? sibling : null;
62053
+ }
62054
+ function deriveFontStylesFromNode({ node, textStyleType, defaultFont, defaultSize, listRunProperties }) {
62055
+ const { marks: allMarks, attrs } = collectTextStyleMarks(node, textStyleType);
62056
+ const styleMarks = textStyleType ? allMarks.filter((m2) => m2.type === textStyleType) : [];
62057
+ const sizeMark = styleMarks.find((m2) => m2.attrs?.fontSize);
62058
+ const familyMark = styleMarks.find((m2) => m2.attrs?.fontFamily);
62059
+ let fontSize2 = defaultSize;
62060
+ if (sizeMark) {
62061
+ const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
62062
+ if (!Number.isNaN(value)) {
62063
+ fontSize2 = `${value}${unit}`;
62064
+ }
60300
62065
  }
60301
- return result;
60302
- };
60303
- const intToJapaneseCounting = (num) => {
60304
- const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
60305
- const units = ["", "十", "百", "千"];
60306
- if (num === 0) return "零";
60307
- if (num < 10) return digits[num];
60308
- let result = "";
60309
- let tempNum = num;
60310
- let unitIndex = 0;
60311
- while (tempNum > 0) {
60312
- const digit = tempNum % 10;
60313
- if (digit !== 0) {
60314
- const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
60315
- result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
60316
- } else if (result && tempNum > 0) {
60317
- if (!result.startsWith("零") && tempNum % 100 !== 0) {
60318
- result = "零" + result;
60319
- }
62066
+ let hasSize = Boolean(sizeMark);
62067
+ if (!hasSize && listRunProperties) {
62068
+ const sizeFromList = parseSizeFromRunProperties(listRunProperties);
62069
+ if (sizeFromList) {
62070
+ fontSize2 = sizeFromList;
62071
+ hasSize = true;
60320
62072
  }
60321
- tempNum = Math.floor(tempNum / 10);
60322
- unitIndex++;
60323
- if (unitIndex > 3) break;
60324
62073
  }
60325
- if (num >= 10 && num < 20) {
60326
- result = result.replace(/^一十/, "十");
62074
+ let fontFamily2 = familyMark?.attrs?.fontFamily ?? defaultFont;
62075
+ let hasFamily = Boolean(familyMark);
62076
+ if (!hasFamily && listRunProperties) {
62077
+ const fontFromList = parseFontFamilyFromRunProperties(listRunProperties);
62078
+ if (fontFromList) {
62079
+ fontFamily2 = fontFromList;
62080
+ hasFamily = true;
62081
+ }
60327
62082
  }
60328
- return result;
60329
- };
62083
+ let lineHeight2 = attrs.lineHeight;
62084
+ const firstChild = node.firstChild;
62085
+ const hasOnlyOnePar = node.childCount === 1 && firstChild?.type?.name === "paragraph";
62086
+ if (hasOnlyOnePar) {
62087
+ const par = firstChild;
62088
+ const parFirstChild = par?.firstChild;
62089
+ if (par?.childCount === 1 && parFirstChild?.type?.name === "fieldAnnotation") {
62090
+ const aFontSize = parFirstChild.attrs?.fontSize;
62091
+ const aFontFamily = parFirstChild.attrs?.fontFamily;
62092
+ if (!sizeMark && aFontSize) fontSize2 = aFontSize;
62093
+ if (!familyMark && aFontFamily) fontFamily2 = aFontFamily;
62094
+ }
62095
+ }
62096
+ return {
62097
+ fontSize: fontSize2,
62098
+ fontFamily: fontFamily2,
62099
+ lineHeight: lineHeight2,
62100
+ hasSize,
62101
+ hasFamily
62102
+ };
62103
+ }
62104
+ function getStylesFromLinkedStyles({ node, pos, editor }) {
62105
+ const { state: state2 } = editor.view;
62106
+ const linkedStyles = LinkedStylesPluginKey.getState(state2)?.decorations;
62107
+ const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
62108
+ const predicates = [
62109
+ (style22) => style22.includes("font-size") && style22.includes("font-family"),
62110
+ (style22) => style22.includes("font-size"),
62111
+ (style22) => style22.includes("font-family")
62112
+ ];
62113
+ let styleDeco;
62114
+ for (const predicateFn of predicates) {
62115
+ styleDeco = decorationsInPlace?.find((dec) => {
62116
+ const style22 = dec.type?.attrs?.style || "";
62117
+ return style22 && predicateFn(style22);
62118
+ });
62119
+ if (styleDeco) break;
62120
+ }
62121
+ const style2 = styleDeco?.type?.attrs?.style;
62122
+ const stylesArray = style2?.split(";") || [];
62123
+ const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1]?.trim();
62124
+ const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1]?.trim();
62125
+ return {
62126
+ font: fontFamilyFromStyles,
62127
+ size: fontSizeFromStyles
62128
+ };
62129
+ }
62130
+ function resolveListItemTypography({ node, pos, editor, nodeView, activeNodeViews }) {
62131
+ const defaults = getStylesFromLinkedStyles({ node, pos, editor });
62132
+ const textStyleType = getMarkType("textStyle", editor.schema);
62133
+ const currentStyles = deriveFontStylesFromNode({
62134
+ node,
62135
+ textStyleType,
62136
+ defaultFont: defaults.font,
62137
+ defaultSize: defaults.size,
62138
+ listRunProperties: node.attrs?.listRunProperties
62139
+ });
62140
+ if ((!currentStyles.hasSize || !currentStyles.hasFamily || !currentStyles.lineHeight) && editor?.view) {
62141
+ const previousListItem = findSiblingListItem({ editor, pos, direction: -1 });
62142
+ if (previousListItem) {
62143
+ const previousStyles = deriveFontStylesFromNode({
62144
+ node: previousListItem,
62145
+ textStyleType,
62146
+ defaultFont: defaults.font,
62147
+ defaultSize: defaults.size,
62148
+ listRunProperties: previousListItem.attrs?.listRunProperties
62149
+ });
62150
+ if (!currentStyles.hasSize && previousStyles.fontSize) currentStyles.fontSize = previousStyles.fontSize;
62151
+ if (!currentStyles.hasFamily && previousStyles.fontFamily) currentStyles.fontFamily = previousStyles.fontFamily;
62152
+ if (!currentStyles.lineHeight && previousStyles.lineHeight) currentStyles.lineHeight = previousStyles.lineHeight;
62153
+ }
62154
+ }
62155
+ if ((!currentStyles.fontSize || !currentStyles.fontFamily || !currentStyles.lineHeight) && nodeView) {
62156
+ const previousView = getAdjacentListItemNodeView({
62157
+ nodeView,
62158
+ pos,
62159
+ direction: -1,
62160
+ activeNodeViews
62161
+ });
62162
+ if (previousView) {
62163
+ const {
62164
+ fontSize: prevSize,
62165
+ fontFamily: prevFamily,
62166
+ lineHeight: prevLineHeight
62167
+ } = readNodeViewStyles(previousView);
62168
+ if (!currentStyles.fontSize && prevSize) currentStyles.fontSize = prevSize;
62169
+ if (!currentStyles.fontFamily && prevFamily) currentStyles.fontFamily = prevFamily;
62170
+ if (!currentStyles.lineHeight && prevLineHeight) currentStyles.lineHeight = prevLineHeight;
62171
+ }
62172
+ }
62173
+ return {
62174
+ fontSize: currentStyles.fontSize,
62175
+ fontFamily: currentStyles.fontFamily,
62176
+ lineHeight: currentStyles.lineHeight
62177
+ };
62178
+ }
60330
62179
  const MARKER_PADDING = 6;
60331
62180
  const MARKER_OFFSET_RIGHT = 4;
60332
62181
  const MIN_MARKER_WIDTH = 20;
@@ -60344,8 +62193,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
60344
62193
  this.decorations = decorations;
60345
62194
  this.view = editor.view;
60346
62195
  this.getPos = getPos;
60347
- activeListItemNodeViews.add(this);
60348
62196
  __privateMethod$1(this, _ListItemNodeView_instances, init_fn2).call(this);
62197
+ activeListItemNodeViews.add(this);
60349
62198
  }
60350
62199
  refreshIndentStyling() {
60351
62200
  const { attrs } = this.node;
@@ -60388,10 +62237,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
60388
62237
  update(node, decorations) {
60389
62238
  this.node = node;
60390
62239
  this.decorations = decorations;
60391
- const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = getTextStyleMarksFromLinkedStyles({
62240
+ const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = resolveListItemTypography({
60392
62241
  node,
60393
62242
  pos: this.getPos(),
60394
- editor: this.editor
62243
+ editor: this.editor,
62244
+ nodeView: this,
62245
+ activeNodeViews: activeListItemNodeViews
60395
62246
  });
60396
62247
  this.dom.style.fontSize = fontSize2;
60397
62248
  this.dom.style.fontFamily = fontFamily2 || "inherit";
@@ -60420,10 +62271,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
60420
62271
  }
60421
62272
  }
60422
62273
  const pos = this.getPos();
60423
- const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = getTextStyleMarksFromLinkedStyles({
62274
+ const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = resolveListItemTypography({
60424
62275
  node: this.node,
60425
62276
  pos,
60426
- editor: this.editor
62277
+ editor: this.editor,
62278
+ nodeView: this,
62279
+ activeNodeViews: activeListItemNodeViews
60427
62280
  });
60428
62281
  this.dom = document.createElement("li");
60429
62282
  this.dom.className = "sd-editor-list-item-node-view";
@@ -60456,79 +62309,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
60456
62309
  }
60457
62310
  });
60458
62311
  }
60459
- function getListItemTextStyleMarks(listItem, markType) {
60460
- let textStyleMarks = [];
60461
- let attrs = {};
60462
- listItem.forEach((childNode) => {
60463
- if (childNode.type.name !== "paragraph") return;
60464
- attrs.lineHeight = childNode.attrs.lineHeight;
60465
- childNode.forEach((textNode) => {
60466
- let isTextNode = textNode.type.name === "text";
60467
- let hasTextStyleMarks = markType.isInSet(textNode.marks);
60468
- if (isTextNode && hasTextStyleMarks) {
60469
- let marks = textNode.marks.filter((mark) => mark.type === markType);
60470
- textStyleMarks.push(...marks);
60471
- }
60472
- });
60473
- });
60474
- return {
60475
- marks: textStyleMarks,
60476
- attrs
60477
- };
60478
- }
60479
- function getTextStyleMarksFromLinkedStyles({ node, pos, editor }) {
60480
- const { font: defaultFont, size: defaultSize } = getStylesFromLinkedStyles({ node, pos, editor });
60481
- const textStyleType = getMarkType("textStyle", editor.schema);
60482
- const { marks: allMarks, attrs: allAttrs } = getListItemTextStyleMarks(node, textStyleType);
60483
- const styleMarks = allMarks.filter((m2) => m2.type === textStyleType);
60484
- const sizeMark = styleMarks.find((m2) => m2.attrs.fontSize);
60485
- const familyMark = styleMarks.find((m2) => m2.attrs.fontFamily);
60486
- const lineHeight2 = allAttrs.lineHeight;
60487
- let fontSize2 = sizeMark ? (() => {
60488
- const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
60489
- return Number.isNaN(value) ? defaultSize : `${value}${unit}`;
60490
- })() : defaultSize;
60491
- let fontFamily2 = familyMark?.attrs.fontFamily ?? defaultFont;
60492
- const firstChild = node.firstChild;
60493
- const hasOnlyOnePar = node.childCount === 1 && firstChild?.type.name === "paragraph";
60494
- if (hasOnlyOnePar) {
60495
- const par = firstChild;
60496
- const parFirstChild = par?.firstChild;
60497
- if (par?.childCount === 1 && parFirstChild?.type.name === "fieldAnnotation") {
60498
- const aFontSize = parFirstChild.attrs.fontSize;
60499
- const aFontFamily = parFirstChild.attrs.fontFamily;
60500
- if (!sizeMark && aFontSize) fontSize2 = aFontSize;
60501
- if (!familyMark && aFontFamily) fontFamily2 = aFontFamily;
60502
- }
60503
- }
60504
- return { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 };
60505
- }
60506
- const getStylesFromLinkedStyles = ({ node, pos, editor }) => {
60507
- const { state: state2 } = editor.view;
60508
- const linkedStyles = LinkedStylesPluginKey.getState(state2)?.decorations;
60509
- const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
60510
- const predicates = [
60511
- (style22) => style22.includes("font-size") && style22.includes("font-family"),
60512
- (style22) => style22.includes("font-size"),
60513
- (style22) => style22.includes("font-family")
60514
- ];
60515
- let styleDeco;
60516
- for (const predicateFn of predicates) {
60517
- styleDeco = decorationsInPlace?.find((dec) => {
60518
- const style22 = dec.type.attrs?.style || "";
60519
- return style22 && predicateFn(style22);
60520
- });
60521
- if (styleDeco) break;
60522
- }
60523
- const style2 = styleDeco?.type.attrs?.style;
60524
- const stylesArray = style2?.split(";") || [];
60525
- const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1].trim();
60526
- const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1].trim();
60527
- return {
60528
- font: fontFamilyFromStyles,
60529
- size: fontSizeFromStyles
60530
- };
60531
- };
60532
62312
  const getVisibleIndent = (stylePpr, numDefPpr, inlineIndent) => {
60533
62313
  const styleIndentTag = stylePpr?.elements?.find((el) => el.name === "w:ind") || {};
60534
62314
  const styleIndent = parseIndentElement(styleIndentTag);
@@ -61262,6 +63042,211 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61262
63042
  return [CommentMarkName, Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
61263
63043
  }
61264
63044
  });
63045
+ const defaultTabDistance = 48;
63046
+ const defaultLineLength = 816;
63047
+ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
63048
+ const decorations = [];
63049
+ const paragraphCache = /* @__PURE__ */ new Map();
63050
+ const end2 = to ?? doc2.content.size;
63051
+ doc2.nodesBetween(from2, end2, (node, pos) => {
63052
+ if (node.type.name !== "tab") return;
63053
+ let extraStyles = "";
63054
+ const $pos = doc2.resolve(pos);
63055
+ const paragraphContext = getParagraphContext($pos, paragraphCache);
63056
+ if (!paragraphContext) return;
63057
+ try {
63058
+ const { tabStops, flattened, startPos } = paragraphContext;
63059
+ const entryIndex = flattened.findIndex((entry) => entry.pos === pos);
63060
+ if (entryIndex === -1) return;
63061
+ const indentWidth = getIndentWidth(view, startPos, paragraphContext.indent);
63062
+ const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
63063
+ const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos) + accumulatedTabWidth;
63064
+ let tabWidth;
63065
+ if (tabStops.length) {
63066
+ const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
63067
+ if (tabStop) {
63068
+ tabWidth = tabStop.pos - currentWidth;
63069
+ if (tabStop.val === "center" || tabStop.val === "end" || tabStop.val === "right") {
63070
+ const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
63071
+ const segmentStartPos = pos + node.nodeSize;
63072
+ const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
63073
+ const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos);
63074
+ tabWidth -= tabStop.val === "center" ? segmentWidth / 2 : segmentWidth;
63075
+ } else if (tabStop.val === "decimal" || tabStop.val === "num") {
63076
+ const breakChar = tabStop.decimalChar || ".";
63077
+ const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
63078
+ const integralWidth = decimalPos ? measureRangeWidth(view, pos + node.nodeSize, decimalPos) : measureRangeWidth(view, pos + node.nodeSize, startPos + paragraphContext.paragraph.nodeSize - 1);
63079
+ tabWidth -= integralWidth;
63080
+ }
63081
+ if (tabStop.leader) {
63082
+ const leaderStyles = {
63083
+ dot: "border-bottom: 1px dotted black;",
63084
+ heavy: "border-bottom: 2px solid black;",
63085
+ hyphen: "border-bottom: 1px solid black;",
63086
+ middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
63087
+ underscore: "border-bottom: 1px solid black;"
63088
+ };
63089
+ extraStyles += leaderStyles[tabStop.leader] || "";
63090
+ }
63091
+ }
63092
+ }
63093
+ if (!tabWidth || tabWidth < 1) {
63094
+ tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
63095
+ if (tabWidth === 0) tabWidth = defaultTabDistance;
63096
+ }
63097
+ const tabHeight = calcTabHeight($pos);
63098
+ decorations.push(
63099
+ Decoration.node(pos, pos + node.nodeSize, {
63100
+ style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
63101
+ })
63102
+ );
63103
+ paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
63104
+ } catch (error) {
63105
+ console.error("tab decoration error", error);
63106
+ }
63107
+ });
63108
+ return decorations;
63109
+ };
63110
+ function getParagraphContext($pos, cache2) {
63111
+ for (let depth = $pos.depth; depth >= 0; depth--) {
63112
+ const node = $pos.node(depth);
63113
+ if (node?.type?.name === "paragraph") {
63114
+ const startPos = $pos.start(depth);
63115
+ if (!cache2.has(startPos)) {
63116
+ cache2.set(startPos, {
63117
+ paragraph: node,
63118
+ paragraphDepth: depth,
63119
+ startPos,
63120
+ indent: node.attrs?.indent || {},
63121
+ tabStops: Array.isArray(node.attrs?.tabStops) ? node.attrs.tabStops : [],
63122
+ flattened: flattenParagraph(node, startPos),
63123
+ accumulatedTabWidth: 0
63124
+ });
63125
+ }
63126
+ return cache2.get(startPos);
63127
+ }
63128
+ }
63129
+ return null;
63130
+ }
63131
+ function flattenParagraph(paragraph, paragraphStartPos) {
63132
+ const entries = [];
63133
+ const walk = (node, basePos) => {
63134
+ if (!node) return;
63135
+ if (node.type?.name === "run") {
63136
+ node.forEach((child, offset2) => {
63137
+ const childPos = basePos + offset2 + 1;
63138
+ walk(child, childPos);
63139
+ });
63140
+ return;
63141
+ }
63142
+ entries.push({ node, pos: basePos - 1 });
63143
+ };
63144
+ paragraph.forEach((child, offset2) => {
63145
+ const childPos = paragraphStartPos + offset2 + 1;
63146
+ walk(child, childPos);
63147
+ });
63148
+ return entries;
63149
+ }
63150
+ function findNextTabIndex(flattened, fromIndex) {
63151
+ for (let i2 = fromIndex; i2 < flattened.length; i2++) {
63152
+ if (flattened[i2]?.node?.type?.name === "tab") {
63153
+ return i2;
63154
+ }
63155
+ }
63156
+ return -1;
63157
+ }
63158
+ function findDecimalBreakPos(flattened, startIndex, breakChar) {
63159
+ for (let i2 = startIndex; i2 < flattened.length; i2++) {
63160
+ const entry = flattened[i2];
63161
+ if (!entry) break;
63162
+ if (entry.node.type?.name === "tab") break;
63163
+ if (entry.node.type?.name === "text") {
63164
+ const index2 = entry.node.text?.indexOf(breakChar);
63165
+ if (index2 !== void 0 && index2 !== -1) {
63166
+ return entry.pos + index2 + 1;
63167
+ }
63168
+ }
63169
+ }
63170
+ return null;
63171
+ }
63172
+ function measureRangeWidth(view, from2, to) {
63173
+ if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
63174
+ try {
63175
+ const range2 = document.createRange();
63176
+ const fromRef = view.domAtPos(from2);
63177
+ const toRef2 = view.domAtPos(to);
63178
+ range2.setStart(fromRef.node, fromRef.offset);
63179
+ range2.setEnd(toRef2.node, toRef2.offset);
63180
+ const rect = range2.getBoundingClientRect();
63181
+ range2.detach?.();
63182
+ return rect.width || 0;
63183
+ } catch {
63184
+ const startLeft = getLeftCoord(view, from2);
63185
+ const endLeft = getLeftCoord(view, to);
63186
+ if (startLeft == null || endLeft == null) return 0;
63187
+ return Math.max(0, endLeft - startLeft);
63188
+ }
63189
+ }
63190
+ function getIndentWidth(view, paragraphStartPos, indentAttrs = {}) {
63191
+ const marginLeft = getLeftCoord(view, paragraphStartPos);
63192
+ const lineLeft = getLeftCoord(view, paragraphStartPos + 1);
63193
+ if (marginLeft != null && lineLeft != null) {
63194
+ const diff = lineLeft - marginLeft;
63195
+ if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
63196
+ return diff;
63197
+ }
63198
+ }
63199
+ return calculateIndentFallback(indentAttrs);
63200
+ }
63201
+ function calculateIndentFallback(indentAttrs = {}) {
63202
+ if (!indentAttrs) return 0;
63203
+ const left2 = Number(indentAttrs.left) || 0;
63204
+ const firstLine = Number(indentAttrs.firstLine) || 0;
63205
+ const hanging = Number(indentAttrs.hanging) || 0;
63206
+ let textIndent = 0;
63207
+ if (firstLine && hanging) {
63208
+ textIndent = firstLine - hanging;
63209
+ } else if (firstLine) {
63210
+ textIndent = firstLine;
63211
+ } else if (hanging) {
63212
+ textIndent = -hanging;
63213
+ } else if (typeof indentAttrs.textIndent === "string") {
63214
+ const match = indentAttrs.textIndent.match(/(-?\d*\.?\d+)in$/);
63215
+ if (match) {
63216
+ textIndent = Number(match[1]) * 96;
63217
+ }
63218
+ }
63219
+ if (textIndent) return left2 + textIndent;
63220
+ if (left2) return left2;
63221
+ return 0;
63222
+ }
63223
+ function getLeftCoord(view, pos) {
63224
+ if (!Number.isFinite(pos)) return null;
63225
+ try {
63226
+ return view.coordsAtPos(pos).left;
63227
+ } catch {
63228
+ try {
63229
+ const ref2 = view.domAtPos(pos);
63230
+ const range2 = document.createRange();
63231
+ range2.setStart(ref2.node, ref2.offset);
63232
+ range2.setEnd(ref2.node, ref2.offset);
63233
+ const rect = range2.getBoundingClientRect();
63234
+ range2.detach?.();
63235
+ return rect.left;
63236
+ } catch {
63237
+ return null;
63238
+ }
63239
+ }
63240
+ }
63241
+ function calcTabHeight(pos) {
63242
+ const ptToPxRatio = 1.333;
63243
+ const defaultFontSize = 16;
63244
+ const defaultLineHeight = 1.1;
63245
+ const blockParent2 = pos.node(1);
63246
+ const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
63247
+ const fontSize2 = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
63248
+ return `${fontSize2 * defaultLineHeight}px`;
63249
+ }
61265
63250
  const TabNode = Node$1.create({
61266
63251
  name: "tab",
61267
63252
  group: "inline",
@@ -61299,8 +63284,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61299
63284
  };
61300
63285
  },
61301
63286
  addPmPlugins() {
61302
- const { view, schema } = this.editor;
61303
- const domSerializer = DOMSerializer.fromSchema(schema);
63287
+ const { view } = this.editor;
61304
63288
  const tabPlugin = new Plugin({
61305
63289
  name: "tabPlugin",
61306
63290
  key: new PluginKey("tabPlugin"),
@@ -61310,10 +63294,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61310
63294
  },
61311
63295
  apply(tr, { decorations }, _oldState, newState) {
61312
63296
  if (!decorations) {
61313
- decorations = DecorationSet.create(
61314
- newState.doc,
61315
- getTabDecorations(newState.doc, StepMap.empty, view, domSerializer)
61316
- );
63297
+ decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view));
61317
63298
  }
61318
63299
  if (!tr.docChanged) {
61319
63300
  return { decorations };
@@ -61353,8 +63334,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61353
63334
  rangesToRecalculate.forEach(([start2, end2]) => {
61354
63335
  const oldDecorations = decorations.find(start2, end2);
61355
63336
  decorations = decorations.remove(oldDecorations);
61356
- const invertMapping = tr.mapping.invert();
61357
- const newDecorations = getTabDecorations(newState.doc, invertMapping, view, domSerializer, start2, end2);
63337
+ const newDecorations = getTabDecorations(newState.doc, view, start2, end2);
61358
63338
  decorations = decorations.add(newState.doc, newDecorations);
61359
63339
  });
61360
63340
  return { decorations };
@@ -61369,156 +63349,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
61369
63349
  return [tabPlugin];
61370
63350
  }
61371
63351
  });
61372
- const defaultTabDistance = 48;
61373
- const defaultLineLength = 816;
61374
- const getTabDecorations = (doc2, invertMapping, view, domSerializer, from2 = 0, to = null) => {
61375
- if (!to) {
61376
- to = doc2.content.size;
61377
- }
61378
- const nodeWidthCache = {};
61379
- let decorations = [];
61380
- doc2.nodesBetween(from2, to, (node, pos, parent) => {
61381
- if (node.type.name === "tab") {
61382
- let extraStyles = "";
61383
- const $pos = doc2.resolve(pos);
61384
- const tabIndex = $pos.index($pos.depth);
61385
- const fistlineIndent = parent.attrs?.indent?.firstLine || 0;
61386
- const currentWidth = calcChildNodesWidth(
61387
- parent,
61388
- pos - $pos.parentOffset,
61389
- 0,
61390
- tabIndex,
61391
- domSerializer,
61392
- view,
61393
- invertMapping,
61394
- nodeWidthCache
61395
- ) + fistlineIndent;
61396
- let tabWidth;
61397
- if ($pos.depth === 1 && parent.attrs.tabStops && parent.attrs.tabStops.length > 0) {
61398
- const tabStop = parent.attrs.tabStops.find((tabStop2) => tabStop2.pos > currentWidth && tabStop2.val !== "clear");
61399
- if (tabStop) {
61400
- tabWidth = tabStop.pos - currentWidth;
61401
- if (["end", "center"].includes(tabStop.val)) {
61402
- let nextTabIndex = tabIndex + 1;
61403
- while (nextTabIndex < parent.childCount && parent.child(nextTabIndex).type.name !== "tab") {
61404
- nextTabIndex++;
61405
- }
61406
- const tabSectionWidth = calcChildNodesWidth(
61407
- parent,
61408
- pos - $pos.parentOffset,
61409
- tabIndex,
61410
- nextTabIndex,
61411
- domSerializer,
61412
- view,
61413
- invertMapping,
61414
- nodeWidthCache
61415
- );
61416
- tabWidth -= tabStop.val === "end" ? tabSectionWidth : tabSectionWidth / 2;
61417
- } else if (["decimal", "num"].includes(tabStop.val)) {
61418
- const breakChar = ".";
61419
- let nodeIndex = tabIndex + 1;
61420
- let integralWidth = 0;
61421
- let nodePos = pos - $pos.parentOffset;
61422
- while (nodeIndex < parent.childCount) {
61423
- const node2 = parent.child(nodeIndex);
61424
- if (node2.type.name === "tab") {
61425
- break;
61426
- }
61427
- const oldPos = invertMapping.map(nodePos);
61428
- if (node2.type.name === "text" && node2.text.includes(breakChar)) {
61429
- const modifiedNode = node2.cut(0, node2.text.indexOf(breakChar));
61430
- integralWidth += calcNodeWidth(domSerializer, modifiedNode, view, oldPos);
61431
- break;
61432
- }
61433
- integralWidth += calcNodeWidth(domSerializer, node2, view, oldPos);
61434
- nodeWidthCache[nodePos] = integralWidth;
61435
- nodePos += node2.nodeSize;
61436
- nodeIndex += 1;
61437
- }
61438
- tabWidth -= integralWidth;
61439
- }
61440
- if (tabStop.leader) {
61441
- if (tabStop.leader === "dot") {
61442
- extraStyles += `border-bottom: 1px dotted black;`;
61443
- } else if (tabStop.leader === "heavy") {
61444
- extraStyles += `border-bottom: 2px solid black;`;
61445
- } else if (tabStop.leader === "hyphen") {
61446
- extraStyles += `border-bottom: 1px solid black;`;
61447
- } else if (tabStop.leader === "middleDot") {
61448
- extraStyles += `border-bottom: 1px dotted black; margin-bottom: 2px;`;
61449
- } else if (tabStop.leader === "underscore") {
61450
- extraStyles += `border-bottom: 1px solid black;`;
61451
- }
61452
- }
61453
- }
61454
- }
61455
- if (!tabWidth || tabWidth < 1) {
61456
- tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
61457
- if (tabWidth === 0) {
61458
- tabWidth = defaultTabDistance;
61459
- }
61460
- }
61461
- nodeWidthCache[pos] = tabWidth;
61462
- const tabHeight = calcTabHeight($pos);
61463
- decorations.push(
61464
- Decoration.node(pos, pos + node.nodeSize, {
61465
- style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
61466
- })
61467
- );
61468
- }
61469
- });
61470
- return decorations;
61471
- };
61472
- function calcNodeWidth(domSerializer, node, view, oldPos) {
61473
- const oldDomNode = view.nodeDOM(oldPos);
61474
- const styleReference = oldDomNode ? oldDomNode.nodeName === "#text" ? oldDomNode.parentNode : oldDomNode : view.dom;
61475
- const temp = document.createElement("div");
61476
- const style2 = window.getComputedStyle(styleReference);
61477
- temp.style.cssText = `
61478
- position: absolute;
61479
- top: -9999px;
61480
- left: -9999px;
61481
- white-space: nowrap;
61482
- font-family: ${style2.fontFamily};
61483
- font-size: ${style2.fontSize};
61484
- font-weight: ${style2.fontWeight};
61485
- font-style: ${style2.fontStyle};
61486
- letter-spacing: ${style2.letterSpacing};
61487
- word-spacing: ${style2.wordSpacing};
61488
- text-transform: ${style2.textTransform};
61489
- display: inline-block;
61490
- `;
61491
- const domNode = domSerializer.serializeNode(node);
61492
- temp.appendChild(domNode);
61493
- document.body.appendChild(temp);
61494
- const width = temp.offsetWidth;
61495
- document.body.removeChild(temp);
61496
- return width;
61497
- }
61498
- function calcChildNodesWidth(parent, parentPos, startIndex, endIndex, domSerializer, view, invertMapping, nodeWidthCache) {
61499
- let pos = parentPos;
61500
- let width = 0;
61501
- for (let i2 = 0; i2 < endIndex; i2++) {
61502
- const node = parent.child(i2);
61503
- if (i2 >= startIndex) {
61504
- if (!nodeWidthCache[pos]) {
61505
- nodeWidthCache[pos] = calcNodeWidth(domSerializer, node, view, invertMapping.map(pos));
61506
- }
61507
- width += nodeWidthCache[pos];
61508
- }
61509
- pos += node.nodeSize;
61510
- }
61511
- return width;
61512
- }
61513
- function calcTabHeight(pos) {
61514
- const ptToPxRatio = 1.333;
61515
- const defaultFontSize = 16;
61516
- const defaultLineHeight = 1.1;
61517
- const blockParent2 = pos.node(1);
61518
- const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
61519
- const fontSize2 = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
61520
- return `${fontSize2 * defaultLineHeight}px`;
61521
- }
61522
63352
  const LineBreak = Node$1.create({
61523
63353
  name: "lineBreak",
61524
63354
  group: "inline",
@@ -67185,10 +69015,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
67185
69015
  },
67186
69016
  padding: {
67187
69017
  default: {},
67188
- renderDOM: ({ size: size2 = {}, padding, marginOffset, transformData }) => {
69018
+ renderDOM: ({ size: size2 = {}, padding, marginOffset, transformData = {} }) => {
67189
69019
  let { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
67190
- const { rotation } = transformData ?? {};
67191
- const { height, width } = size2 ?? {};
69020
+ const { rotation } = transformData;
69021
+ const { height, width } = size2;
67192
69022
  if (rotation && height && width) {
67193
69023
  const { horizontal, vertical } = getRotationMargins(width, height, rotation);
67194
69024
  left2 += horizontal;
@@ -68979,6 +70809,30 @@ Please report this to https://github.com/markedjs/marked.`, e) {
68979
70809
  };
68980
70810
  }
68981
70811
  });
70812
+ function createCascadeToggleCommands({
70813
+ markName,
70814
+ setCommand,
70815
+ unsetCommand,
70816
+ toggleCommand,
70817
+ negationAttrs,
70818
+ isNegation,
70819
+ extendEmptyMarkRange
70820
+ } = {}) {
70821
+ if (!markName) throw new Error("createCascadeToggleCommands requires a markName");
70822
+ const capitalized = markName.charAt(0).toUpperCase() + markName.slice(1);
70823
+ const setName = setCommand ?? `set${capitalized}`;
70824
+ const unsetName = unsetCommand ?? `unset${capitalized}`;
70825
+ const toggleName = toggleCommand ?? `toggle${capitalized}`;
70826
+ const cascadeOptions = {};
70827
+ if (negationAttrs) cascadeOptions.negationAttrs = negationAttrs;
70828
+ if (typeof isNegation === "function") cascadeOptions.isNegation = isNegation;
70829
+ if (extendEmptyMarkRange !== void 0) cascadeOptions.extendEmptyMarkRange = extendEmptyMarkRange;
70830
+ return {
70831
+ [setName]: () => ({ commands: commands2 }) => commands2.setMark(markName),
70832
+ [unsetName]: () => ({ commands: commands2 }) => commands2.unsetMark(markName),
70833
+ [toggleName]: () => ({ commands: commands2 }) => commands2.toggleMarkCascade(markName, cascadeOptions)
70834
+ };
70835
+ }
68982
70836
  const Bold = Mark.create({
68983
70837
  name: "bold",
68984
70838
  addOptions() {
@@ -69009,9 +70863,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69009
70863
  ];
69010
70864
  },
69011
70865
  renderDOM({ htmlAttributes }) {
69012
- return ["strong", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
70866
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
70867
+ const { value, ...rest } = merged || {};
70868
+ if (value === "0") {
70869
+ return ["span", rest, 0];
70870
+ }
70871
+ return ["strong", rest, 0];
69013
70872
  },
69014
70873
  addCommands() {
70874
+ const { setBold, unsetBold, toggleBold } = createCascadeToggleCommands({
70875
+ markName: this.name,
70876
+ negationAttrs: { value: "0" }
70877
+ });
69015
70878
  return {
69016
70879
  /**
69017
70880
  * Apply bold formatting
@@ -69020,21 +70883,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69020
70883
  * editor.commands.setBold()
69021
70884
  * @note '0' renders as normal weight
69022
70885
  */
69023
- setBold: () => ({ commands: commands2 }) => commands2.setMark(this.name),
70886
+ setBold,
69024
70887
  /**
69025
70888
  * Remove bold formatting
69026
70889
  * @category Command
69027
70890
  * @example
69028
70891
  * editor.commands.unsetBold()
69029
70892
  */
69030
- unsetBold: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
70893
+ unsetBold,
69031
70894
  /**
69032
70895
  * Toggle bold formatting
69033
70896
  * @category Command
69034
70897
  * @example
69035
70898
  * editor.commands.toggleBold()
69036
70899
  */
69037
- toggleBold: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
70900
+ toggleBold
69038
70901
  };
69039
70902
  },
69040
70903
  addShortcuts() {
@@ -69051,6 +70914,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69051
70914
  htmlAttributes: {}
69052
70915
  };
69053
70916
  },
70917
+ addAttributes() {
70918
+ return {
70919
+ /**
70920
+ * @category Attribute
70921
+ * @param {string} [value] - Italic toggle value ('0' renders as normal)
70922
+ */
70923
+ value: {
70924
+ default: null,
70925
+ renderDOM: (attrs) => {
70926
+ if (!attrs.value) return {};
70927
+ if (attrs.value === "0") return { style: "font-style: normal" };
70928
+ return {};
70929
+ }
70930
+ }
70931
+ };
70932
+ },
69054
70933
  parseDOM() {
69055
70934
  return [
69056
70935
  { tag: "i" },
@@ -69060,9 +70939,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69060
70939
  ];
69061
70940
  },
69062
70941
  renderDOM({ htmlAttributes }) {
69063
- return ["em", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
70942
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
70943
+ const { value, ...rest } = merged || {};
70944
+ if (value === "0") {
70945
+ return ["span", rest, 0];
70946
+ }
70947
+ return ["em", rest, 0];
69064
70948
  },
69065
70949
  addCommands() {
70950
+ const { setItalic, unsetItalic, toggleItalic } = createCascadeToggleCommands({
70951
+ markName: this.name,
70952
+ negationAttrs: { value: "0" }
70953
+ });
69066
70954
  return {
69067
70955
  /**
69068
70956
  * Apply italic formatting
@@ -69070,21 +70958,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69070
70958
  * @example
69071
70959
  * editor.commands.setItalic()
69072
70960
  */
69073
- setItalic: () => ({ commands: commands2 }) => commands2.setMark(this.name),
70961
+ setItalic,
69074
70962
  /**
69075
70963
  * Remove italic formatting
69076
70964
  * @category Command
69077
70965
  * @example
69078
70966
  * editor.commands.unsetItalic()
69079
70967
  */
69080
- unsetItalic: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
70968
+ unsetItalic,
69081
70969
  /**
69082
70970
  * Toggle italic formatting
69083
70971
  * @category Command
69084
70972
  * @example
69085
70973
  * editor.commands.toggleItalic()
69086
70974
  */
69087
- toggleItalic: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
70975
+ toggleItalic
69088
70976
  };
69089
70977
  },
69090
70978
  addShortcuts() {
@@ -69109,7 +70997,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69109
70997
  ];
69110
70998
  },
69111
70999
  renderDOM({ htmlAttributes }) {
69112
- return ["u", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
71000
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
71001
+ const type2 = merged?.underlineType;
71002
+ const color = merged?.underlineColor;
71003
+ const css = getUnderlineCssString({ type: type2, color });
71004
+ const { style: style2, ...rest } = merged || {};
71005
+ const styleString = [style2, css].filter(Boolean).join("; ");
71006
+ if (type2 === "none") {
71007
+ return ["span", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
71008
+ }
71009
+ return ["u", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
69113
71010
  },
69114
71011
  addAttributes() {
69115
71012
  return {
@@ -69119,10 +71016,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69119
71016
  */
69120
71017
  underlineType: {
69121
71018
  default: "single"
71019
+ },
71020
+ underlineColor: {
71021
+ default: null
69122
71022
  }
69123
71023
  };
69124
71024
  },
69125
71025
  addCommands() {
71026
+ const { setUnderline, unsetUnderline, toggleUnderline } = createCascadeToggleCommands({
71027
+ markName: this.name,
71028
+ negationAttrs: { underlineType: "none" },
71029
+ isNegation: (attrs) => attrs?.underlineType === "none"
71030
+ });
69126
71031
  return {
69127
71032
  /**
69128
71033
  * Apply underline formatting
@@ -69131,7 +71036,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69131
71036
  * @example
69132
71037
  * setUnderline()
69133
71038
  */
69134
- setUnderline: () => ({ commands: commands2 }) => commands2.setMark(this.name),
71039
+ setUnderline,
69135
71040
  /**
69136
71041
  * Remove underline formatting
69137
71042
  * @category Command
@@ -69139,7 +71044,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69139
71044
  * @example
69140
71045
  * unsetUnderline()
69141
71046
  */
69142
- unsetUnderline: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
71047
+ unsetUnderline,
69143
71048
  /**
69144
71049
  * Toggle underline formatting
69145
71050
  * @category Command
@@ -69147,7 +71052,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69147
71052
  * @example
69148
71053
  * toggleUnderline()
69149
71054
  */
69150
- toggleUnderline: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
71055
+ toggleUnderline
69151
71056
  };
69152
71057
  },
69153
71058
  addShortcuts() {
@@ -69235,9 +71140,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69235
71140
  ];
69236
71141
  },
69237
71142
  renderDOM({ htmlAttributes }) {
69238
- return ["s", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
71143
+ const merged = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
71144
+ const { value, ...rest } = merged || {};
71145
+ if (value === "0") {
71146
+ return ["span", rest, 0];
71147
+ }
71148
+ return ["s", rest, 0];
69239
71149
  },
69240
71150
  addCommands() {
71151
+ const { setStrike, unsetStrike, toggleStrike } = createCascadeToggleCommands({
71152
+ markName: this.name,
71153
+ negationAttrs: { value: "0" }
71154
+ });
69241
71155
  return {
69242
71156
  /**
69243
71157
  * Apply strikethrough formatting
@@ -69245,26 +71159,38 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69245
71159
  * @example
69246
71160
  * editor.commands.setStrike()
69247
71161
  */
69248
- setStrike: () => ({ commands: commands2 }) => {
69249
- return commands2.setMark(this.name);
69250
- },
71162
+ setStrike,
69251
71163
  /**
69252
71164
  * Remove strikethrough formatting
69253
71165
  * @category Command
69254
71166
  * @example
69255
71167
  * editor.commands.unsetStrike()
69256
71168
  */
69257
- unsetStrike: () => ({ commands: commands2 }) => {
69258
- return commands2.unsetMark(this.name);
69259
- },
71169
+ unsetStrike,
69260
71170
  /**
69261
71171
  * Toggle strikethrough formatting
69262
71172
  * @category Command
69263
71173
  * @example
69264
71174
  * editor.commands.toggleStrike()
69265
71175
  */
69266
- toggleStrike: () => ({ commands: commands2 }) => {
69267
- return commands2.toggleMark(this.name);
71176
+ toggleStrike
71177
+ };
71178
+ },
71179
+ addAttributes() {
71180
+ return {
71181
+ /**
71182
+ * @category Attribute
71183
+ * @param {string} [value] - Strike toggle value ('0' renders as normal)
71184
+ */
71185
+ value: {
71186
+ default: null,
71187
+ renderDOM: (attrs) => {
71188
+ if (!attrs.value) return {};
71189
+ if (attrs.value === "0") {
71190
+ return { style: "text-decoration: none" };
71191
+ }
71192
+ return {};
71193
+ }
69268
71194
  }
69269
71195
  };
69270
71196
  },
@@ -75405,7 +77331,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75405
77331
  Paragraph,
75406
77332
  LineBreak,
75407
77333
  HardBreak,
75408
- RunItem,
77334
+ Run,
75409
77335
  SlashMenu,
75410
77336
  Strike,
75411
77337
  TabNode,
@@ -88633,6 +90559,38 @@ ${style2}
88633
90559
  documentViewingModeDescription: "View clean version of document only",
88634
90560
  linkedStyles: "Linked styles"
88635
90561
  };
90562
+ const isOffValue = (value) => {
90563
+ if (value == null) return false;
90564
+ const normalized = String(value).toLowerCase();
90565
+ return normalized === "0" || normalized === "false" || normalized === "off";
90566
+ };
90567
+ const negationChecks = {
90568
+ bold: (attrs = {}) => isOffValue(attrs.value),
90569
+ italic: (attrs = {}) => isOffValue(attrs.value),
90570
+ strike: (attrs = {}) => isOffValue(attrs.value),
90571
+ underline: (attrs = {}) => {
90572
+ const type2 = attrs.underlineType ?? attrs.value;
90573
+ if (type2 == null) return false;
90574
+ const normalized = String(type2).toLowerCase();
90575
+ return normalized === "none" || isOffValue(normalized);
90576
+ },
90577
+ color: (attrs = {}) => {
90578
+ const value = attrs.color;
90579
+ if (value == null) return true;
90580
+ return String(value).toLowerCase() === "inherit";
90581
+ },
90582
+ highlight: (attrs = {}) => {
90583
+ const value = attrs.color;
90584
+ if (value == null) return true;
90585
+ const normalized = String(value).toLowerCase();
90586
+ return normalized === "transparent" || normalized === "none";
90587
+ }
90588
+ };
90589
+ const isNegatedMark = (name, attrs = {}) => {
90590
+ const checker = negationChecks[name];
90591
+ if (typeof checker !== "function") return false;
90592
+ return Boolean(checker(attrs));
90593
+ };
88636
90594
  class SuperToolbar extends EventEmitter$1 {
88637
90595
  /**
88638
90596
  * Creates a new SuperToolbar instance
@@ -88726,10 +90684,14 @@ ${style2}
88726
90684
  * @param {string} params.argument - The color to set
88727
90685
  * @returns {void}
88728
90686
  */
88729
- setColor: ({ item, argument }) => {
88730
- __privateMethod(this, _SuperToolbar_instances, runCommandWithArgumentOnly_fn).call(this, { item, argument }, () => {
88731
- this.activeEditor?.commands.setFieldAnnotationsTextColor(argument, true);
88732
- });
90687
+ setColor: ({ argument }) => {
90688
+ if (!argument || !this.activeEditor) return;
90689
+ const isNone = argument === "none";
90690
+ const value = isNone ? "inherit" : argument;
90691
+ if (this.activeEditor?.commands?.setColor) this.activeEditor.commands.setColor(value);
90692
+ const argValue = isNone ? null : argument;
90693
+ this.activeEditor?.commands.setFieldAnnotationsTextColor(argValue, true);
90694
+ this.updateToolbarState();
88733
90695
  },
88734
90696
  /**
88735
90697
  * Sets the highlight color for text
@@ -88738,12 +90700,14 @@ ${style2}
88738
90700
  * @param {string} params.argument - The highlight color to set
88739
90701
  * @returns {void}
88740
90702
  */
88741
- setHighlight: ({ item, argument }) => {
88742
- __privateMethod(this, _SuperToolbar_instances, runCommandWithArgumentOnly_fn).call(this, { item, argument, noArgumentCallback: true }, () => {
88743
- let arg = argument !== "none" ? argument : null;
88744
- this.activeEditor?.commands.setFieldAnnotationsTextHighlight(arg, true);
88745
- this.activeEditor?.commands.setCellBackground(arg);
88746
- });
90703
+ setHighlight: ({ argument }) => {
90704
+ if (!argument || !this.activeEditor) return;
90705
+ const inlineColor = argument !== "none" ? argument : "transparent";
90706
+ if (this.activeEditor?.commands?.setHighlight) this.activeEditor.commands.setHighlight(inlineColor);
90707
+ const argValue = argument !== "none" ? argument : null;
90708
+ this.activeEditor?.commands.setFieldAnnotationsTextHighlight(argValue, true);
90709
+ this.activeEditor?.commands.setCellBackground(argValue);
90710
+ this.updateToolbarState();
88747
90711
  },
88748
90712
  /**
88749
90713
  * Toggles the ruler visibility
@@ -89060,14 +91024,16 @@ ${style2}
89060
91024
  return item.activate();
89061
91025
  }
89062
91026
  }
89063
- const activeMark = marks.find((mark) => mark.name === item.name.value);
91027
+ const rawActiveMark = marks.find((mark) => mark.name === item.name.value);
91028
+ const markNegated = rawActiveMark ? isNegatedMark(rawActiveMark.name, rawActiveMark.attrs) : false;
91029
+ const activeMark = markNegated ? null : rawActiveMark;
89064
91030
  if (activeMark) {
89065
91031
  item.activate(activeMark.attrs);
89066
91032
  } else {
89067
91033
  item.deactivate();
89068
91034
  }
89069
91035
  const styleIdMark = marks.find((mark) => mark.name === "styleId");
89070
- if (!activeMark && styleIdMark?.attrs.styleId) {
91036
+ if (!activeMark && !markNegated && styleIdMark?.attrs.styleId) {
89071
91037
  const markToStyleMap = {
89072
91038
  fontSize: "font-size",
89073
91039
  fontFamily: "font-family",
@@ -89125,7 +91091,6 @@ ${style2}
89125
91091
  if (!command2) {
89126
91092
  return;
89127
91093
  }
89128
- this.log("(emmitCommand) Command:", command2, "\n item:", item, "\n argument:", argument, "\n option:", option);
89129
91094
  if (command2 in __privateGet(this, _interceptedCommands)) {
89130
91095
  return __privateGet(this, _interceptedCommands)[command2]({ item, argument });
89131
91096
  }
@@ -90688,6 +92653,36 @@ ${style2}
90688
92653
  }
90689
92654
  };
90690
92655
  const SuperInput = /* @__PURE__ */ _export_sfc$1(_sfc_main$i, [["__scopeId", "data-v-4d5cff52"]]);
92656
+ const baseHandlers = {
92657
+ ...runPropertyTranslators,
92658
+ "w:br": translator$15,
92659
+ "w:cantSplit": translator$S,
92660
+ "w:cnfStyle": translator$R,
92661
+ "w:divId": translator$Q,
92662
+ "w:gridAfter": translator$P,
92663
+ "w:gridBefore": translator$O,
92664
+ "w:hidden": translator$N,
92665
+ "w:hyperlink": translator$6,
92666
+ "w:jc": translator$M,
92667
+ "w:p": translator$12,
92668
+ "w:r": translator$T,
92669
+ "w:rPr": translator$U,
92670
+ "w:sdt": translator$2,
92671
+ "w:tab": translator$13,
92672
+ "w:tblCellSpacing": translator$L,
92673
+ "w:tblHeader": translator$K,
92674
+ "w:tc": translator$7,
92675
+ "w:tr": translator$F,
92676
+ "w:trHeight": translator$J,
92677
+ "w:trPr": translator$G,
92678
+ "w:wAfter": translator$I,
92679
+ "w:wBefore": translator$H,
92680
+ "wp:anchor": translator$5,
92681
+ "wp:inline": translator$4,
92682
+ "w:bookmarkStart": translator$1,
92683
+ "w:bookmarkEnd": translator
92684
+ };
92685
+ const registeredHandlers = Object.freeze(baseHandlers);
90691
92686
  const Extensions = {
90692
92687
  Node: Node$1,
90693
92688
  Attribute,
@@ -94076,7 +96071,6 @@ ${reason}`);
94076
96071
  }
94077
96072
  debounceTimers[commentId] = setTimeout(() => {
94078
96073
  if (superdoc2) {
94079
- if (__IS_DEBUG__) console.debug("[debounceEmit] tracked change update emitting...", event);
94080
96074
  superdoc2.emit("comments-update", event);
94081
96075
  }
94082
96076
  delete debounceTimers[commentId];
@@ -94084,7 +96078,6 @@ ${reason}`);
94084
96078
  };
94085
96079
  const showAddComment = (superdoc2) => {
94086
96080
  const event = { type: COMMENT_EVENTS.PENDING };
94087
- if (__IS_DEBUG__) console.debug("[showAddComment] emitting...", event);
94088
96081
  superdoc2.emit("comments-update", event);
94089
96082
  const selection = { ...superdocStore.activeSelection };
94090
96083
  selection.selectionBounds = { ...selection.selectionBounds };
@@ -94185,7 +96178,6 @@ ${reason}`);
94185
96178
  }
94186
96179
  const event = { type: COMMENT_EVENTS.ADD, comment: newComment.getValues() };
94187
96180
  syncCommentsToClients(superdoc2, event);
94188
- if (__IS_DEBUG__) console.debug("[addComment] emitting...", event);
94189
96181
  superdoc2.emit("comments-update", event);
94190
96182
  };
94191
96183
  const deleteComment = ({ commentId: commentIdToDelete, superdoc: superdoc2 }) => {
@@ -94202,7 +96194,6 @@ ${reason}`);
94202
96194
  comment: comment.getValues(),
94203
96195
  changes: [{ key: "deleted", commentId, fileId }]
94204
96196
  };
94205
- if (__IS_DEBUG__) console.debug("[deleteComment] emitting...", event);
94206
96197
  superdoc2.emit("comments-update", event);
94207
96198
  syncCommentsToClients(superdoc2, event);
94208
96199
  };
@@ -94211,7 +96202,6 @@ ${reason}`);
94211
96202
  };
94212
96203
  const processLoadedDocxComments = async ({ superdoc: superdoc2, editor, comments, documentId }) => {
94213
96204
  const document2 = superdocStore.getDocument(documentId);
94214
- if (__IS_DEBUG__) console.debug("[processLoadedDocxComments] processing comments...", comments);
94215
96205
  comments.forEach((comment) => {
94216
96206
  const htmlContent = getHTmlFromComment(comment.textJson);
94217
96207
  if (!htmlContent && !comment.trackedChange) {
@@ -94313,13 +96303,41 @@ ${reason}`);
94313
96303
  });
94314
96304
  return comments;
94315
96305
  });
96306
+ const normalizeCommentForEditor = (node) => {
96307
+ if (!node || typeof node !== "object") return node;
96308
+ const cloneMarks = (marks) => Array.isArray(marks) ? marks.filter(Boolean).map((mark) => ({
96309
+ ...mark,
96310
+ attrs: mark?.attrs ? { ...mark.attrs } : void 0
96311
+ })) : void 0;
96312
+ const cloneAttrs = (attrs) => attrs && typeof attrs === "object" ? { ...attrs } : void 0;
96313
+ if (!Array.isArray(node.content)) {
96314
+ return {
96315
+ type: node.type,
96316
+ ...node.text !== void 0 ? { text: node.text } : {},
96317
+ ...node.attrs ? { attrs: cloneAttrs(node.attrs) } : {},
96318
+ ...node.marks ? { marks: cloneMarks(node.marks) } : {}
96319
+ };
96320
+ }
96321
+ const normalizedChildren = node.content.map((child) => normalizeCommentForEditor(child)).flat().filter(Boolean);
96322
+ if (node.type === "run") {
96323
+ return normalizedChildren;
96324
+ }
96325
+ return {
96326
+ type: node.type,
96327
+ ...node.attrs ? { attrs: cloneAttrs(node.attrs) } : {},
96328
+ ...node.marks ? { marks: cloneMarks(node.marks) } : {},
96329
+ content: normalizedChildren
96330
+ };
96331
+ };
94316
96332
  const getHTmlFromComment = (commentTextJson) => {
94317
96333
  if (!commentTextJson.content?.length) return;
94318
96334
  try {
96335
+ const normalizedContent = normalizeCommentForEditor(commentTextJson);
96336
+ const schemaContent = Array.isArray(normalizedContent) ? normalizedContent[0] : normalizedContent;
94319
96337
  const editor = new Editor({
94320
96338
  mode: "text",
94321
96339
  isHeadless: true,
94322
- content: commentTextJson,
96340
+ content: schemaContent,
94323
96341
  loadFromSchema: true,
94324
96342
  extensions: getRichTextExtensions()
94325
96343
  });