@superdoc-dev/mcp 0.3.0-next.60 → 0.3.0-next.61

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 (2) hide show
  1. package/dist/index.js +509 -61
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -142008,7 +142008,7 @@ var init_SuperConverter_ing_1fvK_es = __esm(() => {
142008
142008
  };
142009
142009
  });
142010
142010
 
142011
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-B_1fvPL0.es.js
142011
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-CUl2z6Fd.es.js
142012
142012
  function parseSizeUnit(val = "0") {
142013
142013
  const length = val.toString() || "0";
142014
142014
  const value = Number.parseFloat(length);
@@ -143718,10 +143718,12 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
143718
143718
  return null;
143719
143719
  superdoc.on("editorCreate", onChange);
143720
143720
  superdoc.on("document-mode-change", onChange);
143721
+ superdoc.on("formatting-marks-change", onChange);
143721
143722
  superdoc.on("zoomChange", onChange);
143722
143723
  return () => {
143723
143724
  superdoc.off?.("editorCreate", onChange);
143724
143725
  superdoc.off?.("document-mode-change", onChange);
143726
+ superdoc.off?.("formatting-marks-change", onChange);
143725
143727
  superdoc.off?.("zoomChange", onChange);
143726
143728
  };
143727
143729
  }, subscribeToEditorEvents = (editor, onChange) => {
@@ -143853,6 +143855,11 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
143853
143855
  active: Boolean(superdoc?.config?.rulers),
143854
143856
  disabled: isCommandDisabled(context)
143855
143857
  };
143858
+ }, createFormattingMarksStateDeriver = () => ({ superdoc }) => {
143859
+ return {
143860
+ active: Boolean(superdoc?.config?.layoutEngineOptions?.showFormattingMarks),
143861
+ disabled: typeof superdoc?.toggleFormattingMarks !== "function"
143862
+ };
143856
143863
  }, createZoomStateDeriver = () => ({ context, superdoc }) => {
143857
143864
  return {
143858
143865
  active: false,
@@ -143868,6 +143875,11 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
143868
143875
  }, createRulerExecute = () => ({ superdoc }) => {
143869
143876
  superdoc.toggleRuler?.();
143870
143877
  return true;
143878
+ }, createFormattingMarksExecute = () => ({ superdoc }) => {
143879
+ if (typeof superdoc?.toggleFormattingMarks !== "function")
143880
+ return false;
143881
+ superdoc.toggleFormattingMarks();
143882
+ return true;
143871
143883
  }, createZoomExecute = () => ({ superdoc, payload }) => {
143872
143884
  const normalizedPayload = Number.parseInt(String(payload), 10);
143873
143885
  if (!Number.isFinite(normalizedPayload) || normalizedPayload <= 0)
@@ -144467,6 +144479,11 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
144467
144479
  state: createRulerStateDeriver(),
144468
144480
  execute: createRulerExecute()
144469
144481
  },
144482
+ "formatting-marks": {
144483
+ id: "formatting-marks",
144484
+ state: createFormattingMarksStateDeriver(),
144485
+ execute: createFormattingMarksExecute()
144486
+ },
144470
144487
  zoom: {
144471
144488
  id: "zoom",
144472
144489
  state: createZoomStateDeriver(),
@@ -144644,7 +144661,7 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
144644
144661
  }
144645
144662
  };
144646
144663
  };
144647
- var init_create_headless_toolbar_B_1fvPL0_es = __esm(() => {
144664
+ var init_create_headless_toolbar_CUl2z6Fd_es = __esm(() => {
144648
144665
  init_SuperConverter_ing_1fvK_es();
144649
144666
  init_constants_DrU4EASo_es();
144650
144667
  init_dist_B8HfvhaK_es();
@@ -198853,7 +198870,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
198853
198870
  init_remark_gfm_BhnWr3yf_es();
198854
198871
  });
198855
198872
 
198856
- // ../../packages/superdoc/dist/chunks/src-DKka36--.es.js
198873
+ // ../../packages/superdoc/dist/chunks/src-deKdT-sq.es.js
198857
198874
  function deleteProps(obj, propOrProps) {
198858
198875
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
198859
198876
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -202632,6 +202649,98 @@ function createDropcapPlugin(editor) {
202632
202649
  } }
202633
202650
  });
202634
202651
  }
202652
+ function isListParagraph(node2) {
202653
+ return node2?.type?.name === "paragraph" && node2.attrs?.paragraphProperties?.numberingProperties && node2.attrs?.listRendering;
202654
+ }
202655
+ function isRtlParagraph$1(node2) {
202656
+ return node2?.attrs?.paragraphProperties?.rightToLeft === true || node2?.attrs?.direction === "rtl" || node2?.attrs?.rtl === true;
202657
+ }
202658
+ function getParagraphContext$1($pos) {
202659
+ for (let depth = $pos.depth;depth >= 0; depth--) {
202660
+ const node2 = $pos.node(depth);
202661
+ if (node2.type.name !== "paragraph")
202662
+ continue;
202663
+ return {
202664
+ node: node2,
202665
+ pos: depth === 0 ? 0 : $pos.before(depth),
202666
+ start: $pos.start(depth),
202667
+ end: $pos.end(depth)
202668
+ };
202669
+ }
202670
+ return null;
202671
+ }
202672
+ function getParagraphTextBounds2(paragraph2, paragraphStart) {
202673
+ let first$1 = null;
202674
+ let last2 = null;
202675
+ paragraph2.descendants((node2, pos) => {
202676
+ if (!node2.isText || !node2.text?.length)
202677
+ return true;
202678
+ const from$1 = paragraphStart + pos;
202679
+ const to = from$1 + node2.text.length;
202680
+ if (first$1 == null || from$1 < first$1)
202681
+ first$1 = from$1;
202682
+ if (last2 == null || to > last2)
202683
+ last2 = to;
202684
+ return true;
202685
+ });
202686
+ return first$1 == null || last2 == null ? null : {
202687
+ first: first$1,
202688
+ last: last2
202689
+ };
202690
+ }
202691
+ function findAdjacentTextPosition(doc$12, boundary, direction) {
202692
+ let target = null;
202693
+ if (direction < 0) {
202694
+ doc$12.nodesBetween(0, boundary, (node2, pos) => {
202695
+ if (node2.isText && node2.text?.length)
202696
+ target = pos + node2.text.length;
202697
+ return true;
202698
+ });
202699
+ return target;
202700
+ }
202701
+ doc$12.nodesBetween(boundary, doc$12.content.size, (node2, pos) => {
202702
+ if (target != null)
202703
+ return false;
202704
+ if (node2.isText && node2.text?.length) {
202705
+ target = pos;
202706
+ return false;
202707
+ }
202708
+ return true;
202709
+ });
202710
+ return target;
202711
+ }
202712
+ function shouldHandlePlainHorizontalArrow(event) {
202713
+ return (event.key === "ArrowLeft" || event.key === "ArrowRight") && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;
202714
+ }
202715
+ function createListBoundaryNavigationPlugin() {
202716
+ return new Plugin({ props: { handleKeyDown(view, event) {
202717
+ if (!shouldHandlePlainHorizontalArrow(event))
202718
+ return false;
202719
+ const { state } = view;
202720
+ const { selection } = state;
202721
+ if (!selection.empty)
202722
+ return false;
202723
+ const paragraph2 = getParagraphContext$1(selection.$from);
202724
+ if (!paragraph2 || !isListParagraph(paragraph2.node))
202725
+ return false;
202726
+ if (isRtlParagraph$1(paragraph2.node))
202727
+ return false;
202728
+ const bounds = getParagraphTextBounds2(paragraph2.node, paragraph2.start);
202729
+ if (!bounds)
202730
+ return false;
202731
+ const direction = event.key === "ArrowLeft" ? -1 : 1;
202732
+ const atLeftBoundary = direction < 0 && selection.from <= bounds.first;
202733
+ const atRightBoundary = direction > 0 && selection.from >= bounds.last;
202734
+ if (!atLeftBoundary && !atRightBoundary)
202735
+ return false;
202736
+ const target = findAdjacentTextPosition(state.doc, direction < 0 ? paragraph2.pos : paragraph2.end, direction);
202737
+ if (target == null || target === selection.from)
202738
+ return false;
202739
+ event.preventDefault();
202740
+ view.dispatch(state.tr.setSelection(TextSelection.create(state.doc, target)).scrollIntoView());
202741
+ return true;
202742
+ } } });
202743
+ }
202635
202744
  function parseCssLength(value) {
202636
202745
  if (!value)
202637
202746
  return null;
@@ -241921,15 +242030,19 @@ function renderListMarker(params$1) {
241921
242030
  const suffixType = markerLayout?.suffix ?? "tab";
241922
242031
  if (suffixType === "tab") {
241923
242032
  const tabEl = doc$12.createElement("span");
241924
- tabEl.className = "superdoc-tab";
242033
+ tabEl.classList.add("superdoc-tab", "superdoc-marker-suffix-tab");
241925
242034
  tabEl.innerHTML = "&nbsp;";
241926
242035
  tabEl.style.display = "inline-block";
242036
+ if (markerLayout?.run?.fontSize != null)
242037
+ tabEl.style.fontSize = `${markerLayout.run.fontSize}px`;
241927
242038
  tabEl.style.wordSpacing = "0px";
241928
242039
  tabEl.style.width = `${listTabWidth}px`;
241929
242040
  lineEl.prepend(tabEl);
241930
242041
  } else if (suffixType === "space") {
241931
242042
  const spaceEl = doc$12.createElement("span");
241932
242043
  spaceEl.classList.add("superdoc-marker-suffix-space");
242044
+ if (markerLayout?.run?.fontSize != null)
242045
+ spaceEl.style.fontSize = `${markerLayout.run.fontSize}px`;
241933
242046
  spaceEl.style.wordSpacing = "0px";
241934
242047
  spaceEl.textContent = " ";
241935
242048
  lineEl.prepend(spaceEl);
@@ -242815,9 +242928,9 @@ function resolveParagraphContent(fragment, block, measure) {
242815
242928
  const paragraphLineIndex = fragment.fromLine + index2;
242816
242929
  const isFirstLineOfPara = paragraphLineIndex === 0;
242817
242930
  const firstLineOffsetForCumX = isFirstLineOfPara ? firstLine - hanging : 0;
242818
- const isListParagraph = Boolean(wordLayout?.marker);
242931
+ const isListParagraph$1 = Boolean(wordLayout?.marker);
242819
242932
  const fallbackListTextStartPx = typeof wordLayout?.marker?.textStartX === "number" && Number.isFinite(wordLayout.marker.textStartX) ? wordLayout.marker.textStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : undefined;
242820
- const indentOffset = isListParagraph ? isFirstLineOfPara ? (shouldUseResolvedListTextStart ? listFirstLineTextStartPx : undefined) ?? fallbackListTextStartPx ?? indentLeft : indentLeft : indentLeft + firstLineOffsetForCumX;
242933
+ const indentOffset = isListParagraph$1 ? isFirstLineOfPara ? (shouldUseResolvedListTextStart ? listFirstLineTextStartPx : undefined) ?? fallbackListTextStartPx ?? indentLeft : indentLeft : indentLeft + firstLineOffsetForCumX;
242821
242934
  return {
242822
242935
  line,
242823
242936
  lineIndex: paragraphLineIndex,
@@ -251451,11 +251564,9 @@ function collectClientRectsByLine(doc$12, entries, sliceFrom, sliceTo) {
251451
251564
  function setDomRangeStart(range, entry, pos) {
251452
251565
  const el = entry.el;
251453
251566
  const pmStart = entry.pmStart;
251454
- const firstChild = el.firstChild;
251455
- if (firstChild && firstChild.nodeType === Node.TEXT_NODE) {
251456
- const textNode = firstChild;
251457
- const charIndex = mapPmPosToCharIndex(pos, pmStart, entry.pmEnd, textNode.length);
251458
- range.setStart(textNode, charIndex);
251567
+ const boundary = resolveTextBoundaryInElement(el, pos, pmStart, entry.pmEnd, "forward");
251568
+ if (boundary) {
251569
+ range.setStart(boundary.node, boundary.offset);
251459
251570
  return true;
251460
251571
  }
251461
251572
  if (!el.isConnected || !el.parentNode)
@@ -251470,11 +251581,9 @@ function setDomRangeStart(range, entry, pos) {
251470
251581
  function setDomRangeEnd(range, entry, pos) {
251471
251582
  const el = entry.el;
251472
251583
  const pmStart = entry.pmStart;
251473
- const firstChild = el.firstChild;
251474
- if (firstChild && firstChild.nodeType === Node.TEXT_NODE) {
251475
- const textNode = firstChild;
251476
- const charIndex = mapPmPosToCharIndex(pos, pmStart, entry.pmEnd, textNode.length);
251477
- range.setEnd(textNode, charIndex);
251584
+ const boundary = resolveTextBoundaryInElement(el, pos, pmStart, entry.pmEnd, "backward");
251585
+ if (boundary) {
251586
+ range.setEnd(boundary.node, boundary.offset);
251478
251587
  return true;
251479
251588
  }
251480
251589
  if (!el.isConnected || !el.parentNode)
@@ -251504,8 +251613,8 @@ function computeDomCaretPageLocal(options, pos) {
251504
251613
  return null;
251505
251614
  const pageRect = page.getBoundingClientRect();
251506
251615
  const zoom = options.zoom;
251507
- const textNode = targetEl.firstChild;
251508
- if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
251616
+ const boundary = resolveTextBoundaryInElement(targetEl, pos, entry.pmStart, entry.pmEnd, "forward");
251617
+ if (!boundary) {
251509
251618
  const elRect = targetEl.getBoundingClientRect();
251510
251619
  const atEnd = pos >= entry.pmEnd;
251511
251620
  return {
@@ -251514,10 +251623,9 @@ function computeDomCaretPageLocal(options, pos) {
251514
251623
  y: (elRect.top - pageRect.top) / zoom
251515
251624
  };
251516
251625
  }
251517
- const charIndex = mapPmPosToCharIndex(pos, entry.pmStart, entry.pmEnd, textNode.length);
251518
251626
  const range = document.createRange();
251519
- range.setStart(textNode, charIndex);
251520
- range.setEnd(textNode, charIndex);
251627
+ range.setStart(boundary.node, boundary.offset);
251628
+ range.setEnd(boundary.node, boundary.offset);
251521
251629
  const rangeRect = range.getBoundingClientRect();
251522
251630
  const lineRect = targetEl.closest(".superdoc-line")?.getBoundingClientRect() ?? rangeRect;
251523
251631
  return {
@@ -251526,6 +251634,53 @@ function computeDomCaretPageLocal(options, pos) {
251526
251634
  y: (lineRect.top - pageRect.top) / zoom
251527
251635
  };
251528
251636
  }
251637
+ function resolveTextBoundaryInElement(element3, pos, pmStart, pmEnd, affinity) {
251638
+ const textLength = element3.textContent?.length ?? 0;
251639
+ if (textLength <= 0)
251640
+ return null;
251641
+ return resolveDescendantTextBoundary(element3, mapPmPosToCharIndex(pos, pmStart, pmEnd, textLength), affinity);
251642
+ }
251643
+ function resolveDescendantTextBoundary(element3, targetOffset, affinity) {
251644
+ const walker = (element3.ownerDocument ?? document).createTreeWalker(element3, NodeFilter.SHOW_TEXT);
251645
+ let consumed = 0;
251646
+ let previous3 = null;
251647
+ let current = walker.nextNode();
251648
+ while (current) {
251649
+ const textNode = current;
251650
+ const textLength = textNode.textContent?.length ?? 0;
251651
+ if (textLength <= 0) {
251652
+ current = walker.nextNode();
251653
+ continue;
251654
+ }
251655
+ const segmentEnd = consumed + textLength;
251656
+ if (targetOffset < segmentEnd)
251657
+ return {
251658
+ node: textNode,
251659
+ offset: Math.max(0, targetOffset - consumed)
251660
+ };
251661
+ if (targetOffset === segmentEnd) {
251662
+ if (affinity === "backward")
251663
+ return {
251664
+ node: textNode,
251665
+ offset: textLength
251666
+ };
251667
+ previous3 = {
251668
+ node: textNode,
251669
+ offset: textLength
251670
+ };
251671
+ consumed = segmentEnd;
251672
+ current = walker.nextNode();
251673
+ continue;
251674
+ }
251675
+ previous3 = {
251676
+ node: textNode,
251677
+ offset: textLength
251678
+ };
251679
+ consumed = segmentEnd;
251680
+ current = walker.nextNode();
251681
+ }
251682
+ return previous3;
251683
+ }
251529
251684
  function mapPmPosToCharIndex(pos, pmStart, pmEnd, textLength) {
251530
251685
  if (!Number.isFinite(pos) || !Number.isFinite(pmStart) || !Number.isFinite(pmEnd))
251531
251686
  return 0;
@@ -273025,6 +273180,16 @@ var Node$13 = class Node$14 {
273025
273180
  tooltip: toolbarTexts$1.ruler,
273026
273181
  attributes: { ariaLabel: "Ruler" }
273027
273182
  });
273183
+ const formattingMarks = useToolbarItem({
273184
+ type: "button",
273185
+ name: "formattingMarks",
273186
+ command: "toggleFormattingMarks",
273187
+ allowWithoutEditor: true,
273188
+ icon: toolbarIcons$1.formattingMarks,
273189
+ active: false,
273190
+ tooltip: toolbarTexts$1.formattingMarks,
273191
+ attributes: { ariaLabel: "Formatting marks" }
273192
+ });
273028
273193
  const selectedLinkedStyle = exports_vue.ref(null);
273029
273194
  const linkedStyles = useToolbarItem({
273030
273195
  type: "dropdown",
@@ -273122,7 +273287,8 @@ var Node$13 = class Node$14 {
273122
273287
  "linkedStyles",
273123
273288
  "clearFormatting",
273124
273289
  "copyFormat",
273125
- "ruler"
273290
+ "ruler",
273291
+ "formattingMarks"
273126
273292
  ];
273127
273293
  const itemsToHideSM = [
273128
273294
  "zoom",
@@ -273173,6 +273339,7 @@ var Node$13 = class Node$14 {
273173
273339
  linkedStyles,
273174
273340
  separator,
273175
273341
  ruler,
273342
+ formattingMarks,
273176
273343
  copyFormat,
273177
273344
  clearFormatting,
273178
273345
  aiButton,
@@ -273188,6 +273355,7 @@ var Node$13 = class Node$14 {
273188
273355
  toolbarItems.splice(getLinkedStylesIndex - 1, 2);
273189
273356
  const filterItems = [
273190
273357
  "ruler",
273358
+ "formattingMarks",
273191
273359
  "zoom",
273192
273360
  "undo",
273193
273361
  "redo"
@@ -276778,6 +276946,82 @@ var Node$13 = class Node$14 {
276778
276946
  .superdoc-layout .track-format-dec.highlighted.track-change-focused {
276779
276947
  background-color: var(--sd-tracked-changes-format-background-focused, #ffd70033);
276780
276948
  }
276949
+ `, FORMATTING_MARKS_STYLES = `
276950
+ .superdoc-formatting-space-mark,
276951
+ .superdoc-marker-suffix-space {
276952
+ position: relative;
276953
+ }
276954
+
276955
+ .superdoc-formatting-space-mark {
276956
+ white-space: pre;
276957
+ }
276958
+
276959
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-tab {
276960
+ position: relative;
276961
+ visibility: visible !important;
276962
+ }
276963
+
276964
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-tab::after {
276965
+ content: "→";
276966
+ position: absolute;
276967
+ left: 50%;
276968
+ top: 50%;
276969
+ transform: translate(-50%, -50%);
276970
+ color: var(--sd-formatting-mark-color, var(--sd-ui-action, currentColor));
276971
+ font-size: 0.75em;
276972
+ line-height: 1;
276973
+ pointer-events: none;
276974
+ }
276975
+
276976
+ .superdoc-layout.superdoc-show-formatting-marks [dir="rtl"] .superdoc-tab::after {
276977
+ content: "←";
276978
+ }
276979
+
276980
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-formatting-space-mark::after,
276981
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-marker-suffix-space::after {
276982
+ content: "·";
276983
+ position: absolute;
276984
+ left: 50%;
276985
+ top: 50%;
276986
+ transform: translate(-50%, -50%);
276987
+ color: var(--sd-formatting-mark-color, var(--sd-ui-action, currentColor));
276988
+ font-size: 0.75em;
276989
+ line-height: 1;
276990
+ pointer-events: none;
276991
+ }
276992
+
276993
+ .superdoc-formatting-paragraph-mark {
276994
+ display: none;
276995
+ position: absolute;
276996
+ top: 0;
276997
+ transform: translateX(var(--sd-formatting-paragraph-mark-gap, 0.2em));
276998
+ color: var(--sd-formatting-mark-color, var(--sd-ui-action, currentColor));
276999
+ pointer-events: none;
277000
+ user-select: none;
277001
+ white-space: pre;
277002
+ z-index: 2;
277003
+ }
277004
+
277005
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-formatting-paragraph-mark {
277006
+ display: inline;
277007
+ }
277008
+
277009
+ .superdoc-layout.superdoc-show-formatting-marks [dir="rtl"] .superdoc-formatting-paragraph-mark {
277010
+ transform: translateX(calc(-100% - var(--sd-formatting-paragraph-mark-gap, 0.2em)));
277011
+ }
277012
+
277013
+ @media print {
277014
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-tab::after,
277015
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-formatting-space-mark::after,
277016
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-marker-suffix-space::after {
277017
+ content: "";
277018
+ display: none;
277019
+ }
277020
+
277021
+ .superdoc-layout.superdoc-show-formatting-marks .superdoc-formatting-paragraph-mark {
277022
+ display: none;
277023
+ }
277024
+ }
276781
277025
  `, SDT_CONTAINER_STYLES = `
276782
277026
  /* Document Section - Block-level container with gray border and hover tooltip */
276783
277027
  .superdoc-document-section {
@@ -277149,7 +277393,7 @@ menclose::after {
277149
277393
  pointer-events: none;
277150
277394
  background: var(--sd-menclose-h), var(--sd-menclose-v), var(--sd-menclose-up), var(--sd-menclose-down);
277151
277395
  }
277152
- `, printStylesInjected = false, linkStylesInjected = false, trackChangeStylesInjected = false, sdtContainerStylesInjected = false, fieldAnnotationStylesInjected = false, imageSelectionStylesInjected = false, mathMencloseStylesInjected = false, ensurePrintStyles = (doc$12) => {
277396
+ `, printStylesInjected = false, linkStylesInjected = false, trackChangeStylesInjected = false, formattingMarksStylesInjected = false, sdtContainerStylesInjected = false, fieldAnnotationStylesInjected = false, imageSelectionStylesInjected = false, mathMencloseStylesInjected = false, ensurePrintStyles = (doc$12) => {
277153
277397
  if (printStylesInjected || !doc$12)
277154
277398
  return;
277155
277399
  const styleEl = doc$12.createElement("style");
@@ -277173,6 +277417,14 @@ menclose::after {
277173
277417
  styleEl.textContent = TRACK_CHANGE_STYLES;
277174
277418
  doc$12.head?.appendChild(styleEl);
277175
277419
  trackChangeStylesInjected = true;
277420
+ }, ensureFormattingMarksStyles = (doc$12) => {
277421
+ if (formattingMarksStylesInjected || !doc$12)
277422
+ return;
277423
+ const styleEl = doc$12.createElement("style");
277424
+ styleEl.setAttribute("data-superdoc-formatting-marks-styles", "true");
277425
+ styleEl.textContent = FORMATTING_MARKS_STYLES;
277426
+ doc$12.head?.appendChild(styleEl);
277427
+ formattingMarksStylesInjected = true;
277176
277428
  }, ensureSdtContainerStyles = (doc$12) => {
277177
277429
  if (sdtContainerStylesInjected || !doc$12)
277178
277430
  return;
@@ -277661,6 +277913,12 @@ menclose::after {
277661
277913
  if (value != null && value !== "" && key2 in el.style)
277662
277914
  el.style[key2] = String(value);
277663
277915
  });
277916
+ }, convertParagraphMarkToCellMark = (lineEl) => {
277917
+ const mark2 = lineEl.querySelector(".superdoc-formatting-paragraph-mark");
277918
+ if (!mark2)
277919
+ return;
277920
+ mark2.classList.add("superdoc-formatting-cell-mark");
277921
+ mark2.textContent = "¤";
277664
277922
  }, renderEmbeddedTable = (params$1) => {
277665
277923
  const { doc: doc$12, table: table2, measure, availableWidth, context, renderLine, captureLineSnapshot, renderDrawingContent, applySdtDataset, fromRow: paramFromRow, toRow: paramToRow, partialRow: paramPartialRow } = params$1;
277666
277924
  const effectiveFromRow = paramFromRow ?? 0;
@@ -277935,6 +278193,7 @@ menclose::after {
277935
278193
  const paragraphMeasure = blockMeasure;
277936
278194
  const lines = paragraphMeasure.lines;
277937
278195
  const blockLineCount = lines?.length || 0;
278196
+ const isLastBlockInCell = i4 === Math.min(blockMeasures.length, cellBlocks.length) - 1;
277938
278197
  const wordLayout = block.attrs?.wordLayout ?? null;
277939
278198
  const markerLayout = wordLayout?.marker;
277940
278199
  const markerMeasure = paragraphMeasure.marker;
@@ -277989,6 +278248,8 @@ menclose::after {
277989
278248
  ...context,
277990
278249
  section: "body"
277991
278250
  }, lineIdx, isLastLine, lineIdx === 0 && localStartLine === 0 ? listFirstLineTextStartPx : undefined);
278251
+ if (isLastBlockInCell && isLastLine)
278252
+ convertParagraphMarkToCellMark(lineEl);
277992
278253
  lineEl.style.paddingLeft = "";
277993
278254
  lineEl.style.paddingRight = "";
277994
278255
  lineEl.style.textIndent = "";
@@ -279408,6 +279669,9 @@ menclose::after {
279408
279669
  },
279409
279670
  setScrollContainer(el) {
279410
279671
  painter.setScrollContainer(el);
279672
+ },
279673
+ setShowFormattingMarks(showFormattingMarks) {
279674
+ painter.setShowFormattingMarks(showFormattingMarks);
279411
279675
  }
279412
279676
  };
279413
279677
  }, PresentationPaintIndex = class {
@@ -279491,13 +279755,16 @@ menclose::after {
279491
279755
  #zoom = 1;
279492
279756
  #scrollContainer = null;
279493
279757
  #virtualizationPins = [];
279758
+ #showFormattingMarks = false;
279494
279759
  get hasPainter() {
279495
279760
  return this.#painter !== null;
279496
279761
  }
279497
279762
  ensurePainter(options) {
279498
279763
  if (!this.#painter) {
279764
+ this.#showFormattingMarks = Boolean(options.showFormattingMarks ?? this.#showFormattingMarks);
279499
279765
  this.#painter = createDomPainter({
279500
279766
  ...options,
279767
+ showFormattingMarks: this.#showFormattingMarks,
279501
279768
  onPaintSnapshot: (snapshot2) => {
279502
279769
  this.#lastPaintSnapshot = snapshot2;
279503
279770
  this.#paintIndex.update(snapshot2);
@@ -279521,6 +279788,13 @@ menclose::after {
279521
279788
  this.#footerProvider = footer;
279522
279789
  this.#applyProviders();
279523
279790
  }
279791
+ setShowFormattingMarks(showFormattingMarks) {
279792
+ const next2 = Boolean(showFormattingMarks);
279793
+ if (this.#showFormattingMarks === next2)
279794
+ return;
279795
+ this.#showFormattingMarks = next2;
279796
+ this.#applyShowFormattingMarks();
279797
+ }
279524
279798
  setZoom(zoom) {
279525
279799
  if (this.#zoom === zoom)
279526
279800
  return;
@@ -279575,6 +279849,7 @@ menclose::after {
279575
279849
  this.#applyZoom();
279576
279850
  this.#applyScrollContainer();
279577
279851
  this.#applyVirtualizationPins();
279852
+ this.#applyShowFormattingMarks();
279578
279853
  }
279579
279854
  #applyProviders() {
279580
279855
  this.#painter?.setProviders(this.#headerProvider, this.#footerProvider);
@@ -279588,6 +279863,9 @@ menclose::after {
279588
279863
  #applyVirtualizationPins() {
279589
279864
  this.#painter?.setVirtualizationPins(this.#virtualizationPins);
279590
279865
  }
279866
+ #applyShowFormattingMarks() {
279867
+ this.#painter?.setShowFormattingMarks(this.#showFormattingMarks);
279868
+ }
279591
279869
  }, hashParagraphBorder$1 = (border) => {
279592
279870
  const parts = [];
279593
279871
  if (border.style !== undefined)
@@ -282739,7 +283017,7 @@ menclose::after {
282739
283017
  let paraIndentLeft = 0;
282740
283018
  let paraIndentRight = 0;
282741
283019
  let effectiveLeft = 0;
282742
- let isListParagraph = false;
283020
+ let isListParagraph$1 = false;
282743
283021
  let wl;
282744
283022
  if (block.kind === "paragraph") {
282745
283023
  const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
@@ -282748,8 +283026,8 @@ menclose::after {
282748
283026
  paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
282749
283027
  effectiveLeft = paraIndentLeft;
282750
283028
  wl = getWordLayoutConfig(block);
282751
- isListParagraph = Boolean(block.attrs?.numberingProperties) || Boolean(wl?.marker);
282752
- if (isListParagraph) {
283029
+ isListParagraph$1 = Boolean(block.attrs?.numberingProperties) || Boolean(wl?.marker);
283030
+ if (isListParagraph$1) {
282753
283031
  const explicitTextStart = typeof wl?.marker?.textStartX === "number" && Number.isFinite(wl.marker.textStartX) ? wl.marker.textStartX : typeof wl?.textStartPx === "number" && Number.isFinite(wl.textStartPx) ? wl.textStartPx : undefined;
282754
283032
  if (typeof explicitTextStart === "number" && explicitTextStart > paraIndentLeft)
282755
283033
  effectiveLeft = explicitTextStart;
@@ -282759,7 +283037,7 @@ menclose::after {
282759
283037
  let availableWidth = Math.max(0, fragmentWidth - totalIndent);
282760
283038
  if (totalIndent > fragmentWidth)
282761
283039
  console.warn(`[mapPmToX] Paragraph indents (${totalIndent}px) exceed fragment width (${fragmentWidth}px) for block ${block.id}. This may indicate a layout miscalculation. Available width clamped to 0.`);
282762
- const hasRenderedMarkerText = isListParagraph && (markerTextWidth ?? 0) > 0;
283040
+ const hasRenderedMarkerText = isListParagraph$1 && (markerTextWidth ?? 0) > 0;
282763
283041
  if (isFirstLine && block.kind === "paragraph" && !hasRenderedMarkerText) {
282764
283042
  const suppressFLI = block.attrs?.suppressFirstLineIndent === true;
282765
283043
  const firstLineOffset = getFirstLineIndentOffset(block.attrs?.indent, suppressFLI);
@@ -290466,12 +290744,12 @@ menclose::after {
290466
290744
  return;
290467
290745
  console.log(...args$1);
290468
290746
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions;
290469
- var init_src_DKka36_es = __esm(() => {
290747
+ var init_src_deKdT_sq_es = __esm(() => {
290470
290748
  init_rolldown_runtime_Bg48TavK_es();
290471
290749
  init_SuperConverter_ing_1fvK_es();
290472
290750
  init_jszip_C49i9kUs_es();
290473
290751
  init_uuid_qzgm05fK_es();
290474
- init_create_headless_toolbar_B_1fvPL0_es();
290752
+ init_create_headless_toolbar_CUl2z6Fd_es();
290475
290753
  init_constants_DrU4EASo_es();
290476
290754
  init_dist_B8HfvhaK_es();
290477
290755
  init_unified_Dsuw2be5_es();
@@ -293516,7 +293794,8 @@ ${err.toString()}`);
293516
293794
  event.preventDefault();
293517
293795
  return true;
293518
293796
  } } } }),
293519
- createLeadingCaretPlugin()
293797
+ createLeadingCaretPlugin(),
293798
+ createListBoundaryNavigationPlugin()
293520
293799
  ];
293521
293800
  }
293522
293801
  });
@@ -309266,7 +309545,9 @@ function print() { __p += __j.call(arguments, '') }
309266
309545
  cut: scissors_solid_default,
309267
309546
  copy: copy_solid_default,
309268
309547
  paste: paste_solid_default,
309269
- strikethrough: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M161.3 144c3.2-17.2 14-30.1 33.7-38.6c21.1-9 51.8-12.3 88.6-6.5c11.9 1.9 48.8 9.1 60.1 12c17.1 4.5 34.6-5.6 39.2-22.7s-5.6-34.6-22.7-39.2c-14.3-3.8-53.6-11.4-66.6-13.4c-44.7-7-88.3-4.2-123.7 10.9c-36.5 15.6-64.4 44.8-71.8 87.3c-.1 .6-.2 1.1-.2 1.7c-2.8 23.9 .5 45.6 10.1 64.6c4.5 9 10.2 16.9 16.7 23.9L32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l448 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-209.9 0-.4-.1-1.1-.3c-36-10.8-65.2-19.6-85.2-33.1c-9.3-6.3-15-12.6-18.2-19.1c-3.1-6.1-5.2-14.6-3.8-27.4zM348.9 337.2c2.7 6.5 4.4 15.8 1.9 30.1c-3 17.6-13.8 30.8-33.9 39.4c-21.1 9-51.7 12.3-88.5 6.5c-18-2.9-49.1-13.5-74.4-22.1c-5.6-1.9-11-3.7-15.9-5.4c-16.8-5.6-34.9 3.5-40.5 20.3s3.5 34.9 20.3 40.5c3.6 1.2 7.9 2.7 12.7 4.3c0 0 0 0 0 0s0 0 0 0c24.9 8.5 63.6 21.7 87.6 25.6c0 0 0 0 0 0l.2 0c44.7 7 88.3 4.2 123.7-10.9c36.5-15.6 64.4-44.8 71.8-87.3c3.6-21 2.7-40.4-3.1-58.1l-75.7 0c7 5.6 11.4 11.2 13.9 17.2z"/></svg>\n'
309548
+ strikethrough: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M161.3 144c3.2-17.2 14-30.1 33.7-38.6c21.1-9 51.8-12.3 88.6-6.5c11.9 1.9 48.8 9.1 60.1 12c17.1 4.5 34.6-5.6 39.2-22.7s-5.6-34.6-22.7-39.2c-14.3-3.8-53.6-11.4-66.6-13.4c-44.7-7-88.3-4.2-123.7 10.9c-36.5 15.6-64.4 44.8-71.8 87.3c-.1 .6-.2 1.1-.2 1.7c-2.8 23.9 .5 45.6 10.1 64.6c4.5 9 10.2 16.9 16.7 23.9L32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l448 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-209.9 0-.4-.1-1.1-.3c-36-10.8-65.2-19.6-85.2-33.1c-9.3-6.3-15-12.6-18.2-19.1c-3.1-6.1-5.2-14.6-3.8-27.4zM348.9 337.2c2.7 6.5 4.4 15.8 1.9 30.1c-3 17.6-13.8 30.8-33.9 39.4c-21.1 9-51.7 12.3-88.5 6.5c-18-2.9-49.1-13.5-74.4-22.1c-5.6-1.9-11-3.7-15.9-5.4c-16.8-5.6-34.9 3.5-40.5 20.3s3.5 34.9 20.3 40.5c3.6 1.2 7.9 2.7 12.7 4.3c0 0 0 0 0 0s0 0 0 0c24.9 8.5 63.6 21.7 87.6 25.6c0 0 0 0 0 0l.2 0c44.7 7 88.3 4.2 123.7-10.9c36.5-15.6 64.4-44.8 71.8-87.3c3.6-21 2.7-40.4-3.1-58.1l-75.7 0c7 5.6 11.4 11.2 13.9 17.2z"/></svg>\n',
309549
+ formattingMarks: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true"><text x="12" y="18" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="20" font-weight="700" fill="currentColor">¶</text></svg>
309550
+ `
309270
309551
  };
309271
309552
  _hoisted_1$20 = [
309272
309553
  "onClick",
@@ -310443,6 +310724,7 @@ function print() { __p += __j.call(arguments, '') }
310443
310724
  acceptTrackedChangeBySelection: "track-changes-accept-selection",
310444
310725
  rejectTrackedChangeOnSelection: "track-changes-reject-selection",
310445
310726
  ruler: "ruler",
310727
+ formattingMarks: "formatting-marks",
310446
310728
  zoom: "zoom",
310447
310729
  documentMode: "document-mode",
310448
310730
  link: "link",
@@ -311930,6 +312212,7 @@ function print() { __p += __j.call(arguments, '') }
311930
312212
  lineHeight: "Line height",
311931
312213
  formatText: "Format text",
311932
312214
  ruler: "Show or hide ruler",
312215
+ formattingMarks: "Show or hide formatting marks",
311933
312216
  pageBreak: "Insert page break",
311934
312217
  documentEditingMode: "Editing",
311935
312218
  documentSuggestingMode: "Suggesting",
@@ -312309,6 +312592,10 @@ function print() { __p += __j.call(arguments, '') }
312309
312592
  const currentMode = this.snapshot?.commands?.["document-mode"]?.value || "editing";
312310
312593
  if (!this.activeEditor || currentMode === "viewing") {
312311
312594
  this.#deactivateAll();
312595
+ this.toolbarItems.forEach((item) => {
312596
+ if (item.allowWithoutEditor?.value)
312597
+ this.#applyHeadlessState(item);
312598
+ });
312312
312599
  return;
312313
312600
  }
312314
312601
  const { state } = this.activeEditor;
@@ -316904,11 +317191,13 @@ function print() { __p += __j.call(arguments, '') }
316904
317191
  this.onPaintSnapshotCallback = null;
316905
317192
  this.mountedPageIndices = [];
316906
317193
  this.resolvedLayout = null;
317194
+ this.showFormattingMarks = false;
316907
317195
  this.options = options;
316908
317196
  this.layoutMode = options.layoutMode ?? "vertical";
316909
317197
  this.isSemanticFlow = (options.flowMode ?? "paginated") === "semantic";
316910
317198
  this.headerProvider = options.headerProvider;
316911
317199
  this.footerProvider = options.footerProvider;
317200
+ this.showFormattingMarks = options.showFormattingMarks === true;
316912
317201
  const defaultGap = this.layoutMode === "horizontal" ? 20 : 24;
316913
317202
  this.pageGap = typeof options.pageGap === "number" && Number.isFinite(options.pageGap) ? Math.max(0, options.pageGap) : defaultGap;
316914
317203
  if (!this.isSemanticFlow && this.layoutMode === "vertical" && options.virtualization?.enabled) {
@@ -316925,10 +317214,33 @@ function print() { __p += __j.call(arguments, '') }
316925
317214
  }
316926
317215
  this.onPaintSnapshotCallback = options.onPaintSnapshot ?? null;
316927
317216
  }
317217
+ setShowFormattingMarks(showFormattingMarks) {
317218
+ const next2 = showFormattingMarks === true;
317219
+ if (this.showFormattingMarks === next2)
317220
+ return;
317221
+ this.showFormattingMarks = next2;
317222
+ this.applyFormattingMarksClass();
317223
+ this.invalidateRenderedContent();
317224
+ }
316928
317225
  setProviders(header, footer) {
316929
317226
  this.headerProvider = header;
316930
317227
  this.footerProvider = footer;
316931
317228
  }
317229
+ applyFormattingMarksClass(mount = this.mount) {
317230
+ mount?.classList.toggle("superdoc-show-formatting-marks", this.showFormattingMarks);
317231
+ }
317232
+ invalidateRenderedContent() {
317233
+ this.pageStates = [];
317234
+ this.currentLayout = null;
317235
+ this.pageIndexToState.clear();
317236
+ this.virtualMountedKey = "";
317237
+ this.clearGapSpacers();
317238
+ this.topSpacerEl = null;
317239
+ this.bottomSpacerEl = null;
317240
+ this.virtualPagesEl = null;
317241
+ this.processedLayoutVersion = -1;
317242
+ this.layoutVersion += 1;
317243
+ }
316932
317244
  setVirtualizationPins(pageIndices) {
316933
317245
  this.virtualPinnedPages = Array.from(new Set((pageIndices ?? []).filter((n) => Number.isInteger(n)))).sort((a2, b$1) => a2 - b$1);
316934
317246
  if (this.virtualEnabled && this.mount)
@@ -317111,6 +317423,7 @@ function print() { __p += __j.call(arguments, '') }
317111
317423
  ensurePrintStyles(doc$12);
317112
317424
  ensureLinkStyles(doc$12);
317113
317425
  ensureTrackChangeStyles(doc$12);
317426
+ ensureFormattingMarksStyles(doc$12);
317114
317427
  ensureFieldAnnotationStyles(doc$12);
317115
317428
  ensureSdtContainerStyles(doc$12);
317116
317429
  ensureImageSelectionStyles(doc$12);
@@ -317118,8 +317431,11 @@ function print() { __p += __j.call(arguments, '') }
317118
317431
  if (!this.isSemanticFlow && this.options.ruler?.enabled)
317119
317432
  ensureRulerStyles(doc$12);
317120
317433
  mount.classList.add(CLASS_NAMES$1.container);
317121
- if (this.mount && this.mount !== mount)
317434
+ this.applyFormattingMarksClass(mount);
317435
+ if (this.mount && this.mount !== mount) {
317122
317436
  this.resetState();
317437
+ this.applyFormattingMarksClass(mount);
317438
+ }
317123
317439
  this.layoutVersion += 1;
317124
317440
  this.layoutEpoch = resolvedLayout.layoutEpoch ?? 0;
317125
317441
  this.mount = mount;
@@ -318110,7 +318426,8 @@ function print() { __p += __j.call(arguments, '') }
318110
318426
  const resolvedMarker = content3.marker;
318111
318427
  const expandedRunsForBlock = expandRunsForInlineNewlines(block.runs);
318112
318428
  content3.lines.forEach((resolvedLine) => {
318113
- const lineEl = this.renderLine(block, resolvedLine.line, context, resolvedLine.availableWidth, resolvedLine.lineIndex, resolvedLine.skipJustify, expandedRunsForBlock, resolvedLine.resolvedListTextStartPx, resolvedLine.indentOffset);
318429
+ const paragraphMarkLeftOffset = this.resolveResolvedListParagraphMarkOffset(resolvedLine.isListFirstLine ? resolvedMarker : undefined, fragment.markerTextWidth, resolvedLine.indentOffset);
318430
+ const lineEl = this.renderLine(block, resolvedLine.line, context, resolvedLine.availableWidth, resolvedLine.lineIndex, resolvedLine.skipJustify, expandedRunsForBlock, resolvedLine.resolvedListTextStartPx, resolvedLine.indentOffset, paragraphMarkLeftOffset);
318114
318431
  if (!resolvedLine.isListFirstLine) {
318115
318432
  if (resolvedLine.paddingLeftPx > 0)
318116
318433
  lineEl.style.paddingLeft = `${resolvedLine.paddingLeftPx}px`;
@@ -318155,15 +318472,17 @@ function print() { __p += __j.call(arguments, '') }
318155
318472
  markerContainer.appendChild(markerEl);
318156
318473
  if (resolvedMarker.suffix === "tab") {
318157
318474
  const tabEl = this.doc.createElement("span");
318158
- tabEl.className = "superdoc-tab";
318475
+ tabEl.classList.add("superdoc-tab", "superdoc-marker-suffix-tab");
318159
318476
  tabEl.innerHTML = "&nbsp;";
318160
318477
  tabEl.style.display = "inline-block";
318478
+ tabEl.style.fontSize = `${resolvedMarker.run.fontSize}px`;
318161
318479
  tabEl.style.wordSpacing = "0px";
318162
318480
  tabEl.style.width = `${resolvedMarker.suffixWidthPx}px`;
318163
318481
  lineEl.prepend(tabEl);
318164
318482
  } else if (resolvedMarker.suffix === "space") {
318165
318483
  const spaceEl = this.doc.createElement("span");
318166
318484
  spaceEl.classList.add("superdoc-marker-suffix-space");
318485
+ spaceEl.style.fontSize = `${resolvedMarker.run.fontSize}px`;
318167
318486
  spaceEl.style.wordSpacing = "0px";
318168
318487
  spaceEl.textContent = " ";
318169
318488
  lineEl.prepend(spaceEl);
@@ -318294,15 +318613,17 @@ function print() { __p += __j.call(arguments, '') }
318294
318613
  const suffix = marker.suffix ?? "tab";
318295
318614
  if (suffix === "tab") {
318296
318615
  const tabEl = this.doc.createElement("span");
318297
- tabEl.className = "superdoc-tab";
318616
+ tabEl.classList.add("superdoc-tab", "superdoc-marker-suffix-tab");
318298
318617
  tabEl.innerHTML = "&nbsp;";
318299
318618
  tabEl.style.display = "inline-block";
318619
+ tabEl.style.fontSize = `${marker.run.fontSize}px`;
318300
318620
  tabEl.style.wordSpacing = "0px";
318301
318621
  tabEl.style.width = `${listTabWidth}px`;
318302
318622
  lineEl.prepend(tabEl);
318303
318623
  } else if (suffix === "space") {
318304
318624
  const spaceEl = this.doc.createElement("span");
318305
318625
  spaceEl.classList.add("superdoc-marker-suffix-space");
318626
+ spaceEl.style.fontSize = `${marker.run.fontSize}px`;
318306
318627
  spaceEl.style.wordSpacing = "0px";
318307
318628
  spaceEl.textContent = " ";
318308
318629
  lineEl.prepend(spaceEl);
@@ -319514,6 +319835,87 @@ function print() { __p += __j.call(arguments, '') }
319514
319835
  wrapper.dataset.pmEnd = String(run2.pmEnd);
319515
319836
  return wrapper;
319516
319837
  }
319838
+ setTextContentWithFormattingSpaceMarks(element3, text5) {
319839
+ if (!this.showFormattingMarks || !text5.includes(" ") || !this.doc) {
319840
+ element3.textContent = text5;
319841
+ return;
319842
+ }
319843
+ element3.textContent = "";
319844
+ let chunkStart = 0;
319845
+ for (let index2 = 0;index2 < text5.length; index2 += 1) {
319846
+ if (text5[index2] !== " ")
319847
+ continue;
319848
+ if (index2 > chunkStart)
319849
+ element3.appendChild(this.doc.createTextNode(text5.slice(chunkStart, index2)));
319850
+ const space = this.doc.createElement("span");
319851
+ space.classList.add("superdoc-formatting-space-mark");
319852
+ space.textContent = " ";
319853
+ element3.appendChild(space);
319854
+ chunkStart = index2 + 1;
319855
+ }
319856
+ if (chunkStart < text5.length)
319857
+ element3.appendChild(this.doc.createTextNode(text5.slice(chunkStart)));
319858
+ }
319859
+ findLastTextRun(runs2) {
319860
+ for (let index2 = runs2.length - 1;index2 >= 0; index2 -= 1) {
319861
+ const run2 = runs2[index2];
319862
+ if (run2 && (run2.kind === "text" || run2.kind === undefined) && "text" in run2)
319863
+ return {
319864
+ run: run2,
319865
+ index: index2
319866
+ };
319867
+ }
319868
+ return null;
319869
+ }
319870
+ appendFormattingParagraphMark(lineEl, line, runs2, leftOffsetPx, availableWidth, hasExplicitPositioning) {
319871
+ if (!this.showFormattingMarks || !this.doc)
319872
+ return;
319873
+ const lastRun = runs2.length > 0 ? runs2[runs2.length - 1] : null;
319874
+ if (lastRun) {
319875
+ const lastRunIndex = runs2.length - 1;
319876
+ if (line.toRun < lastRunIndex)
319877
+ return;
319878
+ if (line.toRun === lastRunIndex && (lastRun.kind === "text" || lastRun.kind === undefined) && "text" in lastRun && line.toChar < lastRun.text.length)
319879
+ return;
319880
+ }
319881
+ const lastTextRun = this.findLastTextRun(runs2);
319882
+ const mark2 = this.doc.createElement("span");
319883
+ mark2.classList.add("superdoc-formatting-paragraph-mark");
319884
+ mark2.setAttribute("aria-hidden", "true");
319885
+ mark2.textContent = "¶";
319886
+ const run2 = lastTextRun?.run;
319887
+ if (run2) {
319888
+ if (run2.fontFamily)
319889
+ mark2.style.fontFamily = toCssFontFamily(run2.fontFamily) ?? run2.fontFamily;
319890
+ if (typeof run2.fontSize === "number")
319891
+ mark2.style.fontSize = `${run2.fontSize}px`;
319892
+ if (run2.bold)
319893
+ mark2.style.fontWeight = "bold";
319894
+ if (run2.italic)
319895
+ mark2.style.fontStyle = "italic";
319896
+ if (run2.letterSpacing != null)
319897
+ mark2.style.letterSpacing = `${run2.letterSpacing}px`;
319898
+ }
319899
+ mark2.style.lineHeight = `${line.lineHeight}px`;
319900
+ const lineWidth = line.naturalWidth ?? line.width ?? 0;
319901
+ const alignmentSlack = Math.max(0, availableWidth - lineWidth);
319902
+ const textAlign = lineEl.style.textAlign;
319903
+ const alignmentOffset = !hasExplicitPositioning && textAlign === "center" ? alignmentSlack / 2 : !hasExplicitPositioning && textAlign === "right" ? alignmentSlack : 0;
319904
+ const visualTextEndOffset = lineEl.dir === "rtl" || lineEl.style.direction === "rtl" ? alignmentOffset : alignmentOffset + lineWidth;
319905
+ mark2.style.left = `${Math.max(0, leftOffsetPx + visualTextEndOffset)}px`;
319906
+ lineEl.appendChild(mark2);
319907
+ }
319908
+ resolveResolvedListParagraphMarkOffset(marker, markerTextWidth, fallbackOffset) {
319909
+ if (typeof fallbackOffset === "number" && Number.isFinite(fallbackOffset) && fallbackOffset > 0)
319910
+ return fallbackOffset;
319911
+ if (!marker || marker.vanish)
319912
+ return fallbackOffset;
319913
+ const paddingLeft = Number.isFinite(marker.firstLinePaddingLeftPx) ? marker.firstLinePaddingLeftPx : 0;
319914
+ const suffixWidth = marker.suffix !== "nothing" && Number.isFinite(marker.suffixWidthPx) ? marker.suffixWidthPx : 0;
319915
+ if (marker.justification === "left")
319916
+ return paddingLeft + (typeof markerTextWidth === "number" && Number.isFinite(markerTextWidth) && markerTextWidth > 0 ? markerTextWidth : 0) + suffixWidth;
319917
+ return paddingLeft + (marker.justification === "center" && Number.isFinite(marker.centerPaddingAdjustPx) ? marker.centerPaddingAdjustPx ?? 0 : 0) + suffixWidth;
319918
+ }
319517
319919
  renderRun(run2, context, trackedConfig) {
319518
319920
  if (this.isImageRun(run2))
319519
319921
  return this.renderImageRun(run2);
@@ -319531,7 +319933,7 @@ function print() { __p += __j.call(arguments, '') }
319531
319933
  const isActiveLink = !!(linkData && !linkData.blocked && linkData.href);
319532
319934
  const elem = isActiveLink ? this.doc.createElement("a") : this.doc.createElement("span");
319533
319935
  const text5 = resolveRunText(run2, context);
319534
- elem.textContent = text5;
319936
+ this.setTextContentWithFormattingSpaceMarks(elem, text5);
319535
319937
  if (linkData?.dataset)
319536
319938
  applyLinkDataset(elem, linkData.dataset);
319537
319939
  if (linkData?.blocked) {
@@ -319890,7 +320292,7 @@ function print() { __p += __j.call(arguments, '') }
319890
320292
  this.applySdtDataset(annotation, run2.sdt);
319891
320293
  return annotation;
319892
320294
  }
319893
- renderLine(block, line, context, availableWidthOverride, lineIndex, skipJustify, preExpandedRuns, resolvedListTextStartPx, indentOffsetOverride) {
320295
+ renderLine(block, line, context, availableWidthOverride, lineIndex, skipJustify, preExpandedRuns, resolvedListTextStartPx, indentOffsetOverride, paragraphMarkLeftOffsetOverride) {
319894
320296
  if (!this.doc)
319895
320297
  throw new Error("DomPainter: document is not available");
319896
320298
  const expandedBlock = {
@@ -320105,25 +320507,27 @@ function print() { __p += __j.call(arguments, '') }
320105
320507
  spaceCount,
320106
320508
  shouldJustify: justifyShouldApply
320107
320509
  });
320510
+ const resolveLineIndentOffset = () => {
320511
+ if (indentOffsetOverride != null)
320512
+ return indentOffsetOverride;
320513
+ const paraIndent = block.attrs?.indent;
320514
+ const indentLeft = paraIndent?.left ?? 0;
320515
+ const firstLine = paraIndent?.firstLine ?? 0;
320516
+ const hanging = paraIndent?.hanging ?? 0;
320517
+ const isFirstLineOfPara = lineIndex === 0 || lineIndex === undefined;
320518
+ const firstLineOffsetForCumX = isFirstLineOfPara ? firstLine - hanging : 0;
320519
+ const wordLayoutValue = block.attrs?.wordLayout;
320520
+ const wordLayout = isMinimalWordLayout$1(wordLayoutValue) ? wordLayoutValue : undefined;
320521
+ const isListParagraph$1 = Boolean(wordLayout?.marker);
320522
+ const fallbackListTextStartPx = typeof wordLayout?.marker?.textStartX === "number" && Number.isFinite(wordLayout.marker.textStartX) ? wordLayout.marker.textStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : undefined;
320523
+ return isListParagraph$1 ? isFirstLineOfPara ? resolvedListTextStartPx ?? fallbackListTextStartPx ?? indentLeft : indentLeft : indentLeft + firstLineOffsetForCumX;
320524
+ };
320525
+ const lineTextStartOffsetPx = paragraphMarkLeftOffsetOverride != null ? paragraphMarkLeftOffsetOverride : resolveLineIndentOffset();
320526
+ const paragraphMarkLeftOffsetPx = lineTextStartOffsetPx;
320108
320527
  if (spacingPerSpace !== 0)
320109
320528
  el.style.wordSpacing = `${spacingPerSpace}px`;
320110
320529
  if (shouldUseSegmentPositioning(hasExplicitPositioning ?? false, Boolean(line.segments), isRtl)) {
320111
- let indentOffset;
320112
- if (indentOffsetOverride != null)
320113
- indentOffset = indentOffsetOverride;
320114
- else {
320115
- const paraIndent = block.attrs?.indent;
320116
- const indentLeft = paraIndent?.left ?? 0;
320117
- const firstLine = paraIndent?.firstLine ?? 0;
320118
- const hanging = paraIndent?.hanging ?? 0;
320119
- const isFirstLineOfPara = lineIndex === 0 || lineIndex === undefined;
320120
- const firstLineOffsetForCumX = isFirstLineOfPara ? firstLine - hanging : 0;
320121
- const wordLayoutValue = block.attrs?.wordLayout;
320122
- const wordLayout = isMinimalWordLayout$1(wordLayoutValue) ? wordLayoutValue : undefined;
320123
- const isListParagraph = Boolean(wordLayout?.marker);
320124
- const fallbackListTextStartPx = typeof wordLayout?.marker?.textStartX === "number" && Number.isFinite(wordLayout.marker.textStartX) ? wordLayout.marker.textStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : undefined;
320125
- indentOffset = isListParagraph ? isFirstLineOfPara ? resolvedListTextStartPx ?? fallbackListTextStartPx ?? indentLeft : indentLeft : indentLeft + firstLineOffsetForCumX;
320126
- }
320530
+ const indentOffset = lineTextStartOffsetPx;
320127
320531
  let cumulativeX = 0;
320128
320532
  const segments = line.segments;
320129
320533
  const segmentsByRun = /* @__PURE__ */ new Map;
@@ -320369,6 +320773,7 @@ function print() { __p += __j.call(arguments, '') }
320369
320773
  });
320370
320774
  closeCurrentWrapper();
320371
320775
  }
320776
+ this.appendFormattingParagraphMark(el, line, expandedBlock.runs, paragraphMarkLeftOffsetPx, availableWidth, hasExplicitPositioning ?? false);
320372
320777
  el.querySelectorAll("a[href]").forEach((anchor) => {
320373
320778
  const pendingTooltip = this.pendingTooltips.get(anchor);
320374
320779
  if (pendingTooltip) {
@@ -322000,7 +322405,8 @@ function print() { __p += __j.call(arguments, '') }
322000
322405
  emitCommentPositionsInViewing: options.layoutEngineOptions?.emitCommentPositionsInViewing,
322001
322406
  enableCommentsInViewing: options.layoutEngineOptions?.enableCommentsInViewing,
322002
322407
  presence: validatedPresence,
322003
- showBookmarks: options.layoutEngineOptions?.showBookmarks ?? false
322408
+ showBookmarks: options.layoutEngineOptions?.showBookmarks ?? false,
322409
+ showFormattingMarks: options.layoutEngineOptions?.showFormattingMarks ?? false
322004
322410
  };
322005
322411
  this.#trackedChangesOverrides = options.layoutEngineOptions?.trackedChanges;
322006
322412
  this.#viewportHost = doc$12.createElement("div");
@@ -323222,6 +323628,47 @@ function print() { __p += __j.call(arguments, '') }
323222
323628
  this.#pendingDocChange = true;
323223
323629
  this.#scheduleRerender();
323224
323630
  }
323631
+ setShowFormattingMarks(showFormattingMarks) {
323632
+ const next2 = !!showFormattingMarks;
323633
+ if (this.#layoutOptions.showFormattingMarks === next2)
323634
+ return;
323635
+ this.#layoutOptions.showFormattingMarks = next2;
323636
+ this.#painterAdapter.setShowFormattingMarks(next2);
323637
+ if (!this.#repaintCurrentLayout()) {
323638
+ this.#pendingDocChange = true;
323639
+ this.#scheduleRerender();
323640
+ }
323641
+ }
323642
+ #repaintCurrentLayout() {
323643
+ const layout = this.#layoutState.layout;
323644
+ if (!layout)
323645
+ return false;
323646
+ const blocks2 = this.#layoutLookupBlocks.length > 0 ? this.#layoutLookupBlocks : this.#layoutState.blocks;
323647
+ const measures = this.#layoutLookupMeasures.length > 0 ? this.#layoutLookupMeasures : this.#layoutState.measures;
323648
+ if (blocks2.length === 0 || blocks2.length !== measures.length)
323649
+ return false;
323650
+ const resolvedLayout = resolveLayout({
323651
+ layout,
323652
+ flowMode: this.#layoutOptions.flowMode ?? "paginated",
323653
+ blocks: blocks2,
323654
+ measures
323655
+ });
323656
+ const isSemanticFlow = this.#layoutOptions.flowMode === "semantic";
323657
+ this.#ensurePainter();
323658
+ if (!isSemanticFlow)
323659
+ this.#painterAdapter.setProviders(this.#headerFooterSession?.headerDecorationProvider, this.#headerFooterSession?.footerDecorationProvider);
323660
+ this.#domIndexObserverManager?.pause();
323661
+ try {
323662
+ this.#painterAdapter.paint({ resolvedLayout }, this.#painterHost);
323663
+ this.#refreshEditorDomAugmentations();
323664
+ } finally {
323665
+ this.#domIndexObserverManager?.resume();
323666
+ }
323667
+ this.#revalidateScrollContainer();
323668
+ this.#updatePermissionOverlay();
323669
+ this.#applyZoom();
323670
+ return true;
323671
+ }
323225
323672
  hitTest(clientX, clientY) {
323226
323673
  const normalized = this.#normalizeClientPoint(clientX, clientY);
323227
323674
  if (!normalized)
@@ -325357,7 +325804,8 @@ function print() { __p += __j.call(arguments, '') }
325357
325804
  headerProvider: this.#headerFooterSession?.headerDecorationProvider,
325358
325805
  footerProvider: this.#headerFooterSession?.footerDecorationProvider,
325359
325806
  ruler: this.#layoutOptions.ruler,
325360
- pageGap: this.#layoutState.layout?.pageGap ?? effectiveGap
325807
+ pageGap: this.#layoutState.layout?.pageGap ?? effectiveGap,
325808
+ showFormattingMarks: this.#layoutOptions.showFormattingMarks ?? false
325361
325809
  });
325362
325810
  const currentZoom = this.#layoutOptions.zoom ?? 1;
325363
325811
  if (currentZoom !== 1)
@@ -327839,11 +328287,11 @@ function print() { __p += __j.call(arguments, '') }
327839
328287
  ];
327840
328288
  });
327841
328289
 
327842
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-D34Mg4v-.es.js
328290
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-C-wMmL5m.es.js
327843
328291
  var MOD_ALIASES, ALT_ALIASES, CTRL_ALIASES, SHIFT_ALIASES, BUILTIN_CONTEXT_MENU_GROUPS, BUILTIN_GROUP_ORDER, RESERVED_PROXY_PROPERTY_NAMES, ALL_TOOLBAR_COMMAND_IDS, EMPTY_ACTIVE_IDS;
327844
- var init_create_super_doc_ui_D34Mg4v_es = __esm(() => {
328292
+ var init_create_super_doc_ui_C_wMmL5m_es = __esm(() => {
327845
328293
  init_SuperConverter_ing_1fvK_es();
327846
- init_create_headless_toolbar_B_1fvPL0_es();
328294
+ init_create_headless_toolbar_CUl2z6Fd_es();
327847
328295
  MOD_ALIASES = new Set([
327848
328296
  "Mod",
327849
328297
  "Meta",
@@ -327885,16 +328333,16 @@ var init_zipper_BxRAi0_5_es = __esm(() => {
327885
328333
 
327886
328334
  // ../../packages/superdoc/dist/super-editor.es.js
327887
328335
  var init_super_editor_es = __esm(() => {
327888
- init_src_DKka36_es();
328336
+ init_src_deKdT_sq_es();
327889
328337
  init_SuperConverter_ing_1fvK_es();
327890
328338
  init_jszip_C49i9kUs_es();
327891
328339
  init_xml_js_CqGKpaft_es();
327892
- init_create_headless_toolbar_B_1fvPL0_es();
328340
+ init_create_headless_toolbar_CUl2z6Fd_es();
327893
328341
  init_constants_DrU4EASo_es();
327894
328342
  init_dist_B8HfvhaK_es();
327895
328343
  init_unified_Dsuw2be5_es();
327896
328344
  init_DocxZipper_CUX64E5K_es();
327897
- init_create_super_doc_ui_D34Mg4v_es();
328345
+ init_create_super_doc_ui_C_wMmL5m_es();
327898
328346
  init_ui_CGB3qmy3_es();
327899
328347
  init_eventemitter3_UwU_CLPU_es();
327900
328348
  init_errors_C_DoKMoN_es();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc-dev/mcp",
3
- "version": "0.3.0-next.60",
3
+ "version": "0.3.0-next.61",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -19,8 +19,8 @@
19
19
  "@types/bun": "^1.3.8",
20
20
  "@types/node": "22.19.2",
21
21
  "typescript": "^5.9.2",
22
- "@superdoc/super-editor": "0.0.1",
23
22
  "@superdoc/document-api": "0.0.1",
23
+ "@superdoc/super-editor": "0.0.1",
24
24
  "superdoc": "1.31.0"
25
25
  },
26
26
  "publishConfig": {