@scrider/formatter 1.7.2 → 1.8.1

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.cjs CHANGED
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  codeBlockFormat: () => codeBlockFormat,
62
62
  codeFormat: () => codeFormat,
63
63
  codeWidgetFormat: () => codeWidgetFormat,
64
+ collectAdjacentTableLines: () => collectAdjacentTableLines,
64
65
  colorFormat: () => colorFormat,
65
66
  columnsBlockHandler: () => columnsBlockHandler,
66
67
  createDefaultBlockHandlers: () => createDefaultBlockHandlers,
@@ -88,6 +89,7 @@ __export(index_exports, {
88
89
  imageFormat: () => imageFormat,
89
90
  indentFormat: () => indentFormat,
90
91
  isAdapterAvailable: () => isAdapterAvailable,
92
+ isAdjacentSimpleTableGridBoundary: () => isAdjacentSimpleTableGridBoundary,
91
93
  isElement: () => isElement,
92
94
  isRemarkAvailable: () => isRemarkAvailable,
93
95
  isTableNewlineOp: () => isTableNewlineOp,
@@ -120,6 +122,8 @@ __export(index_exports, {
120
122
  subscriptFormat: () => subscriptFormat,
121
123
  superscriptFormat: () => superscriptFormat,
122
124
  tableBlockHandler: () => tableBlockHandler,
125
+ tableCellCoordsFromAttributes: () => tableCellCoordsFromAttributes,
126
+ tableCellCoordsFromOp: () => tableCellCoordsFromOp,
123
127
  tableColAlignFormat: () => tableColAlignFormat,
124
128
  tableColFormat: () => tableColFormat,
125
129
  tableHeaderFormat: () => tableHeaderFormat,
@@ -459,6 +463,20 @@ function cloneDelta(delta) {
459
463
  return new import_delta.Delta((0, import_delta.deepClone)(delta.ops));
460
464
  }
461
465
 
466
+ // src/conversion/markdown/table-header-markdown.ts
467
+ function isHeaderDashPlaceholder(text) {
468
+ const t = text.trim();
469
+ return t === "-" && t.length === 1;
470
+ }
471
+ function normalizeHeaderCellForParse(text, isHeaderRow) {
472
+ if (isHeaderRow && isHeaderDashPlaceholder(text)) return "";
473
+ return text;
474
+ }
475
+ function serializeHeaderCell(text) {
476
+ if (text.trim() === "") return "-";
477
+ return text;
478
+ }
479
+
462
480
  // src/conversion/adapters/types.ts
463
481
  var NODE_TYPE = {
464
482
  ELEMENT_NODE: 1,
@@ -580,19 +598,21 @@ function renderGfmTable(data, context) {
580
598
  if (headerRows === 0) {
581
599
  const emptyParts = [];
582
600
  for (let c = 0; c < cols; c++) {
583
- emptyParts.push(" ");
601
+ emptyParts.push("");
584
602
  }
585
603
  lines.push("| " + emptyParts.join(" | ") + " |");
586
604
  lines.push(renderGfmSeparator(cols, data.colAligns));
587
605
  }
588
606
  for (let r = 0; r < rows; r++) {
589
607
  const parts = [];
608
+ const isHeaderRow = headerRows > 0 && r < headerRows;
590
609
  for (let c = 0; c < cols; c++) {
591
610
  const cell = data.cells[`${r}:${c}`];
592
611
  let text = "";
593
612
  if (cell && context.renderDelta) {
594
613
  text = stripCellContent(context.renderDelta(cell.ops));
595
614
  }
615
+ if (isHeaderRow) text = serializeHeaderCell(text);
596
616
  parts.push(text.replace(/\|/g, "\\|"));
597
617
  }
598
618
  lines.push("| " + parts.join(" | ") + " |");
@@ -2762,7 +2782,7 @@ function isAdapterAvailable() {
2762
2782
  }
2763
2783
 
2764
2784
  // src/conversion/html/delta-to-html.ts
2765
- var import_delta7 = require("@scrider/delta");
2785
+ var import_delta8 = require("@scrider/delta");
2766
2786
 
2767
2787
  // src/conversion/utils/slugify.ts
2768
2788
  function slugify(text) {
@@ -2985,6 +3005,97 @@ function buildTableCellStyleAttr(params) {
2985
3005
  return ` style="${parts.join("; ")}"`;
2986
3006
  }
2987
3007
 
3008
+ // src/conversion/markdown/table-region.ts
3009
+ var import_delta7 = require("@scrider/delta");
3010
+ function isTableNewlineOp(op) {
3011
+ if (!op || !(0, import_delta7.isInsert)(op) || !(0, import_delta7.isTextInsert)(op)) return false;
3012
+ if (!op.insert.includes("\n")) return false;
3013
+ return !!op.attributes && "table-row" in op.attributes;
3014
+ }
3015
+ function tableCellCoordsFromAttributes(attrs) {
3016
+ if (!attrs || typeof attrs["table-row"] !== "number" || typeof attrs["table-col"] !== "number") {
3017
+ return null;
3018
+ }
3019
+ return { row: attrs["table-row"], col: attrs["table-col"] };
3020
+ }
3021
+ function tableCellCoordsFromOp(op) {
3022
+ if (!isTableNewlineOp(op) || !(0, import_delta7.isTextInsert)(op)) return null;
3023
+ return tableCellCoordsFromAttributes(op.attributes);
3024
+ }
3025
+ function isAdjacentSimpleTableGridBoundary(prev, next) {
3026
+ if (next.row < prev.row) return true;
3027
+ if (next.row === 0 && prev.row === 0 && next.col === 0 && prev.col > 0) return true;
3028
+ return false;
3029
+ }
3030
+ function collectAdjacentTableLines(lines, startIndex) {
3031
+ const result = [];
3032
+ let prevCoords = null;
3033
+ for (let i = startIndex; i < lines.length; i++) {
3034
+ const line = lines[i];
3035
+ if (line === void 0) break;
3036
+ const coords = tableCellCoordsFromAttributes(line.attributes);
3037
+ if (!coords) break;
3038
+ if (prevCoords && isAdjacentSimpleTableGridBoundary(prevCoords, coords)) break;
3039
+ result.push(line);
3040
+ prevCoords = coords;
3041
+ }
3042
+ return result;
3043
+ }
3044
+ function extractTableRegion(ops, hintOpIdx) {
3045
+ if (hintOpIdx < 0 || hintOpIdx >= ops.length) return null;
3046
+ let probeIdx = -1;
3047
+ for (let i = hintOpIdx; i < ops.length; i++) {
3048
+ const op = ops[i];
3049
+ if (!op || !(0, import_delta7.isInsert)(op)) continue;
3050
+ if ((0, import_delta7.isTextInsert)(op) && op.insert.includes("\n")) {
3051
+ probeIdx = i;
3052
+ break;
3053
+ }
3054
+ }
3055
+ if (probeIdx < 0) return null;
3056
+ if (!isTableNewlineOp(ops[probeIdx])) return null;
3057
+ const probeCoords = tableCellCoordsFromOp(ops[probeIdx]);
3058
+ if (!probeCoords) return null;
3059
+ let endOpIdx = probeIdx;
3060
+ let prevCoords = probeCoords;
3061
+ for (let i = probeIdx + 1; i < ops.length; i++) {
3062
+ const op = ops[i];
3063
+ if (!op || !(0, import_delta7.isInsert)(op)) break;
3064
+ if (!(0, import_delta7.isTextInsert)(op) || !op.insert.includes("\n")) continue;
3065
+ if (isTableNewlineOp(op)) {
3066
+ const coords = tableCellCoordsFromOp(op);
3067
+ if (isAdjacentSimpleTableGridBoundary(prevCoords, coords)) break;
3068
+ prevCoords = coords;
3069
+ endOpIdx = i;
3070
+ } else {
3071
+ break;
3072
+ }
3073
+ }
3074
+ let startOpIdx = 0;
3075
+ let nextCoords = probeCoords;
3076
+ for (let i = probeIdx - 1; i >= 0; i--) {
3077
+ const op = ops[i];
3078
+ if (!op || !(0, import_delta7.isInsert)(op)) {
3079
+ startOpIdx = i + 1;
3080
+ break;
3081
+ }
3082
+ if (!(0, import_delta7.isTextInsert)(op) || !op.insert.includes("\n")) continue;
3083
+ if (isTableNewlineOp(op)) {
3084
+ const coords = tableCellCoordsFromOp(op);
3085
+ if (isAdjacentSimpleTableGridBoundary(coords, nextCoords)) {
3086
+ startOpIdx = i + 1;
3087
+ break;
3088
+ }
3089
+ nextCoords = coords;
3090
+ } else {
3091
+ startOpIdx = i + 1;
3092
+ break;
3093
+ }
3094
+ }
3095
+ const regionOps = ops.slice(startOpIdx, endOpIdx + 1);
3096
+ return { startOpIdx, endOpIdx, ops: regionOps };
3097
+ }
3098
+
2988
3099
  // src/conversion/html/delta-to-html.ts
2989
3100
  function deltaToHtml(delta, options = {}) {
2990
3101
  const lines = splitIntoLines(delta);
@@ -3005,7 +3116,7 @@ function deltaToHtml(delta, options = {}) {
3005
3116
  html += closeAllLists(listStack, pretty);
3006
3117
  listStack = [];
3007
3118
  counters = [];
3008
- const tableLines = collectTableLines(lines, i);
3119
+ const tableLines = collectAdjacentTableLines(lines, i);
3009
3120
  html += renderTable(tableLines, embedRenderers, pretty, blockHandlers, options);
3010
3121
  i += tableLines.length - 1;
3011
3122
  continue;
@@ -3114,8 +3225,8 @@ function splitIntoLines(delta) {
3114
3225
  const lines = [];
3115
3226
  let currentOps = [];
3116
3227
  for (const op of delta.ops) {
3117
- if (!(0, import_delta7.isInsert)(op)) continue;
3118
- if ((0, import_delta7.isEmbedInsert)(op)) {
3228
+ if (!(0, import_delta8.isInsert)(op)) continue;
3229
+ if ((0, import_delta8.isEmbedInsert)(op)) {
3119
3230
  currentOps.push(op);
3120
3231
  continue;
3121
3232
  }
@@ -3152,7 +3263,7 @@ var BLOCK_LEVEL_EMBEDS = /* @__PURE__ */ new Set(["divider", "block"]);
3152
3263
  function isBlockLevelEmbedLine(line) {
3153
3264
  if (line.ops.length !== 1) return false;
3154
3265
  const op = line.ops[0];
3155
- if (!op || !(0, import_delta7.isEmbedInsert)(op)) return false;
3266
+ if (!op || !(0, import_delta8.isEmbedInsert)(op)) return false;
3156
3267
  const embed = op.insert;
3157
3268
  const embedType = Object.keys(embed)[0];
3158
3269
  if (!!embedType && BLOCK_LEVEL_EMBEDS.has(embedType)) return true;
@@ -3163,15 +3274,6 @@ function isBlockLevelEmbedLine(line) {
3163
3274
  function isTableLine(line) {
3164
3275
  return line.attributes != null && typeof line.attributes["table-row"] === "number" && typeof line.attributes["table-col"] === "number";
3165
3276
  }
3166
- function collectTableLines(lines, startIndex) {
3167
- const result = [];
3168
- for (let i = startIndex; i < lines.length; i++) {
3169
- const line = lines[i];
3170
- if (!line || !isTableLine(line)) break;
3171
- result.push(line);
3172
- }
3173
- return result;
3174
- }
3175
3277
  function renderTable(tableLines, embedRenderers, pretty, blockHandlers, options) {
3176
3278
  const rows = /* @__PURE__ */ new Map();
3177
3279
  for (const line of tableLines) {
@@ -3442,7 +3544,7 @@ function getBlockStyleAttribute(tag, attributes, resolvedDocumentPresentation) {
3442
3544
  function extractPlainText(ops) {
3443
3545
  let text = "";
3444
3546
  for (const op of ops) {
3445
- if ((0, import_delta7.isInsert)(op) && typeof op.insert === "string") {
3547
+ if ((0, import_delta8.isInsert)(op) && typeof op.insert === "string") {
3446
3548
  text += op.insert;
3447
3549
  }
3448
3550
  }
@@ -3451,8 +3553,8 @@ function extractPlainText(ops) {
3451
3553
  function renderLineContent(ops, embedRenderers, blockHandlers, options) {
3452
3554
  let html = "";
3453
3555
  for (const op of ops) {
3454
- if (!(0, import_delta7.isInsert)(op)) continue;
3455
- if ((0, import_delta7.isEmbedInsert)(op)) {
3556
+ if (!(0, import_delta8.isInsert)(op)) continue;
3557
+ if ((0, import_delta8.isEmbedInsert)(op)) {
3456
3558
  html += renderEmbed(
3457
3559
  op.insert,
3458
3560
  op.attributes,
@@ -3508,7 +3610,7 @@ function renderEmbed(value, attributes, renderers, blockHandlers, options) {
3508
3610
  const context = {
3509
3611
  registry: null,
3510
3612
  options: { pretty: options?.pretty ?? false },
3511
- renderDelta: (ops) => deltaToHtml(new import_delta7.Delta(ops), options ?? {}),
3613
+ renderDelta: (ops) => deltaToHtml(new import_delta8.Delta(ops), options ?? {}),
3512
3614
  ...attributes ? { opAttributes: attributes } : {}
3513
3615
  };
3514
3616
  return handler.toHtml(blockData, context);
@@ -3533,13 +3635,13 @@ function renderEmbed(value, attributes, renderers, blockHandlers, options) {
3533
3635
  }
3534
3636
 
3535
3637
  // src/conversion/html/html-to-delta.ts
3536
- var import_delta8 = require("@scrider/delta");
3638
+ var import_delta9 = require("@scrider/delta");
3537
3639
  function htmlToDelta(html, options = {}) {
3538
3640
  const adapter = options.adapter ?? getAdapter();
3539
3641
  const normalizeWhitespace = options.normalizeWhitespace ?? true;
3540
3642
  const tagHandlers = { ...DEFAULT_TAG_HANDLERS, ...options.tagHandlers };
3541
3643
  const fragment = adapter.parseHTML(html);
3542
- const delta = new import_delta8.Delta();
3644
+ const delta = new import_delta9.Delta();
3543
3645
  let currentAttributes = {};
3544
3646
  let currentBlockAttributes = {};
3545
3647
  let pendingText = "";
@@ -4249,7 +4351,7 @@ var DEFAULT_TAG_HANDLERS = {
4249
4351
  };
4250
4352
 
4251
4353
  // src/conversion/markdown/delta-to-markdown.ts
4252
- var import_delta9 = require("@scrider/delta");
4354
+ var import_delta10 = require("@scrider/delta");
4253
4355
 
4254
4356
  // src/conversion/markdown/config.ts
4255
4357
  var MARKDOWN_ESCAPE_CHARS = /[\\`*_[\]<>#]/g;
@@ -4337,7 +4439,7 @@ function deltaToMarkdown(delta, options = {}) {
4337
4439
  const attrs = line.attributes;
4338
4440
  const isBlockquote = !!attrs.blockquote;
4339
4441
  if (typeof attrs["table-row"] === "number" && typeof attrs["table-col"] === "number") {
4340
- const tableLines = collectTableLines2(lines, i);
4442
+ const tableLines = collectAdjacentTableLines(lines, i);
4341
4443
  result.push(
4342
4444
  renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4343
4445
  );
@@ -4442,9 +4544,9 @@ function splitIntoLines2(ops) {
4442
4544
  const lines = [];
4443
4545
  let currentOps = [];
4444
4546
  for (const op of ops) {
4445
- if (!(0, import_delta9.isInsert)(op)) continue;
4547
+ if (!(0, import_delta10.isInsert)(op)) continue;
4446
4548
  const opAttrs = op.attributes ?? {};
4447
- if ((0, import_delta9.isTextInsert)(op)) {
4549
+ if ((0, import_delta10.isTextInsert)(op)) {
4448
4550
  const text = op.insert;
4449
4551
  const parts = text.split("\n");
4450
4552
  for (let i = 0; i < parts.length; i++) {
@@ -4509,17 +4611,6 @@ function collectCodeBlock(lines, startIndex) {
4509
4611
  }
4510
4612
  return codeLines;
4511
4613
  }
4512
- function collectTableLines2(lines, startIndex) {
4513
- const result = [];
4514
- for (let i = startIndex; i < lines.length; i++) {
4515
- const line = lines[i];
4516
- if (!line || typeof line.attributes["table-row"] !== "number" || typeof line.attributes["table-col"] !== "number") {
4517
- break;
4518
- }
4519
- result.push(line);
4520
- }
4521
- return result;
4522
- }
4523
4614
  function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces") {
4524
4615
  const rows = /* @__PURE__ */ new Map();
4525
4616
  for (const line of tableLines) {
@@ -4558,7 +4649,15 @@ function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = fa
4558
4649
  if (headerRows.length > 0) {
4559
4650
  for (const [, row] of headerRows) {
4560
4651
  mdLines.push(
4561
- renderMdRow(row.cells, maxCol, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4652
+ renderMdRow(
4653
+ row.cells,
4654
+ maxCol,
4655
+ embedRenderers,
4656
+ useLatexDelimiters,
4657
+ registry,
4658
+ softBreakStyle,
4659
+ true
4660
+ )
4562
4661
  );
4563
4662
  }
4564
4663
  mdLines.push(renderMdSeparator(maxCol, colAligns));
@@ -4568,22 +4667,38 @@ function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = fa
4568
4667
  emptyRow.set(col, { ops: [] });
4569
4668
  }
4570
4669
  mdLines.push(
4571
- renderMdRow(emptyRow, maxCol, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4670
+ renderMdRow(
4671
+ emptyRow,
4672
+ maxCol,
4673
+ embedRenderers,
4674
+ useLatexDelimiters,
4675
+ registry,
4676
+ softBreakStyle,
4677
+ false
4678
+ )
4572
4679
  );
4573
4680
  mdLines.push(renderMdSeparator(maxCol, colAligns));
4574
4681
  }
4575
4682
  for (const [, row] of bodyRows) {
4576
4683
  mdLines.push(
4577
- renderMdRow(row.cells, maxCol, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4684
+ renderMdRow(
4685
+ row.cells,
4686
+ maxCol,
4687
+ embedRenderers,
4688
+ useLatexDelimiters,
4689
+ registry,
4690
+ softBreakStyle,
4691
+ false
4692
+ )
4578
4693
  );
4579
4694
  }
4580
4695
  return mdLines.join("\n");
4581
4696
  }
4582
- function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces") {
4697
+ function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces", isHeaderRow = false) {
4583
4698
  const parts = [];
4584
4699
  for (let col = 0; col <= maxCol; col++) {
4585
4700
  const cell = cells.get(col);
4586
- const content = cell ? renderLineContent2(
4701
+ let content = cell ? renderLineContent2(
4587
4702
  cell.ops,
4588
4703
  embedRenderers,
4589
4704
  false,
@@ -4595,6 +4710,7 @@ function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false,
4595
4710
  true
4596
4711
  // inTableCell — softBreak must use <br>, never " \n"
4597
4712
  ) : "";
4713
+ if (isHeaderRow) content = serializeHeaderCell(content);
4598
4714
  parts.push(content.replace(/\|/g, "\\|"));
4599
4715
  }
4600
4716
  return "| " + parts.join(" | ") + " |";
@@ -4630,14 +4746,14 @@ function renderLineContent2(ops, embedRenderers, inCodeBlock, useLatexDelimiters
4630
4746
  let result = "";
4631
4747
  for (const op of ops) {
4632
4748
  const attrs = op.attributes;
4633
- if ((0, import_delta9.isTextInsert)(op)) {
4749
+ if ((0, import_delta10.isTextInsert)(op)) {
4634
4750
  const text = op.insert;
4635
4751
  if (inCodeBlock) {
4636
4752
  result += text;
4637
4753
  } else {
4638
4754
  result += renderInlineText2(text, attrs);
4639
4755
  }
4640
- } else if ((0, import_delta9.isEmbedInsert)(op)) {
4756
+ } else if ((0, import_delta10.isEmbedInsert)(op)) {
4641
4757
  const embed = op.insert;
4642
4758
  result += renderEmbed2(
4643
4759
  embed,
@@ -4702,7 +4818,7 @@ function renderEmbed2(embed, attributes, customRenderers, useLatexDelimiters = f
4702
4818
  if (handler.toMarkdown) {
4703
4819
  const mdContext = {
4704
4820
  registry: void 0,
4705
- renderDelta: (ops) => deltaToMarkdown(new import_delta9.Delta(ops), { blockHandlers }),
4821
+ renderDelta: (ops) => deltaToMarkdown(new import_delta10.Delta(ops), { blockHandlers }),
4706
4822
  ...opAttrs
4707
4823
  };
4708
4824
  const md = handler.toMarkdown(blockData, mdContext);
@@ -4711,7 +4827,7 @@ function renderEmbed2(embed, attributes, customRenderers, useLatexDelimiters = f
4711
4827
  const htmlContext = {
4712
4828
  registry: void 0,
4713
4829
  ...prettyHtml ? { options: { pretty: true } } : {},
4714
- renderDelta: (ops) => deltaToHtml(new import_delta9.Delta(ops), { blockHandlers, pretty: prettyHtml }),
4830
+ renderDelta: (ops) => deltaToHtml(new import_delta10.Delta(ops), { blockHandlers, pretty: prettyHtml }),
4715
4831
  ...opAttrs
4716
4832
  };
4717
4833
  return "\n" + handler.toHtml(blockData, htmlContext) + "\n";
@@ -4859,7 +4975,138 @@ function renderBlockFormat(content, attributes, orderedIndex, _strict) {
4859
4975
  }
4860
4976
 
4861
4977
  // src/conversion/markdown/markdown-to-delta.ts
4862
- var import_delta10 = require("@scrider/delta");
4978
+ var import_delta12 = require("@scrider/delta");
4979
+
4980
+ // src/conversion/markdown/table-header-normalize.ts
4981
+ var import_delta11 = require("@scrider/delta");
4982
+ function isTableCellTerminator(op) {
4983
+ return (0, import_delta11.isInsert)(op) && typeof op.insert === "string" && op.insert === "\n" && op.attributes !== void 0 && typeof op.attributes["table-row"] === "number";
4984
+ }
4985
+ function normalizeSyntheticEmptyHeaderRow(ops) {
4986
+ const ends = [];
4987
+ let buf = "";
4988
+ const textOpIndicesByCell = [];
4989
+ let currentTextOps = [];
4990
+ for (let i = 0; i < ops.length; i++) {
4991
+ const op = ops[i];
4992
+ if (!(0, import_delta11.isInsert)(op)) continue;
4993
+ if (typeof op.insert === "string" && op.insert !== "\n") {
4994
+ buf += op.insert;
4995
+ currentTextOps.push(i);
4996
+ continue;
4997
+ }
4998
+ if (isTableCellTerminator(op)) {
4999
+ const row = op.attributes["table-row"];
5000
+ const col = op.attributes["table-col"];
5001
+ ends.push({ row, col, newlineIdx: i, text: buf });
5002
+ textOpIndicesByCell.push([...currentTextOps]);
5003
+ buf = "";
5004
+ currentTextOps = [];
5005
+ }
5006
+ }
5007
+ const row0 = ends.filter((e) => e.row === 0);
5008
+ if (row0.length === 0) return [...ops];
5009
+ if (!row0.every((e) => e.text.trim() === "")) return [...ops];
5010
+ if (row0.some((e) => isHeaderDashPlaceholder(e.text))) return [...ops];
5011
+ const remove = /* @__PURE__ */ new Set();
5012
+ for (let j = 0; j < ends.length; j++) {
5013
+ const end = ends[j];
5014
+ if (end.row !== 0) continue;
5015
+ remove.add(end.newlineIdx);
5016
+ for (const ti of textOpIndicesByCell[j] ?? []) remove.add(ti);
5017
+ }
5018
+ const out = [];
5019
+ for (let i = 0; i < ops.length; i++) {
5020
+ if (remove.has(i)) continue;
5021
+ const op = ops[i];
5022
+ if (!isTableCellTerminator(op)) {
5023
+ out.push(op);
5024
+ continue;
5025
+ }
5026
+ const row = op.attributes["table-row"];
5027
+ if (row === 0) continue;
5028
+ const attrs = { ...op.attributes };
5029
+ delete attrs["table-header"];
5030
+ out.push({
5031
+ insert: "\n",
5032
+ attributes: { ...attrs, "table-row": row - 1 }
5033
+ });
5034
+ }
5035
+ return out;
5036
+ }
5037
+ function normalizeHeaderDashPlaceholders(ops) {
5038
+ const ends = [];
5039
+ let buf = "";
5040
+ let currentTextOps = [];
5041
+ for (let i = 0; i < ops.length; i++) {
5042
+ const op = ops[i];
5043
+ if (!(0, import_delta11.isInsert)(op)) continue;
5044
+ if (typeof op.insert === "string" && op.insert !== "\n") {
5045
+ buf += op.insert;
5046
+ currentTextOps.push(i);
5047
+ continue;
5048
+ }
5049
+ if (isTableCellTerminator(op)) {
5050
+ const row = op.attributes["table-row"];
5051
+ const isHeader = row === 0 && op.attributes["table-header"] === true;
5052
+ ends.push({ isHeader, textOpIndices: [...currentTextOps], text: buf });
5053
+ buf = "";
5054
+ currentTextOps = [];
5055
+ }
5056
+ }
5057
+ const dashHeaderCells = ends.filter(
5058
+ (e) => e.isHeader && e.textOpIndices.length > 0 && isHeaderDashPlaceholder(e.text)
5059
+ );
5060
+ if (dashHeaderCells.length === 0) return [...ops];
5061
+ const replaceIndices = /* @__PURE__ */ new Set();
5062
+ for (const end of dashHeaderCells) {
5063
+ for (const ti of end.textOpIndices) replaceIndices.add(ti);
5064
+ }
5065
+ const out = [];
5066
+ for (let i = 0; i < ops.length; i++) {
5067
+ const op = ops[i];
5068
+ if (!replaceIndices.has(i)) {
5069
+ out.push(op);
5070
+ continue;
5071
+ }
5072
+ if (!(0, import_delta11.isInsert)(op)) {
5073
+ out.push(op);
5074
+ continue;
5075
+ }
5076
+ if (typeof op.insert === "string" && op.insert !== "\n") {
5077
+ const normalized = normalizeHeaderCellForParse(op.insert, true);
5078
+ if (normalized.length === 0) continue;
5079
+ out.push(
5080
+ op.attributes ? { insert: normalized, attributes: op.attributes } : { insert: normalized }
5081
+ );
5082
+ } else {
5083
+ out.push(op);
5084
+ }
5085
+ }
5086
+ return out;
5087
+ }
5088
+ function normalizeImportedTableOps(ops) {
5089
+ if (ops.length === 0) return [...ops];
5090
+ const ends = [];
5091
+ let buf = "";
5092
+ for (const op of ops) {
5093
+ if (!(0, import_delta11.isInsert)(op)) continue;
5094
+ if (typeof op.insert === "string" && op.insert !== "\n") {
5095
+ buf += op.insert;
5096
+ continue;
5097
+ }
5098
+ if (isTableCellTerminator(op)) {
5099
+ ends.push({ row: op.attributes["table-row"], text: buf });
5100
+ buf = "";
5101
+ }
5102
+ }
5103
+ const row0 = ends.filter((e) => e.row === 0);
5104
+ const headerless = row0.length > 0 && row0.every((e) => e.text.trim() === "") && !row0.some((e) => isHeaderDashPlaceholder(e.text));
5105
+ if (headerless) return normalizeSyntheticEmptyHeaderRow(ops);
5106
+ return normalizeHeaderDashPlaceholders(ops);
5107
+ }
5108
+
5109
+ // src/conversion/markdown/markdown-to-delta.ts
4863
5110
  var remarkParse = null;
4864
5111
  var remarkGfm = null;
4865
5112
  var remarkMath = null;
@@ -4996,7 +5243,7 @@ function markdownToDeltaSync(markdown, options = {}) {
4996
5243
  );
4997
5244
  }
4998
5245
  function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock, blockHandlers) {
4999
- const delta = new import_delta10.Delta();
5246
+ const delta = new import_delta12.Delta();
5000
5247
  let currentInlineAttrs = {};
5001
5248
  let pendingText = "";
5002
5249
  const spanAttrStack = [];
@@ -5348,6 +5595,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5348
5595
  }
5349
5596
  function processTable(node) {
5350
5597
  if (!node.children) return;
5598
+ const tableStart = delta.ops.length;
5351
5599
  const aligns = node.align || [];
5352
5600
  for (let rowIdx = 0; rowIdx < node.children.length; rowIdx++) {
5353
5601
  const rowNode = node.children[rowIdx];
@@ -5376,6 +5624,15 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5376
5624
  context.pushNewline(cellBlockAttrs);
5377
5625
  }
5378
5626
  }
5627
+ const tableOps = delta.ops.splice(tableStart);
5628
+ for (const op of normalizeImportedTableOps(tableOps)) {
5629
+ if (!(0, import_delta12.isInsert)(op)) continue;
5630
+ if (op.attributes && Object.keys(op.attributes).length > 0) {
5631
+ delta.insert(op.insert, op.attributes);
5632
+ } else {
5633
+ delta.insert(op.insert);
5634
+ }
5635
+ }
5379
5636
  }
5380
5637
  function isBlockLevelHtml(html) {
5381
5638
  return /^\s*<(div|table|section|article|aside|nav|header|footer|figure|pre|hr|ol|ul|dl|details|iframe|video)\b/i.test(
@@ -5555,54 +5812,6 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5555
5812
  }
5556
5813
  return delta;
5557
5814
  }
5558
-
5559
- // src/conversion/markdown/table-region.ts
5560
- var import_delta11 = require("@scrider/delta");
5561
- function isTableNewlineOp(op) {
5562
- if (!op || !(0, import_delta11.isInsert)(op) || !(0, import_delta11.isTextInsert)(op)) return false;
5563
- if (!op.insert.includes("\n")) return false;
5564
- return !!op.attributes && "table-row" in op.attributes;
5565
- }
5566
- function extractTableRegion(ops, hintOpIdx) {
5567
- if (hintOpIdx < 0 || hintOpIdx >= ops.length) return null;
5568
- let probeIdx = -1;
5569
- for (let i = hintOpIdx; i < ops.length; i++) {
5570
- const op = ops[i];
5571
- if (!op || !(0, import_delta11.isInsert)(op)) continue;
5572
- if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n")) {
5573
- probeIdx = i;
5574
- break;
5575
- }
5576
- }
5577
- if (probeIdx < 0) return null;
5578
- if (!isTableNewlineOp(ops[probeIdx])) return null;
5579
- let endOpIdx = probeIdx;
5580
- for (let i = probeIdx + 1; i < ops.length; i++) {
5581
- const op = ops[i];
5582
- if (!op || !(0, import_delta11.isInsert)(op)) break;
5583
- if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n")) {
5584
- if (isTableNewlineOp(op)) {
5585
- endOpIdx = i;
5586
- } else {
5587
- break;
5588
- }
5589
- }
5590
- }
5591
- let startOpIdx = 0;
5592
- for (let i = probeIdx - 1; i >= 0; i--) {
5593
- const op = ops[i];
5594
- if (!op || !(0, import_delta11.isInsert)(op)) {
5595
- startOpIdx = i + 1;
5596
- break;
5597
- }
5598
- if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n") && !isTableNewlineOp(op)) {
5599
- startOpIdx = i + 1;
5600
- break;
5601
- }
5602
- }
5603
- const regionOps = ops.slice(startOpIdx, endOpIdx + 1);
5604
- return { startOpIdx, endOpIdx, ops: regionOps };
5605
- }
5606
5815
  // Annotate the CommonJS export names for ESM import in node:
5607
5816
  0 && (module.exports = {
5608
5817
  ALERT_TYPES,
@@ -5635,6 +5844,7 @@ function extractTableRegion(ops, hintOpIdx) {
5635
5844
  codeBlockFormat,
5636
5845
  codeFormat,
5637
5846
  codeWidgetFormat,
5847
+ collectAdjacentTableLines,
5638
5848
  colorFormat,
5639
5849
  columnsBlockHandler,
5640
5850
  createDefaultBlockHandlers,
@@ -5662,6 +5872,7 @@ function extractTableRegion(ops, hintOpIdx) {
5662
5872
  imageFormat,
5663
5873
  indentFormat,
5664
5874
  isAdapterAvailable,
5875
+ isAdjacentSimpleTableGridBoundary,
5665
5876
  isElement,
5666
5877
  isRemarkAvailable,
5667
5878
  isTableNewlineOp,
@@ -5694,6 +5905,8 @@ function extractTableRegion(ops, hintOpIdx) {
5694
5905
  subscriptFormat,
5695
5906
  superscriptFormat,
5696
5907
  tableBlockHandler,
5908
+ tableCellCoordsFromAttributes,
5909
+ tableCellCoordsFromOp,
5697
5910
  tableColAlignFormat,
5698
5911
  tableColFormat,
5699
5912
  tableHeaderFormat,