@scrider/formatter 1.8.0 → 1.8.2

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.
package/dist/index.js CHANGED
@@ -199,7 +199,7 @@ var BlockHandlerRegistry = class {
199
199
  };
200
200
 
201
201
  // src/schema/blocks/table.ts
202
- import { Delta as Delta2 } from "@scrider/delta";
202
+ import { Delta as Delta2, isInsert as isInsert2, isTextInsert } from "@scrider/delta";
203
203
 
204
204
  // src/conversion/sanitize.ts
205
205
  import { Delta, isInsert, isRetain, isEmbedInsert, deepClone } from "@scrider/delta";
@@ -362,6 +362,13 @@ function isTextNode(node) {
362
362
  }
363
363
 
364
364
  // src/schema/blocks/table.ts
365
+ var VALID_CELL_HORIZONTAL_ALIGNS = [
366
+ "left",
367
+ "center",
368
+ "right",
369
+ "justify"
370
+ ];
371
+ var VALID_CELL_VERTICAL_ALIGNS = ["top", "middle", "bottom"];
365
372
  var CELL_KEY_RE = /^(\d+):(\d+)$/;
366
373
  function parseCellKey(key) {
367
374
  const match = CELL_KEY_RE.exec(key);
@@ -382,7 +389,22 @@ function getGridDimensions(cells) {
382
389
  return [maxRow + 1, maxCol + 1];
383
390
  }
384
391
  function isValidCellData(cell) {
385
- return typeof cell === "object" && cell !== null && Array.isArray(cell.ops) && cell.ops.length > 0 && (cell.colspan === void 0 || Number.isInteger(cell.colspan) && cell.colspan >= 1) && (cell.rowspan === void 0 || Number.isInteger(cell.rowspan) && cell.rowspan >= 1);
392
+ if (typeof cell !== "object" || cell === null || !Array.isArray(cell.ops) || cell.ops.length === 0) {
393
+ return false;
394
+ }
395
+ if (cell.colspan !== void 0 && (!Number.isInteger(cell.colspan) || cell.colspan < 1)) {
396
+ return false;
397
+ }
398
+ if (cell.rowspan !== void 0 && (!Number.isInteger(cell.rowspan) || cell.rowspan < 1)) {
399
+ return false;
400
+ }
401
+ if (cell.align !== void 0 && !VALID_CELL_HORIZONTAL_ALIGNS.includes(cell.align)) {
402
+ return false;
403
+ }
404
+ if (cell.vAlign !== void 0 && !VALID_CELL_VERTICAL_ALIGNS.includes(cell.vAlign)) {
405
+ return false;
406
+ }
407
+ return true;
386
408
  }
387
409
  function validateMergedCells(cells, rows, cols) {
388
410
  const covered = /* @__PURE__ */ new Set();
@@ -412,6 +434,38 @@ function validateMergedCells(cells, rows, cols) {
412
434
  }
413
435
  return true;
414
436
  }
437
+ function parseHorizontalAlign(value) {
438
+ const normalized = value?.trim().toLowerCase();
439
+ if (normalized === "left" || normalized === "center" || normalized === "right") {
440
+ return normalized;
441
+ }
442
+ if (normalized === "justify") return "justify";
443
+ return null;
444
+ }
445
+ function resolveCellHorizontalAlign(cell, col, colAligns) {
446
+ if (cell.align !== void 0) return cell.align;
447
+ const colAlign = colAligns?.[col];
448
+ if (colAlign) return colAlign;
449
+ return "left";
450
+ }
451
+ function promoteAlignFromCellOps(cell) {
452
+ if (cell.align !== void 0) return cell;
453
+ for (let i = cell.ops.length - 1; i >= 0; i--) {
454
+ const op = cell.ops[i];
455
+ if (!op || !isInsert2(op) || !isTextInsert(op) || !op.insert.includes("\n")) continue;
456
+ const align = op.attributes?.align;
457
+ const parsed = typeof align === "string" ? parseHorizontalAlign(align) : null;
458
+ if (!parsed) continue;
459
+ const ops = cell.ops.map((item, idx) => {
460
+ if (idx !== i || !isInsert2(item) || item.attributes == null) return item;
461
+ const rest = { ...item.attributes };
462
+ delete rest.align;
463
+ return Object.keys(rest).length > 0 ? { insert: item.insert, attributes: rest } : { insert: item.insert };
464
+ });
465
+ return { ...cell, ops, align: parsed };
466
+ }
467
+ return cell;
468
+ }
415
469
  function renderExtendedRow(data, row, cols, defaultCellTag, context, pretty) {
416
470
  const nl = pretty ? "\n" : "";
417
471
  const ind = (level) => pretty ? " ".repeat(level) : "";
@@ -429,11 +483,16 @@ function renderExtendedRow(data, row, cols, defaultCellTag, context, pretty) {
429
483
  if (cell.rowspan && cell.rowspan > 1) {
430
484
  attrs.push(`rowspan="${cell.rowspan}"`);
431
485
  }
432
- if (data.colAligns) {
433
- const align = data.colAligns[c];
434
- if (align && align !== "left") {
435
- attrs.push(`style="text-align: ${align}"`);
436
- }
486
+ const colDefault = data.colAligns?.[c] ?? "left";
487
+ const effectiveAlign = resolveCellHorizontalAlign(cell, c, data.colAligns);
488
+ let alignStyle = null;
489
+ if (effectiveAlign !== "left") {
490
+ alignStyle = `text-align: ${effectiveAlign}`;
491
+ } else if (cell.align === "left" && colDefault !== "left") {
492
+ alignStyle = "text-align: left";
493
+ }
494
+ if (alignStyle) {
495
+ attrs.push(`style="${alignStyle}"`);
437
496
  }
438
497
  const attrStr = attrs.length > 0 ? " " + attrs.join(" ") : "";
439
498
  let content = "";
@@ -449,6 +508,9 @@ function isGfmCompatible(data) {
449
508
  if (data.colWidths && data.colWidths.some((w) => w > 0)) {
450
509
  return false;
451
510
  }
511
+ for (const cell of Object.values(data.cells)) {
512
+ if (cell !== null && cell.align !== void 0) return false;
513
+ }
452
514
  for (const cell of Object.values(data.cells)) {
453
515
  if (cell === null) return false;
454
516
  if (cell.colspan && cell.colspan > 1) return false;
@@ -559,14 +621,28 @@ function extractColWidths(table) {
559
621
  return void 0;
560
622
  }
561
623
  function extractCellAlign(cell) {
562
- const textAlign = cell.style?.textAlign || cell.style?.getPropertyValue?.("text-align");
563
- if (textAlign === "left" || textAlign === "center" || textAlign === "right") {
564
- return textAlign;
624
+ const direct = extractInlineHorizontalAlign(cell);
625
+ if (direct) return direct;
626
+ const children = cell.childNodes;
627
+ for (let i = 0; i < children.length; i++) {
628
+ const child = children[i];
629
+ if (!child || !isElement(child)) continue;
630
+ const tag = child.tagName.toLowerCase();
631
+ if (tag === "p" || tag === "div") {
632
+ const align = extractInlineHorizontalAlign(child);
633
+ if (align) return align;
634
+ }
565
635
  }
566
- const style = cell.getAttribute("style") || "";
567
- const match = style.match(/text-align:\s*(left|center|right)/);
636
+ return null;
637
+ }
638
+ function extractInlineHorizontalAlign(element) {
639
+ const textAlign = element.style?.textAlign || element.style?.getPropertyValue?.("text-align");
640
+ const fromStyle = parseHorizontalAlign(textAlign);
641
+ if (fromStyle) return fromStyle;
642
+ const style = element.getAttribute("style") || "";
643
+ const match = style.match(/text-align:\s*(left|center|right|justify)/i);
568
644
  if (match?.[1]) {
569
- return match[1];
645
+ return parseHorizontalAlign(match[1]);
570
646
  }
571
647
  return null;
572
648
  }
@@ -575,6 +651,7 @@ function parseTableElement(table, context) {
575
651
  if (rows.length === 0) return null;
576
652
  const cells = {};
577
653
  const colAligns = [];
654
+ const rawAligns = {};
578
655
  let maxCol = 0;
579
656
  let firstRowProcessed = false;
580
657
  const occupied = /* @__PURE__ */ new Set();
@@ -603,10 +680,20 @@ function parseTableElement(table, context) {
603
680
  } else {
604
681
  ops = [{ insert: "\n" }];
605
682
  }
606
- const cellData = { ops };
683
+ let cellData = { ops };
607
684
  if (colspan > 1) cellData.colspan = colspan;
608
685
  if (rowspan > 1) cellData.rowspan = rowspan;
609
- cells[`${rowIdx}:${colIdx}`] = cellData;
686
+ cellData = promoteAlignFromCellOps(cellData);
687
+ const htmlAlign = extractCellAlign(cell);
688
+ const effectiveAlign = htmlAlign ?? cellData.align ?? "left";
689
+ if (cellData.align !== void 0) {
690
+ const withoutAlign = { ...cellData };
691
+ delete withoutAlign.align;
692
+ cellData = withoutAlign;
693
+ }
694
+ const cellKey = `${rowIdx}:${colIdx}`;
695
+ cells[cellKey] = cellData;
696
+ rawAligns[cellKey] = effectiveAlign;
610
697
  for (let dr = 0; dr < rowspan; dr++) {
611
698
  for (let dc = 0; dc < colspan; dc++) {
612
699
  if (dr === 0 && dc === 0) continue;
@@ -620,8 +707,9 @@ function parseTableElement(table, context) {
620
707
  }
621
708
  if (!firstRowProcessed) {
622
709
  const align = extractCellAlign(cell);
710
+ const colAlign = align === "center" || align === "right" ? align : null;
623
711
  for (let dc = 0; dc < colspan; dc++) {
624
- colAligns.push(align);
712
+ colAligns.push(colAlign);
625
713
  }
626
714
  }
627
715
  const cellEndCol = colIdx + colspan - 1;
@@ -662,6 +750,18 @@ function parseTableElement(table, context) {
662
750
  if (colAligns.length > totalCols) colAligns.length = totalCols;
663
751
  result.colAligns = colAligns;
664
752
  }
753
+ for (let r = 0; r < totalRows; r++) {
754
+ for (let c = 0; c < totalCols; c++) {
755
+ const key = `${r}:${c}`;
756
+ const cell = result.cells[key];
757
+ if (cell == null) continue;
758
+ const colDefault = result.colAligns?.[c] ?? "left";
759
+ const effective = rawAligns[key] ?? "left";
760
+ if (effective !== colDefault) {
761
+ result.cells[key] = { ...cell, align: effective };
762
+ }
763
+ }
764
+ }
665
765
  return result;
666
766
  }
667
767
  var tableBlockHandler = {
@@ -773,8 +873,11 @@ var tableBlockHandler = {
773
873
  for (const [key, cell] of Object.entries(data.cells)) {
774
874
  if (cell !== null) {
775
875
  const normalized = normalizeDelta(new Delta2(cell.ops), registry);
776
- if (normalized.ops !== cell.ops) {
777
- newCells[key] = { ...cell, ops: normalized.ops };
876
+ const promoted = promoteAlignFromCellOps(
877
+ normalized.ops !== cell.ops ? { ...cell, ops: normalized.ops } : cell
878
+ );
879
+ if (promoted.ops !== cell.ops || promoted.align !== cell.align) {
880
+ newCells[key] = promoted;
778
881
  changed = true;
779
882
  } else {
780
883
  newCells[key] = cell;
@@ -810,7 +913,7 @@ var tableBlockHandler = {
810
913
  };
811
914
 
812
915
  // src/schema/blocks/footnotes.ts
813
- import { isTextInsert, Delta as Delta3 } from "@scrider/delta";
916
+ import { isTextInsert as isTextInsert2, Delta as Delta3 } from "@scrider/delta";
814
917
  function isValidNoteData(note) {
815
918
  return typeof note === "object" && note !== null && Array.isArray(note.ops) && note.ops.length > 0;
816
919
  }
@@ -895,11 +998,11 @@ var footnotesBlockHandler = {
895
998
  if (context.parseElement) {
896
999
  ops = context.parseElement(li);
897
1000
  ops = ops.map((op) => {
898
- if (isTextInsert(op) && op.insert.includes("\u21A9")) {
1001
+ if (isTextInsert2(op) && op.insert.includes("\u21A9")) {
899
1002
  return { ...op, insert: op.insert.replace(/\u21a9/g, "") };
900
1003
  }
901
1004
  return op;
902
- }).filter((op) => !isTextInsert(op) || op.insert !== "");
1005
+ }).filter((op) => !isTextInsert2(op) || op.insert !== "");
903
1006
  if (ops.length === 0) {
904
1007
  ops = [{ insert: "\n" }];
905
1008
  }
@@ -2652,7 +2755,7 @@ function isAdapterAvailable() {
2652
2755
  }
2653
2756
 
2654
2757
  // src/conversion/html/delta-to-html.ts
2655
- import { Delta as Delta7, isInsert as isInsert2, isEmbedInsert as isEmbedInsert2 } from "@scrider/delta";
2758
+ import { Delta as Delta7, isInsert as isInsert4, isEmbedInsert as isEmbedInsert2 } from "@scrider/delta";
2656
2759
 
2657
2760
  // src/conversion/utils/slugify.ts
2658
2761
  function slugify(text) {
@@ -2875,6 +2978,97 @@ function buildTableCellStyleAttr(params) {
2875
2978
  return ` style="${parts.join("; ")}"`;
2876
2979
  }
2877
2980
 
2981
+ // src/conversion/markdown/table-region.ts
2982
+ import { isInsert as isInsert3, isTextInsert as isTextInsert3 } from "@scrider/delta";
2983
+ function isTableNewlineOp(op) {
2984
+ if (!op || !isInsert3(op) || !isTextInsert3(op)) return false;
2985
+ if (!op.insert.includes("\n")) return false;
2986
+ return !!op.attributes && "table-row" in op.attributes;
2987
+ }
2988
+ function tableCellCoordsFromAttributes(attrs) {
2989
+ if (!attrs || typeof attrs["table-row"] !== "number" || typeof attrs["table-col"] !== "number") {
2990
+ return null;
2991
+ }
2992
+ return { row: attrs["table-row"], col: attrs["table-col"] };
2993
+ }
2994
+ function tableCellCoordsFromOp(op) {
2995
+ if (!isTableNewlineOp(op) || !isTextInsert3(op)) return null;
2996
+ return tableCellCoordsFromAttributes(op.attributes);
2997
+ }
2998
+ function isAdjacentSimpleTableGridBoundary(prev, next) {
2999
+ if (next.row < prev.row) return true;
3000
+ if (next.row === 0 && prev.row === 0 && next.col === 0 && prev.col > 0) return true;
3001
+ return false;
3002
+ }
3003
+ function collectAdjacentTableLines(lines, startIndex) {
3004
+ const result = [];
3005
+ let prevCoords = null;
3006
+ for (let i = startIndex; i < lines.length; i++) {
3007
+ const line = lines[i];
3008
+ if (line === void 0) break;
3009
+ const coords = tableCellCoordsFromAttributes(line.attributes);
3010
+ if (!coords) break;
3011
+ if (prevCoords && isAdjacentSimpleTableGridBoundary(prevCoords, coords)) break;
3012
+ result.push(line);
3013
+ prevCoords = coords;
3014
+ }
3015
+ return result;
3016
+ }
3017
+ function extractTableRegion(ops, hintOpIdx) {
3018
+ if (hintOpIdx < 0 || hintOpIdx >= ops.length) return null;
3019
+ let probeIdx = -1;
3020
+ for (let i = hintOpIdx; i < ops.length; i++) {
3021
+ const op = ops[i];
3022
+ if (!op || !isInsert3(op)) continue;
3023
+ if (isTextInsert3(op) && op.insert.includes("\n")) {
3024
+ probeIdx = i;
3025
+ break;
3026
+ }
3027
+ }
3028
+ if (probeIdx < 0) return null;
3029
+ if (!isTableNewlineOp(ops[probeIdx])) return null;
3030
+ const probeCoords = tableCellCoordsFromOp(ops[probeIdx]);
3031
+ if (!probeCoords) return null;
3032
+ let endOpIdx = probeIdx;
3033
+ let prevCoords = probeCoords;
3034
+ for (let i = probeIdx + 1; i < ops.length; i++) {
3035
+ const op = ops[i];
3036
+ if (!op || !isInsert3(op)) break;
3037
+ if (!isTextInsert3(op) || !op.insert.includes("\n")) continue;
3038
+ if (isTableNewlineOp(op)) {
3039
+ const coords = tableCellCoordsFromOp(op);
3040
+ if (isAdjacentSimpleTableGridBoundary(prevCoords, coords)) break;
3041
+ prevCoords = coords;
3042
+ endOpIdx = i;
3043
+ } else {
3044
+ break;
3045
+ }
3046
+ }
3047
+ let startOpIdx = 0;
3048
+ let nextCoords = probeCoords;
3049
+ for (let i = probeIdx - 1; i >= 0; i--) {
3050
+ const op = ops[i];
3051
+ if (!op || !isInsert3(op)) {
3052
+ startOpIdx = i + 1;
3053
+ break;
3054
+ }
3055
+ if (!isTextInsert3(op) || !op.insert.includes("\n")) continue;
3056
+ if (isTableNewlineOp(op)) {
3057
+ const coords = tableCellCoordsFromOp(op);
3058
+ if (isAdjacentSimpleTableGridBoundary(coords, nextCoords)) {
3059
+ startOpIdx = i + 1;
3060
+ break;
3061
+ }
3062
+ nextCoords = coords;
3063
+ } else {
3064
+ startOpIdx = i + 1;
3065
+ break;
3066
+ }
3067
+ }
3068
+ const regionOps = ops.slice(startOpIdx, endOpIdx + 1);
3069
+ return { startOpIdx, endOpIdx, ops: regionOps };
3070
+ }
3071
+
2878
3072
  // src/conversion/html/delta-to-html.ts
2879
3073
  function deltaToHtml(delta, options = {}) {
2880
3074
  const lines = splitIntoLines(delta);
@@ -2895,7 +3089,7 @@ function deltaToHtml(delta, options = {}) {
2895
3089
  html += closeAllLists(listStack, pretty);
2896
3090
  listStack = [];
2897
3091
  counters = [];
2898
- const tableLines = collectTableLines(lines, i);
3092
+ const tableLines = collectAdjacentTableLines(lines, i);
2899
3093
  html += renderTable(tableLines, embedRenderers, pretty, blockHandlers, options);
2900
3094
  i += tableLines.length - 1;
2901
3095
  continue;
@@ -3004,7 +3198,7 @@ function splitIntoLines(delta) {
3004
3198
  const lines = [];
3005
3199
  let currentOps = [];
3006
3200
  for (const op of delta.ops) {
3007
- if (!isInsert2(op)) continue;
3201
+ if (!isInsert4(op)) continue;
3008
3202
  if (isEmbedInsert2(op)) {
3009
3203
  currentOps.push(op);
3010
3204
  continue;
@@ -3053,15 +3247,6 @@ function isBlockLevelEmbedLine(line) {
3053
3247
  function isTableLine(line) {
3054
3248
  return line.attributes != null && typeof line.attributes["table-row"] === "number" && typeof line.attributes["table-col"] === "number";
3055
3249
  }
3056
- function collectTableLines(lines, startIndex) {
3057
- const result = [];
3058
- for (let i = startIndex; i < lines.length; i++) {
3059
- const line = lines[i];
3060
- if (!line || !isTableLine(line)) break;
3061
- result.push(line);
3062
- }
3063
- return result;
3064
- }
3065
3250
  function renderTable(tableLines, embedRenderers, pretty, blockHandlers, options) {
3066
3251
  const rows = /* @__PURE__ */ new Map();
3067
3252
  for (const line of tableLines) {
@@ -3332,7 +3517,7 @@ function getBlockStyleAttribute(tag, attributes, resolvedDocumentPresentation) {
3332
3517
  function extractPlainText(ops) {
3333
3518
  let text = "";
3334
3519
  for (const op of ops) {
3335
- if (isInsert2(op) && typeof op.insert === "string") {
3520
+ if (isInsert4(op) && typeof op.insert === "string") {
3336
3521
  text += op.insert;
3337
3522
  }
3338
3523
  }
@@ -3341,7 +3526,7 @@ function extractPlainText(ops) {
3341
3526
  function renderLineContent(ops, embedRenderers, blockHandlers, options) {
3342
3527
  let html = "";
3343
3528
  for (const op of ops) {
3344
- if (!isInsert2(op)) continue;
3529
+ if (!isInsert4(op)) continue;
3345
3530
  if (isEmbedInsert2(op)) {
3346
3531
  html += renderEmbed(
3347
3532
  op.insert,
@@ -4139,7 +4324,7 @@ var DEFAULT_TAG_HANDLERS = {
4139
4324
  };
4140
4325
 
4141
4326
  // src/conversion/markdown/delta-to-markdown.ts
4142
- import { Delta as Delta9, isInsert as isInsert3, isTextInsert as isTextInsert2, isEmbedInsert as isEmbedInsert3 } from "@scrider/delta";
4327
+ import { Delta as Delta9, isInsert as isInsert5, isTextInsert as isTextInsert4, isEmbedInsert as isEmbedInsert3 } from "@scrider/delta";
4143
4328
 
4144
4329
  // src/conversion/markdown/config.ts
4145
4330
  var MARKDOWN_ESCAPE_CHARS = /[\\`*_[\]<>#]/g;
@@ -4227,7 +4412,7 @@ function deltaToMarkdown(delta, options = {}) {
4227
4412
  const attrs = line.attributes;
4228
4413
  const isBlockquote = !!attrs.blockquote;
4229
4414
  if (typeof attrs["table-row"] === "number" && typeof attrs["table-col"] === "number") {
4230
- const tableLines = collectTableLines2(lines, i);
4415
+ const tableLines = collectAdjacentTableLines(lines, i);
4231
4416
  result.push(
4232
4417
  renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4233
4418
  );
@@ -4332,9 +4517,9 @@ function splitIntoLines2(ops) {
4332
4517
  const lines = [];
4333
4518
  let currentOps = [];
4334
4519
  for (const op of ops) {
4335
- if (!isInsert3(op)) continue;
4520
+ if (!isInsert5(op)) continue;
4336
4521
  const opAttrs = op.attributes ?? {};
4337
- if (isTextInsert2(op)) {
4522
+ if (isTextInsert4(op)) {
4338
4523
  const text = op.insert;
4339
4524
  const parts = text.split("\n");
4340
4525
  for (let i = 0; i < parts.length; i++) {
@@ -4399,17 +4584,6 @@ function collectCodeBlock(lines, startIndex) {
4399
4584
  }
4400
4585
  return codeLines;
4401
4586
  }
4402
- function collectTableLines2(lines, startIndex) {
4403
- const result = [];
4404
- for (let i = startIndex; i < lines.length; i++) {
4405
- const line = lines[i];
4406
- if (!line || typeof line.attributes["table-row"] !== "number" || typeof line.attributes["table-col"] !== "number") {
4407
- break;
4408
- }
4409
- result.push(line);
4410
- }
4411
- return result;
4412
- }
4413
4587
  function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces") {
4414
4588
  const rows = /* @__PURE__ */ new Map();
4415
4589
  for (const line of tableLines) {
@@ -4545,7 +4719,7 @@ function renderLineContent2(ops, embedRenderers, inCodeBlock, useLatexDelimiters
4545
4719
  let result = "";
4546
4720
  for (const op of ops) {
4547
4721
  const attrs = op.attributes;
4548
- if (isTextInsert2(op)) {
4722
+ if (isTextInsert4(op)) {
4549
4723
  const text = op.insert;
4550
4724
  if (inCodeBlock) {
4551
4725
  result += text;
@@ -4774,12 +4948,12 @@ function renderBlockFormat(content, attributes, orderedIndex, _strict) {
4774
4948
  }
4775
4949
 
4776
4950
  // src/conversion/markdown/markdown-to-delta.ts
4777
- import { Delta as Delta10, isInsert as isInsert5 } from "@scrider/delta";
4951
+ import { Delta as Delta10, isInsert as isInsert7 } from "@scrider/delta";
4778
4952
 
4779
4953
  // src/conversion/markdown/table-header-normalize.ts
4780
- import { isInsert as isInsert4 } from "@scrider/delta";
4954
+ import { isInsert as isInsert6 } from "@scrider/delta";
4781
4955
  function isTableCellTerminator(op) {
4782
- return isInsert4(op) && typeof op.insert === "string" && op.insert === "\n" && op.attributes !== void 0 && typeof op.attributes["table-row"] === "number";
4956
+ return isInsert6(op) && typeof op.insert === "string" && op.insert === "\n" && op.attributes !== void 0 && typeof op.attributes["table-row"] === "number";
4783
4957
  }
4784
4958
  function normalizeSyntheticEmptyHeaderRow(ops) {
4785
4959
  const ends = [];
@@ -4788,7 +4962,7 @@ function normalizeSyntheticEmptyHeaderRow(ops) {
4788
4962
  let currentTextOps = [];
4789
4963
  for (let i = 0; i < ops.length; i++) {
4790
4964
  const op = ops[i];
4791
- if (!isInsert4(op)) continue;
4965
+ if (!isInsert6(op)) continue;
4792
4966
  if (typeof op.insert === "string" && op.insert !== "\n") {
4793
4967
  buf += op.insert;
4794
4968
  currentTextOps.push(i);
@@ -4839,7 +5013,7 @@ function normalizeHeaderDashPlaceholders(ops) {
4839
5013
  let currentTextOps = [];
4840
5014
  for (let i = 0; i < ops.length; i++) {
4841
5015
  const op = ops[i];
4842
- if (!isInsert4(op)) continue;
5016
+ if (!isInsert6(op)) continue;
4843
5017
  if (typeof op.insert === "string" && op.insert !== "\n") {
4844
5018
  buf += op.insert;
4845
5019
  currentTextOps.push(i);
@@ -4868,7 +5042,7 @@ function normalizeHeaderDashPlaceholders(ops) {
4868
5042
  out.push(op);
4869
5043
  continue;
4870
5044
  }
4871
- if (!isInsert4(op)) {
5045
+ if (!isInsert6(op)) {
4872
5046
  out.push(op);
4873
5047
  continue;
4874
5048
  }
@@ -4889,7 +5063,7 @@ function normalizeImportedTableOps(ops) {
4889
5063
  const ends = [];
4890
5064
  let buf = "";
4891
5065
  for (const op of ops) {
4892
- if (!isInsert4(op)) continue;
5066
+ if (!isInsert6(op)) continue;
4893
5067
  if (typeof op.insert === "string" && op.insert !== "\n") {
4894
5068
  buf += op.insert;
4895
5069
  continue;
@@ -5425,7 +5599,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5425
5599
  }
5426
5600
  const tableOps = delta.ops.splice(tableStart);
5427
5601
  for (const op of normalizeImportedTableOps(tableOps)) {
5428
- if (!isInsert5(op)) continue;
5602
+ if (!isInsert7(op)) continue;
5429
5603
  if (op.attributes && Object.keys(op.attributes).length > 0) {
5430
5604
  delta.insert(op.insert, op.attributes);
5431
5605
  } else {
@@ -5611,54 +5785,6 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5611
5785
  }
5612
5786
  return delta;
5613
5787
  }
5614
-
5615
- // src/conversion/markdown/table-region.ts
5616
- import { isInsert as isInsert6, isTextInsert as isTextInsert3 } from "@scrider/delta";
5617
- function isTableNewlineOp(op) {
5618
- if (!op || !isInsert6(op) || !isTextInsert3(op)) return false;
5619
- if (!op.insert.includes("\n")) return false;
5620
- return !!op.attributes && "table-row" in op.attributes;
5621
- }
5622
- function extractTableRegion(ops, hintOpIdx) {
5623
- if (hintOpIdx < 0 || hintOpIdx >= ops.length) return null;
5624
- let probeIdx = -1;
5625
- for (let i = hintOpIdx; i < ops.length; i++) {
5626
- const op = ops[i];
5627
- if (!op || !isInsert6(op)) continue;
5628
- if (isTextInsert3(op) && op.insert.includes("\n")) {
5629
- probeIdx = i;
5630
- break;
5631
- }
5632
- }
5633
- if (probeIdx < 0) return null;
5634
- if (!isTableNewlineOp(ops[probeIdx])) return null;
5635
- let endOpIdx = probeIdx;
5636
- for (let i = probeIdx + 1; i < ops.length; i++) {
5637
- const op = ops[i];
5638
- if (!op || !isInsert6(op)) break;
5639
- if (isTextInsert3(op) && op.insert.includes("\n")) {
5640
- if (isTableNewlineOp(op)) {
5641
- endOpIdx = i;
5642
- } else {
5643
- break;
5644
- }
5645
- }
5646
- }
5647
- let startOpIdx = 0;
5648
- for (let i = probeIdx - 1; i >= 0; i--) {
5649
- const op = ops[i];
5650
- if (!op || !isInsert6(op)) {
5651
- startOpIdx = i + 1;
5652
- break;
5653
- }
5654
- if (isTextInsert3(op) && op.insert.includes("\n") && !isTableNewlineOp(op)) {
5655
- startOpIdx = i + 1;
5656
- break;
5657
- }
5658
- }
5659
- const regionOps = ops.slice(startOpIdx, endOpIdx + 1);
5660
- return { startOpIdx, endOpIdx, ops: regionOps };
5661
- }
5662
5788
  export {
5663
5789
  ALERT_TYPES,
5664
5790
  BOX_FLOAT_VALUES,
@@ -5690,6 +5816,7 @@ export {
5690
5816
  codeBlockFormat,
5691
5817
  codeFormat,
5692
5818
  codeWidgetFormat,
5819
+ collectAdjacentTableLines,
5693
5820
  colorFormat,
5694
5821
  columnsBlockHandler,
5695
5822
  createDefaultBlockHandlers,
@@ -5717,6 +5844,7 @@ export {
5717
5844
  imageFormat,
5718
5845
  indentFormat,
5719
5846
  isAdapterAvailable,
5847
+ isAdjacentSimpleTableGridBoundary,
5720
5848
  isElement,
5721
5849
  isRemarkAvailable,
5722
5850
  isTableNewlineOp,
@@ -5749,6 +5877,8 @@ export {
5749
5877
  subscriptFormat,
5750
5878
  superscriptFormat,
5751
5879
  tableBlockHandler,
5880
+ tableCellCoordsFromAttributes,
5881
+ tableCellCoordsFromOp,
5752
5882
  tableColAlignFormat,
5753
5883
  tableColFormat,
5754
5884
  tableHeaderFormat,