@harbour-enterprises/superdoc 1.3.0-next.4 → 1.3.0-next.5

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.
@@ -36366,7 +36366,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36366
36366
  static getStoredSuperdocVersion(docx) {
36367
36367
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
36368
36368
  }
36369
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.3.0-next.4") {
36369
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.3.0-next.5") {
36370
36370
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
36371
36371
  }
36372
36372
  /**
@@ -62076,7 +62076,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62076
62076
  return false;
62077
62077
  }
62078
62078
  };
62079
- const summaryVersion = "1.3.0-next.4";
62079
+ const summaryVersion = "1.3.0-next.5";
62080
62080
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
62081
62081
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
62082
62082
  function mapAttributes(attrs) {
@@ -64710,7 +64710,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
64710
64710
  * Process collaboration migrations
64711
64711
  */
64712
64712
  processCollaborationMigrations() {
64713
- console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.4");
64713
+ console.debug("[checkVersionMigrations] Current editor version", "1.3.0-next.5");
64714
64714
  if (!this.options.ydoc) return;
64715
64715
  const metaMap = this.options.ydoc.getMap("meta");
64716
64716
  let docVersion = metaMap.get("version");
@@ -87920,6 +87920,19 @@ ${l}
87920
87920
  const effectiveMarks = nodeMarks.length > 0 ? nodeMarks : marksAsAttrs;
87921
87921
  const marks = [...effectiveMarks, ...inheritedMarks ?? []];
87922
87922
  applyMarksToRun(run2, marks, hyperlinkConfig, themeColors);
87923
+ if (marksAsAttrs.length > 0) {
87924
+ run2._explicitFont = true;
87925
+ }
87926
+ console.debug("[token-debug] tokenNodeToRun", {
87927
+ token,
87928
+ fontFamily: run2.fontFamily,
87929
+ fontSize: run2.fontSize,
87930
+ defaultFont,
87931
+ defaultSize,
87932
+ nodeMarksCount: nodeMarks.length,
87933
+ marksAsAttrsCount: marksAsAttrs.length,
87934
+ inheritedMarksCount: inheritedMarks?.length ?? 0
87935
+ });
87923
87936
  return run2;
87924
87937
  }
87925
87938
  const EIGHTHS_PER_POINT = 8;
@@ -91668,6 +91681,10 @@ ${l}
91668
91681
  if (TOKEN_INLINE_TYPES.has(node2.type)) {
91669
91682
  const tokenKind = TOKEN_INLINE_TYPES.get(node2.type);
91670
91683
  if (tokenKind) {
91684
+ const marksAsAttrs = Array.isArray(node2.attrs?.marksAsAttrs) ? node2.attrs.marksAsAttrs : [];
91685
+ const nodeMarks = node2.marks ?? [];
91686
+ const effectiveMarks = nodeMarks.length > 0 ? nodeMarks : marksAsAttrs;
91687
+ const mergedMarks = [...effectiveMarks, ...inheritedMarks ?? []];
91671
91688
  const tokenRun = tokenNodeToRun(
91672
91689
  node2,
91673
91690
  positions,
@@ -91684,6 +91701,23 @@ ${l}
91684
91701
  const inlineStyleId = getInlineStyleId(inheritedMarks);
91685
91702
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
91686
91703
  applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
91704
+ if (mergedMarks.length > 0) {
91705
+ applyMarksToRun(
91706
+ tokenRun,
91707
+ mergedMarks,
91708
+ hyperlinkConfig,
91709
+ themeColors,
91710
+ converterContext?.backgroundColor
91711
+ );
91712
+ }
91713
+ console.debug("[token-debug] paragraph-token-run", {
91714
+ token: tokenRun.token,
91715
+ fontFamily: tokenRun.fontFamily,
91716
+ fontSize: tokenRun.fontSize,
91717
+ inlineStyleId,
91718
+ runStyleId: activeRunStyleId,
91719
+ mergedMarksCount: mergedMarks.length
91720
+ });
91687
91721
  currentRuns.push(tokenRun);
91688
91722
  }
91689
91723
  return;
@@ -94668,6 +94702,77 @@ ${l}
94668
94702
  function isFieldAnnotationRun(run2) {
94669
94703
  return run2.kind === "fieldAnnotation";
94670
94704
  }
94705
+ function measureTabAlignmentGroup(startRunIndex, runs2, ctx2, decimalSeparator = ".") {
94706
+ const result = {
94707
+ totalWidth: 0,
94708
+ runs: [],
94709
+ endRunIndex: runs2.length
94710
+ };
94711
+ let foundDecimal = false;
94712
+ for (let i2 = startRunIndex; i2 < runs2.length; i2++) {
94713
+ const run2 = runs2[i2];
94714
+ if (isTabRun(run2)) {
94715
+ result.endRunIndex = i2;
94716
+ break;
94717
+ }
94718
+ if (isLineBreakRun(run2) || run2.kind === "break" && run2.breakType === "line") {
94719
+ result.endRunIndex = i2;
94720
+ break;
94721
+ }
94722
+ if (run2.kind === "text" || run2.kind === void 0) {
94723
+ const textRun = run2;
94724
+ const text2 = textRun.text || "";
94725
+ if (text2.length > 0) {
94726
+ const { font } = buildFontString(textRun);
94727
+ const width = measureRunWidth(text2, font, ctx2, textRun, 0);
94728
+ let beforeDecimalWidth;
94729
+ if (!foundDecimal) {
94730
+ const decimalIdx = text2.indexOf(decimalSeparator);
94731
+ if (decimalIdx >= 0) {
94732
+ foundDecimal = true;
94733
+ const beforeText = text2.slice(0, decimalIdx);
94734
+ beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, textRun, 0) : 0;
94735
+ result.beforeDecimalWidth = result.totalWidth + beforeDecimalWidth;
94736
+ }
94737
+ }
94738
+ result.runs.push({
94739
+ runIndex: i2,
94740
+ width,
94741
+ text: text2,
94742
+ beforeDecimalWidth
94743
+ });
94744
+ result.totalWidth += width;
94745
+ } else {
94746
+ result.runs.push({ runIndex: i2, width: 0, text: "" });
94747
+ }
94748
+ continue;
94749
+ }
94750
+ if (isImageRun(run2)) {
94751
+ const leftSpace = run2.distLeft ?? 0;
94752
+ const rightSpace = run2.distRight ?? 0;
94753
+ const imageWidth = run2.width + leftSpace + rightSpace;
94754
+ result.runs.push({ runIndex: i2, width: imageWidth });
94755
+ result.totalWidth += imageWidth;
94756
+ continue;
94757
+ }
94758
+ if (isFieldAnnotationRun(run2)) {
94759
+ const fontSize2 = run2.fontSize ?? DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
94760
+ const { font } = buildFontString({
94761
+ fontFamily: run2.fontFamily ?? "Arial",
94762
+ fontSize: fontSize2,
94763
+ bold: run2.bold,
94764
+ italic: run2.italic
94765
+ });
94766
+ const textWidth = run2.displayLabel ? measureRunWidth(run2.displayLabel, font, ctx2, run2, 0) : 0;
94767
+ const pillWidth = textWidth + FIELD_ANNOTATION_PILL_PADDING;
94768
+ result.runs.push({ runIndex: i2, width: pillWidth });
94769
+ result.totalWidth += pillWidth;
94770
+ continue;
94771
+ }
94772
+ result.runs.push({ runIndex: i2, width: 0 });
94773
+ }
94774
+ return result;
94775
+ }
94671
94776
  async function measureBlock(block, constraints) {
94672
94777
  const normalized = normalizeConstraints(constraints);
94673
94778
  if (block.kind === "drawing") {
@@ -94791,6 +94896,7 @@ ${l}
94791
94896
  let pendingTabAlignment = null;
94792
94897
  let lastAppliedTabAlign = null;
94793
94898
  const warnedTabVals = /* @__PURE__ */ new Set();
94899
+ let activeTabGroup = null;
94794
94900
  const validateTabStopVal = (stop) => {
94795
94901
  if (!ALLOWED_TAB_VALS.has(stop.val) && !warnedTabVals.has(stop.val)) {
94796
94902
  warnedTabVals.add(stop.val);
@@ -94970,6 +95076,7 @@ ${l}
94970
95076
  continue;
94971
95077
  }
94972
95078
  if (isTabRun(run2)) {
95079
+ activeTabGroup = null;
94973
95080
  if (!currentLine) {
94974
95081
  currentLine = {
94975
95082
  fromRun: runIndex,
@@ -94994,12 +95101,6 @@ ${l}
94994
95101
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, 12);
94995
95102
  currentLine.toRun = runIndex;
94996
95103
  currentLine.toChar = 1;
94997
- if (stop) {
94998
- validateTabStopVal(stop);
94999
- pendingTabAlignment = { target: clampedTarget, val: stop.val };
95000
- } else {
95001
- pendingTabAlignment = null;
95002
- }
95003
95104
  if (stop && stop.leader && stop.leader !== "none") {
95004
95105
  const leaderStyle = stop.leader;
95005
95106
  const from2 = Math.min(originX, clampedTarget);
@@ -95007,6 +95108,36 @@ ${l}
95007
95108
  if (!currentLine.leaders) currentLine.leaders = [];
95008
95109
  currentLine.leaders.push({ from: from2, to, style: leaderStyle });
95009
95110
  }
95111
+ if (stop) {
95112
+ validateTabStopVal(stop);
95113
+ if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
95114
+ const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx2, decimalSeparator);
95115
+ if (groupMeasure.totalWidth > 0) {
95116
+ let groupStartX;
95117
+ if (stop.val === "end") {
95118
+ groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth);
95119
+ } else if (stop.val === "center") {
95120
+ groupStartX = Math.max(0, clampedTarget - groupMeasure.totalWidth / 2);
95121
+ } else {
95122
+ const beforeDecimal = groupMeasure.beforeDecimalWidth ?? groupMeasure.totalWidth;
95123
+ groupStartX = Math.max(0, clampedTarget - beforeDecimal);
95124
+ }
95125
+ activeTabGroup = {
95126
+ measure: groupMeasure,
95127
+ startX: groupStartX,
95128
+ currentX: groupStartX,
95129
+ target: clampedTarget,
95130
+ val: stop.val
95131
+ };
95132
+ currentLine.width = roundValue(groupStartX);
95133
+ }
95134
+ pendingTabAlignment = null;
95135
+ } else {
95136
+ pendingTabAlignment = { target: clampedTarget, val: stop.val };
95137
+ }
95138
+ } else {
95139
+ pendingTabAlignment = null;
95140
+ }
95010
95141
  continue;
95011
95142
  }
95012
95143
  if (isImageRun(run2)) {
@@ -95017,7 +95148,10 @@ ${l}
95017
95148
  const bottomSpace = run2.distBottom ?? 0;
95018
95149
  const imageHeight = run2.height + topSpace + bottomSpace;
95019
95150
  let imageStartX;
95020
- if (pendingTabAlignment && currentLine) {
95151
+ if (activeTabGroup && currentLine) {
95152
+ imageStartX = activeTabGroup.currentX;
95153
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + imageWidth);
95154
+ } else if (pendingTabAlignment && currentLine) {
95021
95155
  imageStartX = alignPendingTabForWidth(imageWidth);
95022
95156
  }
95023
95157
  if (!currentLine) {
@@ -95042,10 +95176,14 @@ ${l}
95042
95176
  }
95043
95177
  ]
95044
95178
  };
95179
+ if (activeTabGroup && runIndex + 1 >= activeTabGroup.measure.endRunIndex) {
95180
+ activeTabGroup = null;
95181
+ }
95045
95182
  continue;
95046
95183
  }
95047
95184
  const appliedTabAlign = lastAppliedTabAlign;
95048
- if (currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
95185
+ const skipFitCheck = activeTabGroup !== null;
95186
+ if (!skipFitCheck && currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
95049
95187
  trimTrailingWrapSpaces(currentLine);
95050
95188
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
95051
95189
  const lineBase = currentLine;
@@ -95058,6 +95196,7 @@ ${l}
95058
95196
  tabStopCursor = 0;
95059
95197
  pendingTabAlignment = null;
95060
95198
  lastAppliedTabAlign = null;
95199
+ activeTabGroup = null;
95061
95200
  currentLine = {
95062
95201
  fromRun: runIndex,
95063
95202
  fromChar: 0,
@@ -95090,6 +95229,9 @@ ${l}
95090
95229
  ...imageStartX !== void 0 ? { x: imageStartX } : {}
95091
95230
  });
95092
95231
  }
95232
+ if (activeTabGroup && runIndex + 1 >= activeTabGroup.measure.endRunIndex) {
95233
+ activeTabGroup = null;
95234
+ }
95093
95235
  const tabAlign = appliedTabAlign;
95094
95236
  if (tabAlign && currentLine && tabAlign.val === "end") {
95095
95237
  currentLine.width = roundValue(tabAlign.target);
@@ -95265,7 +95407,11 @@ ${l}
95265
95407
  }
95266
95408
  }
95267
95409
  let segmentStartX;
95268
- if (currentLine && pendingTabAlignment) {
95410
+ let inActiveTabGroup = false;
95411
+ if (activeTabGroup && currentLine) {
95412
+ segmentStartX = activeTabGroup.currentX;
95413
+ inActiveTabGroup = true;
95414
+ } else if (currentLine && pendingTabAlignment) {
95269
95415
  segmentStartX = alignSegmentAtTab(segment, font, run2, charPosInRun);
95270
95416
  if (segmentStartX == null) {
95271
95417
  segmentStartX = currentLine.width;
@@ -95302,6 +95448,7 @@ ${l}
95302
95448
  tabStopCursor = 0;
95303
95449
  pendingTabAlignment = null;
95304
95450
  lastAppliedTabAlign = null;
95451
+ activeTabGroup = null;
95305
95452
  currentLine = {
95306
95453
  fromRun: runIndex,
95307
95454
  fromChar: spaceStartChar,
@@ -95320,7 +95467,19 @@ ${l}
95320
95467
  currentLine.width = roundValue(currentLine.width + boundarySpacing2 + singleSpaceWidth);
95321
95468
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
95322
95469
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
95323
- appendSegment(currentLine.segments, runIndex, spaceStartChar, spaceEndChar, singleSpaceWidth);
95470
+ let spaceExplicitX;
95471
+ if (inActiveTabGroup && activeTabGroup) {
95472
+ spaceExplicitX = activeTabGroup.currentX;
95473
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + singleSpaceWidth);
95474
+ }
95475
+ appendSegment(
95476
+ currentLine.segments,
95477
+ runIndex,
95478
+ spaceStartChar,
95479
+ spaceEndChar,
95480
+ singleSpaceWidth,
95481
+ spaceExplicitX
95482
+ );
95324
95483
  currentLine.spaceCount += 1;
95325
95484
  }
95326
95485
  }
@@ -95468,7 +95627,7 @@ ${l}
95468
95627
  const totalWidthWithWord = currentLine.width + boundarySpacing + wordCommitWidth + // Safe cast: only TextRuns produce word segments from split(), other run types are handled earlier
95469
95628
  (shouldIncludeDelimiterSpace ? run2.letterSpacing ?? 0 : 0);
95470
95629
  const availableWidth = currentLine.maxWidth - WIDTH_FUDGE_PX2;
95471
- let shouldBreak = currentLine.width + boundarySpacing + wordOnlyWidth > availableWidth && currentLine.width > 0 && !isTocEntry;
95630
+ let shouldBreak = !inActiveTabGroup && currentLine.width + boundarySpacing + wordOnlyWidth > availableWidth && currentLine.width > 0 && !isTocEntry;
95472
95631
  let compressedWidth = null;
95473
95632
  if (shouldBreak && justifyAlignment) {
95474
95633
  const isLastNonEmptyWordInSegment = wordIndex === lastNonEmptyWordIndex;
@@ -95533,15 +95692,14 @@ ${l}
95533
95692
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
95534
95693
  currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
95535
95694
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
95536
- const useExplicitXHere = wordIndex === 0 && segmentStartX !== void 0;
95537
- appendSegment(
95538
- currentLine.segments,
95539
- runIndex,
95540
- wordStartChar,
95541
- wordEndNoSpace,
95542
- wordOnlyWidth,
95543
- useExplicitXHere ? segmentStartX : void 0
95544
- );
95695
+ let explicitXHere;
95696
+ if (inActiveTabGroup && activeTabGroup) {
95697
+ explicitXHere = activeTabGroup.currentX;
95698
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + wordOnlyWidth);
95699
+ } else if (wordIndex === 0 && segmentStartX !== void 0) {
95700
+ explicitXHere = segmentStartX;
95701
+ }
95702
+ appendSegment(currentLine.segments, runIndex, wordStartChar, wordEndNoSpace, wordOnlyWidth, explicitXHere);
95545
95703
  trimTrailingWrapSpaces(currentLine);
95546
95704
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
95547
95705
  const lineBase = currentLine;
@@ -95556,8 +95714,13 @@ ${l}
95556
95714
  }
95557
95715
  const newToChar = shouldIncludeDelimiterSpace ? wordEndWithSpace : wordEndNoSpace;
95558
95716
  currentLine.toChar = newToChar;
95559
- const useExplicitX = wordIndex === 0 && segmentStartX !== void 0;
95560
- const explicitX = useExplicitX ? segmentStartX : void 0;
95717
+ let explicitX;
95718
+ if (inActiveTabGroup && activeTabGroup) {
95719
+ explicitX = activeTabGroup.currentX;
95720
+ activeTabGroup.currentX = roundValue(activeTabGroup.currentX + wordCommitWidth);
95721
+ } else if (wordIndex === 0 && segmentStartX !== void 0) {
95722
+ explicitX = segmentStartX;
95723
+ }
95561
95724
  const targetWidth = compressedWidth != null ? compressedWidth : currentLine.width + boundarySpacing + wordCommitWidth + (shouldIncludeDelimiterSpace ? run2.letterSpacing ?? 0 : 0);
95562
95725
  if (compressedWidth != null) {
95563
95726
  currentLine.naturalWidth = roundValue(totalWidthWithWord);
@@ -95579,6 +95742,12 @@ ${l}
95579
95742
  }
95580
95743
  }
95581
95744
  lastAppliedTabAlign = null;
95745
+ if (activeTabGroup && runIndex + 1 >= activeTabGroup.measure.endRunIndex) {
95746
+ if (currentLine && activeTabGroup.val === "end") {
95747
+ currentLine.width = roundValue(activeTabGroup.target);
95748
+ }
95749
+ activeTabGroup = null;
95750
+ }
95582
95751
  if (!isLastSegment) {
95583
95752
  pendingTabAlignment = null;
95584
95753
  if (!currentLine) {
@@ -143695,7 +143864,7 @@ ${reason}`);
143695
143864
  this.config.colors = shuffleArray(this.config.colors);
143696
143865
  this.userColorMap = /* @__PURE__ */ new Map();
143697
143866
  this.colorIndex = 0;
143698
- this.version = "1.3.0-next.4";
143867
+ this.version = "1.3.0-next.5";
143699
143868
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
143700
143869
  this.superdocId = config2.superdocId || v4();
143701
143870
  this.colors = this.config.colors;