@scrider/formatter 1.7.1 → 1.8.0

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
@@ -459,6 +459,20 @@ function cloneDelta(delta) {
459
459
  return new import_delta.Delta((0, import_delta.deepClone)(delta.ops));
460
460
  }
461
461
 
462
+ // src/conversion/markdown/table-header-markdown.ts
463
+ function isHeaderDashPlaceholder(text) {
464
+ const t = text.trim();
465
+ return t === "-" && t.length === 1;
466
+ }
467
+ function normalizeHeaderCellForParse(text, isHeaderRow) {
468
+ if (isHeaderRow && isHeaderDashPlaceholder(text)) return "";
469
+ return text;
470
+ }
471
+ function serializeHeaderCell(text) {
472
+ if (text.trim() === "") return "-";
473
+ return text;
474
+ }
475
+
462
476
  // src/conversion/adapters/types.ts
463
477
  var NODE_TYPE = {
464
478
  ELEMENT_NODE: 1,
@@ -580,19 +594,21 @@ function renderGfmTable(data, context) {
580
594
  if (headerRows === 0) {
581
595
  const emptyParts = [];
582
596
  for (let c = 0; c < cols; c++) {
583
- emptyParts.push(" ");
597
+ emptyParts.push("");
584
598
  }
585
599
  lines.push("| " + emptyParts.join(" | ") + " |");
586
600
  lines.push(renderGfmSeparator(cols, data.colAligns));
587
601
  }
588
602
  for (let r = 0; r < rows; r++) {
589
603
  const parts = [];
604
+ const isHeaderRow = headerRows > 0 && r < headerRows;
590
605
  for (let c = 0; c < cols; c++) {
591
606
  const cell = data.cells[`${r}:${c}`];
592
607
  let text = "";
593
608
  if (cell && context.renderDelta) {
594
609
  text = stripCellContent(context.renderDelta(cell.ops));
595
610
  }
611
+ if (isHeaderRow) text = serializeHeaderCell(text);
596
612
  parts.push(text.replace(/\|/g, "\\|"));
597
613
  }
598
614
  lines.push("| " + parts.join(" | ") + " |");
@@ -2195,6 +2211,14 @@ function toCodeWidgetEmbedUrl(url) {
2195
2211
  const trimmed = base.replace(/\/+$/, "");
2196
2212
  return `${trimmed}/embedded/${query}${hash}`;
2197
2213
  }
2214
+ if (/(?:\/\/|^)(?:[\w-]+\.)*trinket\.io\//i.test(u)) {
2215
+ if (/trinket\.io\/embed\//i.test(u)) return u;
2216
+ return u.replace(/trinket\.io\//i, "trinket.io/embed/");
2217
+ }
2218
+ if (/(?:\/\/|^)(?:[\w-]+\.)*onecompiler\.com\//i.test(u)) {
2219
+ if (/onecompiler\.com\/embed\//i.test(u)) return u;
2220
+ return u.replace(/onecompiler\.com\//i, "onecompiler.com/embed/");
2221
+ }
2198
2222
  return u;
2199
2223
  }
2200
2224
 
@@ -4550,7 +4574,15 @@ function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = fa
4550
4574
  if (headerRows.length > 0) {
4551
4575
  for (const [, row] of headerRows) {
4552
4576
  mdLines.push(
4553
- renderMdRow(row.cells, maxCol, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4577
+ renderMdRow(
4578
+ row.cells,
4579
+ maxCol,
4580
+ embedRenderers,
4581
+ useLatexDelimiters,
4582
+ registry,
4583
+ softBreakStyle,
4584
+ true
4585
+ )
4554
4586
  );
4555
4587
  }
4556
4588
  mdLines.push(renderMdSeparator(maxCol, colAligns));
@@ -4560,22 +4592,38 @@ function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = fa
4560
4592
  emptyRow.set(col, { ops: [] });
4561
4593
  }
4562
4594
  mdLines.push(
4563
- renderMdRow(emptyRow, maxCol, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4595
+ renderMdRow(
4596
+ emptyRow,
4597
+ maxCol,
4598
+ embedRenderers,
4599
+ useLatexDelimiters,
4600
+ registry,
4601
+ softBreakStyle,
4602
+ false
4603
+ )
4564
4604
  );
4565
4605
  mdLines.push(renderMdSeparator(maxCol, colAligns));
4566
4606
  }
4567
4607
  for (const [, row] of bodyRows) {
4568
4608
  mdLines.push(
4569
- renderMdRow(row.cells, maxCol, embedRenderers, useLatexDelimiters, registry, softBreakStyle)
4609
+ renderMdRow(
4610
+ row.cells,
4611
+ maxCol,
4612
+ embedRenderers,
4613
+ useLatexDelimiters,
4614
+ registry,
4615
+ softBreakStyle,
4616
+ false
4617
+ )
4570
4618
  );
4571
4619
  }
4572
4620
  return mdLines.join("\n");
4573
4621
  }
4574
- function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces") {
4622
+ function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces", isHeaderRow = false) {
4575
4623
  const parts = [];
4576
4624
  for (let col = 0; col <= maxCol; col++) {
4577
4625
  const cell = cells.get(col);
4578
- const content = cell ? renderLineContent2(
4626
+ let content = cell ? renderLineContent2(
4579
4627
  cell.ops,
4580
4628
  embedRenderers,
4581
4629
  false,
@@ -4587,6 +4635,7 @@ function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false,
4587
4635
  true
4588
4636
  // inTableCell — softBreak must use <br>, never " \n"
4589
4637
  ) : "";
4638
+ if (isHeaderRow) content = serializeHeaderCell(content);
4590
4639
  parts.push(content.replace(/\|/g, "\\|"));
4591
4640
  }
4592
4641
  return "| " + parts.join(" | ") + " |";
@@ -4851,7 +4900,138 @@ function renderBlockFormat(content, attributes, orderedIndex, _strict) {
4851
4900
  }
4852
4901
 
4853
4902
  // src/conversion/markdown/markdown-to-delta.ts
4903
+ var import_delta11 = require("@scrider/delta");
4904
+
4905
+ // src/conversion/markdown/table-header-normalize.ts
4854
4906
  var import_delta10 = require("@scrider/delta");
4907
+ function isTableCellTerminator(op) {
4908
+ return (0, import_delta10.isInsert)(op) && typeof op.insert === "string" && op.insert === "\n" && op.attributes !== void 0 && typeof op.attributes["table-row"] === "number";
4909
+ }
4910
+ function normalizeSyntheticEmptyHeaderRow(ops) {
4911
+ const ends = [];
4912
+ let buf = "";
4913
+ const textOpIndicesByCell = [];
4914
+ let currentTextOps = [];
4915
+ for (let i = 0; i < ops.length; i++) {
4916
+ const op = ops[i];
4917
+ if (!(0, import_delta10.isInsert)(op)) continue;
4918
+ if (typeof op.insert === "string" && op.insert !== "\n") {
4919
+ buf += op.insert;
4920
+ currentTextOps.push(i);
4921
+ continue;
4922
+ }
4923
+ if (isTableCellTerminator(op)) {
4924
+ const row = op.attributes["table-row"];
4925
+ const col = op.attributes["table-col"];
4926
+ ends.push({ row, col, newlineIdx: i, text: buf });
4927
+ textOpIndicesByCell.push([...currentTextOps]);
4928
+ buf = "";
4929
+ currentTextOps = [];
4930
+ }
4931
+ }
4932
+ const row0 = ends.filter((e) => e.row === 0);
4933
+ if (row0.length === 0) return [...ops];
4934
+ if (!row0.every((e) => e.text.trim() === "")) return [...ops];
4935
+ if (row0.some((e) => isHeaderDashPlaceholder(e.text))) return [...ops];
4936
+ const remove = /* @__PURE__ */ new Set();
4937
+ for (let j = 0; j < ends.length; j++) {
4938
+ const end = ends[j];
4939
+ if (end.row !== 0) continue;
4940
+ remove.add(end.newlineIdx);
4941
+ for (const ti of textOpIndicesByCell[j] ?? []) remove.add(ti);
4942
+ }
4943
+ const out = [];
4944
+ for (let i = 0; i < ops.length; i++) {
4945
+ if (remove.has(i)) continue;
4946
+ const op = ops[i];
4947
+ if (!isTableCellTerminator(op)) {
4948
+ out.push(op);
4949
+ continue;
4950
+ }
4951
+ const row = op.attributes["table-row"];
4952
+ if (row === 0) continue;
4953
+ const attrs = { ...op.attributes };
4954
+ delete attrs["table-header"];
4955
+ out.push({
4956
+ insert: "\n",
4957
+ attributes: { ...attrs, "table-row": row - 1 }
4958
+ });
4959
+ }
4960
+ return out;
4961
+ }
4962
+ function normalizeHeaderDashPlaceholders(ops) {
4963
+ const ends = [];
4964
+ let buf = "";
4965
+ let currentTextOps = [];
4966
+ for (let i = 0; i < ops.length; i++) {
4967
+ const op = ops[i];
4968
+ if (!(0, import_delta10.isInsert)(op)) continue;
4969
+ if (typeof op.insert === "string" && op.insert !== "\n") {
4970
+ buf += op.insert;
4971
+ currentTextOps.push(i);
4972
+ continue;
4973
+ }
4974
+ if (isTableCellTerminator(op)) {
4975
+ const row = op.attributes["table-row"];
4976
+ const isHeader = row === 0 && op.attributes["table-header"] === true;
4977
+ ends.push({ isHeader, textOpIndices: [...currentTextOps], text: buf });
4978
+ buf = "";
4979
+ currentTextOps = [];
4980
+ }
4981
+ }
4982
+ const dashHeaderCells = ends.filter(
4983
+ (e) => e.isHeader && e.textOpIndices.length > 0 && isHeaderDashPlaceholder(e.text)
4984
+ );
4985
+ if (dashHeaderCells.length === 0) return [...ops];
4986
+ const replaceIndices = /* @__PURE__ */ new Set();
4987
+ for (const end of dashHeaderCells) {
4988
+ for (const ti of end.textOpIndices) replaceIndices.add(ti);
4989
+ }
4990
+ const out = [];
4991
+ for (let i = 0; i < ops.length; i++) {
4992
+ const op = ops[i];
4993
+ if (!replaceIndices.has(i)) {
4994
+ out.push(op);
4995
+ continue;
4996
+ }
4997
+ if (!(0, import_delta10.isInsert)(op)) {
4998
+ out.push(op);
4999
+ continue;
5000
+ }
5001
+ if (typeof op.insert === "string" && op.insert !== "\n") {
5002
+ const normalized = normalizeHeaderCellForParse(op.insert, true);
5003
+ if (normalized.length === 0) continue;
5004
+ out.push(
5005
+ op.attributes ? { insert: normalized, attributes: op.attributes } : { insert: normalized }
5006
+ );
5007
+ } else {
5008
+ out.push(op);
5009
+ }
5010
+ }
5011
+ return out;
5012
+ }
5013
+ function normalizeImportedTableOps(ops) {
5014
+ if (ops.length === 0) return [...ops];
5015
+ const ends = [];
5016
+ let buf = "";
5017
+ for (const op of ops) {
5018
+ if (!(0, import_delta10.isInsert)(op)) continue;
5019
+ if (typeof op.insert === "string" && op.insert !== "\n") {
5020
+ buf += op.insert;
5021
+ continue;
5022
+ }
5023
+ if (isTableCellTerminator(op)) {
5024
+ ends.push({ row: op.attributes["table-row"], text: buf });
5025
+ buf = "";
5026
+ }
5027
+ }
5028
+ const row0 = ends.filter((e) => e.row === 0);
5029
+ const headerless = row0.length > 0 && row0.every((e) => e.text.trim() === "") && !row0.some((e) => isHeaderDashPlaceholder(e.text));
5030
+ if (headerless) return normalizeSyntheticEmptyHeaderRow(ops);
5031
+ return normalizeHeaderDashPlaceholders(ops);
5032
+ }
5033
+
5034
+ // src/conversion/markdown/markdown-to-delta.ts
4855
5035
  var remarkParse = null;
4856
5036
  var remarkGfm = null;
4857
5037
  var remarkMath = null;
@@ -4988,7 +5168,7 @@ function markdownToDeltaSync(markdown, options = {}) {
4988
5168
  );
4989
5169
  }
4990
5170
  function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock, blockHandlers) {
4991
- const delta = new import_delta10.Delta();
5171
+ const delta = new import_delta11.Delta();
4992
5172
  let currentInlineAttrs = {};
4993
5173
  let pendingText = "";
4994
5174
  const spanAttrStack = [];
@@ -5340,6 +5520,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5340
5520
  }
5341
5521
  function processTable(node) {
5342
5522
  if (!node.children) return;
5523
+ const tableStart = delta.ops.length;
5343
5524
  const aligns = node.align || [];
5344
5525
  for (let rowIdx = 0; rowIdx < node.children.length; rowIdx++) {
5345
5526
  const rowNode = node.children[rowIdx];
@@ -5368,6 +5549,15 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5368
5549
  context.pushNewline(cellBlockAttrs);
5369
5550
  }
5370
5551
  }
5552
+ const tableOps = delta.ops.splice(tableStart);
5553
+ for (const op of normalizeImportedTableOps(tableOps)) {
5554
+ if (!(0, import_delta11.isInsert)(op)) continue;
5555
+ if (op.attributes && Object.keys(op.attributes).length > 0) {
5556
+ delta.insert(op.insert, op.attributes);
5557
+ } else {
5558
+ delta.insert(op.insert);
5559
+ }
5560
+ }
5371
5561
  }
5372
5562
  function isBlockLevelHtml(html) {
5373
5563
  return /^\s*<(div|table|section|article|aside|nav|header|footer|figure|pre|hr|ol|ul|dl|details|iframe|video)\b/i.test(
@@ -5549,9 +5739,9 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
5549
5739
  }
5550
5740
 
5551
5741
  // src/conversion/markdown/table-region.ts
5552
- var import_delta11 = require("@scrider/delta");
5742
+ var import_delta12 = require("@scrider/delta");
5553
5743
  function isTableNewlineOp(op) {
5554
- if (!op || !(0, import_delta11.isInsert)(op) || !(0, import_delta11.isTextInsert)(op)) return false;
5744
+ if (!op || !(0, import_delta12.isInsert)(op) || !(0, import_delta12.isTextInsert)(op)) return false;
5555
5745
  if (!op.insert.includes("\n")) return false;
5556
5746
  return !!op.attributes && "table-row" in op.attributes;
5557
5747
  }
@@ -5560,8 +5750,8 @@ function extractTableRegion(ops, hintOpIdx) {
5560
5750
  let probeIdx = -1;
5561
5751
  for (let i = hintOpIdx; i < ops.length; i++) {
5562
5752
  const op = ops[i];
5563
- if (!op || !(0, import_delta11.isInsert)(op)) continue;
5564
- if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n")) {
5753
+ if (!op || !(0, import_delta12.isInsert)(op)) continue;
5754
+ if ((0, import_delta12.isTextInsert)(op) && op.insert.includes("\n")) {
5565
5755
  probeIdx = i;
5566
5756
  break;
5567
5757
  }
@@ -5571,8 +5761,8 @@ function extractTableRegion(ops, hintOpIdx) {
5571
5761
  let endOpIdx = probeIdx;
5572
5762
  for (let i = probeIdx + 1; i < ops.length; i++) {
5573
5763
  const op = ops[i];
5574
- if (!op || !(0, import_delta11.isInsert)(op)) break;
5575
- if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n")) {
5764
+ if (!op || !(0, import_delta12.isInsert)(op)) break;
5765
+ if ((0, import_delta12.isTextInsert)(op) && op.insert.includes("\n")) {
5576
5766
  if (isTableNewlineOp(op)) {
5577
5767
  endOpIdx = i;
5578
5768
  } else {
@@ -5583,11 +5773,11 @@ function extractTableRegion(ops, hintOpIdx) {
5583
5773
  let startOpIdx = 0;
5584
5774
  for (let i = probeIdx - 1; i >= 0; i--) {
5585
5775
  const op = ops[i];
5586
- if (!op || !(0, import_delta11.isInsert)(op)) {
5776
+ if (!op || !(0, import_delta12.isInsert)(op)) {
5587
5777
  startOpIdx = i + 1;
5588
5778
  break;
5589
5779
  }
5590
- if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n") && !isTableNewlineOp(op)) {
5780
+ if ((0, import_delta12.isTextInsert)(op) && op.insert.includes("\n") && !isTableNewlineOp(op)) {
5591
5781
  startOpIdx = i + 1;
5592
5782
  break;
5593
5783
  }