@scrider/formatter 1.7.2 → 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 +197 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +194 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -333,6 +333,20 @@ function cloneDelta(delta) {
|
|
|
333
333
|
return new Delta(deepClone(delta.ops));
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
+
// src/conversion/markdown/table-header-markdown.ts
|
|
337
|
+
function isHeaderDashPlaceholder(text) {
|
|
338
|
+
const t = text.trim();
|
|
339
|
+
return t === "-" && t.length === 1;
|
|
340
|
+
}
|
|
341
|
+
function normalizeHeaderCellForParse(text, isHeaderRow) {
|
|
342
|
+
if (isHeaderRow && isHeaderDashPlaceholder(text)) return "";
|
|
343
|
+
return text;
|
|
344
|
+
}
|
|
345
|
+
function serializeHeaderCell(text) {
|
|
346
|
+
if (text.trim() === "") return "-";
|
|
347
|
+
return text;
|
|
348
|
+
}
|
|
349
|
+
|
|
336
350
|
// src/conversion/adapters/types.ts
|
|
337
351
|
var NODE_TYPE = {
|
|
338
352
|
ELEMENT_NODE: 1,
|
|
@@ -454,19 +468,21 @@ function renderGfmTable(data, context) {
|
|
|
454
468
|
if (headerRows === 0) {
|
|
455
469
|
const emptyParts = [];
|
|
456
470
|
for (let c = 0; c < cols; c++) {
|
|
457
|
-
emptyParts.push("
|
|
471
|
+
emptyParts.push("");
|
|
458
472
|
}
|
|
459
473
|
lines.push("| " + emptyParts.join(" | ") + " |");
|
|
460
474
|
lines.push(renderGfmSeparator(cols, data.colAligns));
|
|
461
475
|
}
|
|
462
476
|
for (let r = 0; r < rows; r++) {
|
|
463
477
|
const parts = [];
|
|
478
|
+
const isHeaderRow = headerRows > 0 && r < headerRows;
|
|
464
479
|
for (let c = 0; c < cols; c++) {
|
|
465
480
|
const cell = data.cells[`${r}:${c}`];
|
|
466
481
|
let text = "";
|
|
467
482
|
if (cell && context.renderDelta) {
|
|
468
483
|
text = stripCellContent(context.renderDelta(cell.ops));
|
|
469
484
|
}
|
|
485
|
+
if (isHeaderRow) text = serializeHeaderCell(text);
|
|
470
486
|
parts.push(text.replace(/\|/g, "\\|"));
|
|
471
487
|
}
|
|
472
488
|
lines.push("| " + parts.join(" | ") + " |");
|
|
@@ -4432,7 +4448,15 @@ function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = fa
|
|
|
4432
4448
|
if (headerRows.length > 0) {
|
|
4433
4449
|
for (const [, row] of headerRows) {
|
|
4434
4450
|
mdLines.push(
|
|
4435
|
-
renderMdRow(
|
|
4451
|
+
renderMdRow(
|
|
4452
|
+
row.cells,
|
|
4453
|
+
maxCol,
|
|
4454
|
+
embedRenderers,
|
|
4455
|
+
useLatexDelimiters,
|
|
4456
|
+
registry,
|
|
4457
|
+
softBreakStyle,
|
|
4458
|
+
true
|
|
4459
|
+
)
|
|
4436
4460
|
);
|
|
4437
4461
|
}
|
|
4438
4462
|
mdLines.push(renderMdSeparator(maxCol, colAligns));
|
|
@@ -4442,22 +4466,38 @@ function renderMarkdownTable(tableLines, embedRenderers, useLatexDelimiters = fa
|
|
|
4442
4466
|
emptyRow.set(col, { ops: [] });
|
|
4443
4467
|
}
|
|
4444
4468
|
mdLines.push(
|
|
4445
|
-
renderMdRow(
|
|
4469
|
+
renderMdRow(
|
|
4470
|
+
emptyRow,
|
|
4471
|
+
maxCol,
|
|
4472
|
+
embedRenderers,
|
|
4473
|
+
useLatexDelimiters,
|
|
4474
|
+
registry,
|
|
4475
|
+
softBreakStyle,
|
|
4476
|
+
false
|
|
4477
|
+
)
|
|
4446
4478
|
);
|
|
4447
4479
|
mdLines.push(renderMdSeparator(maxCol, colAligns));
|
|
4448
4480
|
}
|
|
4449
4481
|
for (const [, row] of bodyRows) {
|
|
4450
4482
|
mdLines.push(
|
|
4451
|
-
renderMdRow(
|
|
4483
|
+
renderMdRow(
|
|
4484
|
+
row.cells,
|
|
4485
|
+
maxCol,
|
|
4486
|
+
embedRenderers,
|
|
4487
|
+
useLatexDelimiters,
|
|
4488
|
+
registry,
|
|
4489
|
+
softBreakStyle,
|
|
4490
|
+
false
|
|
4491
|
+
)
|
|
4452
4492
|
);
|
|
4453
4493
|
}
|
|
4454
4494
|
return mdLines.join("\n");
|
|
4455
4495
|
}
|
|
4456
|
-
function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces") {
|
|
4496
|
+
function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false, registry, softBreakStyle = "spaces", isHeaderRow = false) {
|
|
4457
4497
|
const parts = [];
|
|
4458
4498
|
for (let col = 0; col <= maxCol; col++) {
|
|
4459
4499
|
const cell = cells.get(col);
|
|
4460
|
-
|
|
4500
|
+
let content = cell ? renderLineContent2(
|
|
4461
4501
|
cell.ops,
|
|
4462
4502
|
embedRenderers,
|
|
4463
4503
|
false,
|
|
@@ -4469,6 +4509,7 @@ function renderMdRow(cells, maxCol, embedRenderers, useLatexDelimiters = false,
|
|
|
4469
4509
|
true
|
|
4470
4510
|
// inTableCell — softBreak must use <br>, never " \n"
|
|
4471
4511
|
) : "";
|
|
4512
|
+
if (isHeaderRow) content = serializeHeaderCell(content);
|
|
4472
4513
|
parts.push(content.replace(/\|/g, "\\|"));
|
|
4473
4514
|
}
|
|
4474
4515
|
return "| " + parts.join(" | ") + " |";
|
|
@@ -4733,7 +4774,138 @@ function renderBlockFormat(content, attributes, orderedIndex, _strict) {
|
|
|
4733
4774
|
}
|
|
4734
4775
|
|
|
4735
4776
|
// src/conversion/markdown/markdown-to-delta.ts
|
|
4736
|
-
import { Delta as Delta10 } from "@scrider/delta";
|
|
4777
|
+
import { Delta as Delta10, isInsert as isInsert5 } from "@scrider/delta";
|
|
4778
|
+
|
|
4779
|
+
// src/conversion/markdown/table-header-normalize.ts
|
|
4780
|
+
import { isInsert as isInsert4 } from "@scrider/delta";
|
|
4781
|
+
function isTableCellTerminator(op) {
|
|
4782
|
+
return isInsert4(op) && typeof op.insert === "string" && op.insert === "\n" && op.attributes !== void 0 && typeof op.attributes["table-row"] === "number";
|
|
4783
|
+
}
|
|
4784
|
+
function normalizeSyntheticEmptyHeaderRow(ops) {
|
|
4785
|
+
const ends = [];
|
|
4786
|
+
let buf = "";
|
|
4787
|
+
const textOpIndicesByCell = [];
|
|
4788
|
+
let currentTextOps = [];
|
|
4789
|
+
for (let i = 0; i < ops.length; i++) {
|
|
4790
|
+
const op = ops[i];
|
|
4791
|
+
if (!isInsert4(op)) continue;
|
|
4792
|
+
if (typeof op.insert === "string" && op.insert !== "\n") {
|
|
4793
|
+
buf += op.insert;
|
|
4794
|
+
currentTextOps.push(i);
|
|
4795
|
+
continue;
|
|
4796
|
+
}
|
|
4797
|
+
if (isTableCellTerminator(op)) {
|
|
4798
|
+
const row = op.attributes["table-row"];
|
|
4799
|
+
const col = op.attributes["table-col"];
|
|
4800
|
+
ends.push({ row, col, newlineIdx: i, text: buf });
|
|
4801
|
+
textOpIndicesByCell.push([...currentTextOps]);
|
|
4802
|
+
buf = "";
|
|
4803
|
+
currentTextOps = [];
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
const row0 = ends.filter((e) => e.row === 0);
|
|
4807
|
+
if (row0.length === 0) return [...ops];
|
|
4808
|
+
if (!row0.every((e) => e.text.trim() === "")) return [...ops];
|
|
4809
|
+
if (row0.some((e) => isHeaderDashPlaceholder(e.text))) return [...ops];
|
|
4810
|
+
const remove = /* @__PURE__ */ new Set();
|
|
4811
|
+
for (let j = 0; j < ends.length; j++) {
|
|
4812
|
+
const end = ends[j];
|
|
4813
|
+
if (end.row !== 0) continue;
|
|
4814
|
+
remove.add(end.newlineIdx);
|
|
4815
|
+
for (const ti of textOpIndicesByCell[j] ?? []) remove.add(ti);
|
|
4816
|
+
}
|
|
4817
|
+
const out = [];
|
|
4818
|
+
for (let i = 0; i < ops.length; i++) {
|
|
4819
|
+
if (remove.has(i)) continue;
|
|
4820
|
+
const op = ops[i];
|
|
4821
|
+
if (!isTableCellTerminator(op)) {
|
|
4822
|
+
out.push(op);
|
|
4823
|
+
continue;
|
|
4824
|
+
}
|
|
4825
|
+
const row = op.attributes["table-row"];
|
|
4826
|
+
if (row === 0) continue;
|
|
4827
|
+
const attrs = { ...op.attributes };
|
|
4828
|
+
delete attrs["table-header"];
|
|
4829
|
+
out.push({
|
|
4830
|
+
insert: "\n",
|
|
4831
|
+
attributes: { ...attrs, "table-row": row - 1 }
|
|
4832
|
+
});
|
|
4833
|
+
}
|
|
4834
|
+
return out;
|
|
4835
|
+
}
|
|
4836
|
+
function normalizeHeaderDashPlaceholders(ops) {
|
|
4837
|
+
const ends = [];
|
|
4838
|
+
let buf = "";
|
|
4839
|
+
let currentTextOps = [];
|
|
4840
|
+
for (let i = 0; i < ops.length; i++) {
|
|
4841
|
+
const op = ops[i];
|
|
4842
|
+
if (!isInsert4(op)) continue;
|
|
4843
|
+
if (typeof op.insert === "string" && op.insert !== "\n") {
|
|
4844
|
+
buf += op.insert;
|
|
4845
|
+
currentTextOps.push(i);
|
|
4846
|
+
continue;
|
|
4847
|
+
}
|
|
4848
|
+
if (isTableCellTerminator(op)) {
|
|
4849
|
+
const row = op.attributes["table-row"];
|
|
4850
|
+
const isHeader = row === 0 && op.attributes["table-header"] === true;
|
|
4851
|
+
ends.push({ isHeader, textOpIndices: [...currentTextOps], text: buf });
|
|
4852
|
+
buf = "";
|
|
4853
|
+
currentTextOps = [];
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
const dashHeaderCells = ends.filter(
|
|
4857
|
+
(e) => e.isHeader && e.textOpIndices.length > 0 && isHeaderDashPlaceholder(e.text)
|
|
4858
|
+
);
|
|
4859
|
+
if (dashHeaderCells.length === 0) return [...ops];
|
|
4860
|
+
const replaceIndices = /* @__PURE__ */ new Set();
|
|
4861
|
+
for (const end of dashHeaderCells) {
|
|
4862
|
+
for (const ti of end.textOpIndices) replaceIndices.add(ti);
|
|
4863
|
+
}
|
|
4864
|
+
const out = [];
|
|
4865
|
+
for (let i = 0; i < ops.length; i++) {
|
|
4866
|
+
const op = ops[i];
|
|
4867
|
+
if (!replaceIndices.has(i)) {
|
|
4868
|
+
out.push(op);
|
|
4869
|
+
continue;
|
|
4870
|
+
}
|
|
4871
|
+
if (!isInsert4(op)) {
|
|
4872
|
+
out.push(op);
|
|
4873
|
+
continue;
|
|
4874
|
+
}
|
|
4875
|
+
if (typeof op.insert === "string" && op.insert !== "\n") {
|
|
4876
|
+
const normalized = normalizeHeaderCellForParse(op.insert, true);
|
|
4877
|
+
if (normalized.length === 0) continue;
|
|
4878
|
+
out.push(
|
|
4879
|
+
op.attributes ? { insert: normalized, attributes: op.attributes } : { insert: normalized }
|
|
4880
|
+
);
|
|
4881
|
+
} else {
|
|
4882
|
+
out.push(op);
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
return out;
|
|
4886
|
+
}
|
|
4887
|
+
function normalizeImportedTableOps(ops) {
|
|
4888
|
+
if (ops.length === 0) return [...ops];
|
|
4889
|
+
const ends = [];
|
|
4890
|
+
let buf = "";
|
|
4891
|
+
for (const op of ops) {
|
|
4892
|
+
if (!isInsert4(op)) continue;
|
|
4893
|
+
if (typeof op.insert === "string" && op.insert !== "\n") {
|
|
4894
|
+
buf += op.insert;
|
|
4895
|
+
continue;
|
|
4896
|
+
}
|
|
4897
|
+
if (isTableCellTerminator(op)) {
|
|
4898
|
+
ends.push({ row: op.attributes["table-row"], text: buf });
|
|
4899
|
+
buf = "";
|
|
4900
|
+
}
|
|
4901
|
+
}
|
|
4902
|
+
const row0 = ends.filter((e) => e.row === 0);
|
|
4903
|
+
const headerless = row0.length > 0 && row0.every((e) => e.text.trim() === "") && !row0.some((e) => isHeaderDashPlaceholder(e.text));
|
|
4904
|
+
if (headerless) return normalizeSyntheticEmptyHeaderRow(ops);
|
|
4905
|
+
return normalizeHeaderDashPlaceholders(ops);
|
|
4906
|
+
}
|
|
4907
|
+
|
|
4908
|
+
// src/conversion/markdown/markdown-to-delta.ts
|
|
4737
4909
|
var remarkParse = null;
|
|
4738
4910
|
var remarkGfm = null;
|
|
4739
4911
|
var remarkMath = null;
|
|
@@ -5222,6 +5394,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
5222
5394
|
}
|
|
5223
5395
|
function processTable(node) {
|
|
5224
5396
|
if (!node.children) return;
|
|
5397
|
+
const tableStart = delta.ops.length;
|
|
5225
5398
|
const aligns = node.align || [];
|
|
5226
5399
|
for (let rowIdx = 0; rowIdx < node.children.length; rowIdx++) {
|
|
5227
5400
|
const rowNode = node.children[rowIdx];
|
|
@@ -5250,6 +5423,15 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
5250
5423
|
context.pushNewline(cellBlockAttrs);
|
|
5251
5424
|
}
|
|
5252
5425
|
}
|
|
5426
|
+
const tableOps = delta.ops.splice(tableStart);
|
|
5427
|
+
for (const op of normalizeImportedTableOps(tableOps)) {
|
|
5428
|
+
if (!isInsert5(op)) continue;
|
|
5429
|
+
if (op.attributes && Object.keys(op.attributes).length > 0) {
|
|
5430
|
+
delta.insert(op.insert, op.attributes);
|
|
5431
|
+
} else {
|
|
5432
|
+
delta.insert(op.insert);
|
|
5433
|
+
}
|
|
5434
|
+
}
|
|
5253
5435
|
}
|
|
5254
5436
|
function isBlockLevelHtml(html) {
|
|
5255
5437
|
return /^\s*<(div|table|section|article|aside|nav|header|footer|figure|pre|hr|ol|ul|dl|details|iframe|video)\b/i.test(
|
|
@@ -5431,9 +5613,9 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
5431
5613
|
}
|
|
5432
5614
|
|
|
5433
5615
|
// src/conversion/markdown/table-region.ts
|
|
5434
|
-
import { isInsert as
|
|
5616
|
+
import { isInsert as isInsert6, isTextInsert as isTextInsert3 } from "@scrider/delta";
|
|
5435
5617
|
function isTableNewlineOp(op) {
|
|
5436
|
-
if (!op || !
|
|
5618
|
+
if (!op || !isInsert6(op) || !isTextInsert3(op)) return false;
|
|
5437
5619
|
if (!op.insert.includes("\n")) return false;
|
|
5438
5620
|
return !!op.attributes && "table-row" in op.attributes;
|
|
5439
5621
|
}
|
|
@@ -5442,7 +5624,7 @@ function extractTableRegion(ops, hintOpIdx) {
|
|
|
5442
5624
|
let probeIdx = -1;
|
|
5443
5625
|
for (let i = hintOpIdx; i < ops.length; i++) {
|
|
5444
5626
|
const op = ops[i];
|
|
5445
|
-
if (!op || !
|
|
5627
|
+
if (!op || !isInsert6(op)) continue;
|
|
5446
5628
|
if (isTextInsert3(op) && op.insert.includes("\n")) {
|
|
5447
5629
|
probeIdx = i;
|
|
5448
5630
|
break;
|
|
@@ -5453,7 +5635,7 @@ function extractTableRegion(ops, hintOpIdx) {
|
|
|
5453
5635
|
let endOpIdx = probeIdx;
|
|
5454
5636
|
for (let i = probeIdx + 1; i < ops.length; i++) {
|
|
5455
5637
|
const op = ops[i];
|
|
5456
|
-
if (!op || !
|
|
5638
|
+
if (!op || !isInsert6(op)) break;
|
|
5457
5639
|
if (isTextInsert3(op) && op.insert.includes("\n")) {
|
|
5458
5640
|
if (isTableNewlineOp(op)) {
|
|
5459
5641
|
endOpIdx = i;
|
|
@@ -5465,7 +5647,7 @@ function extractTableRegion(ops, hintOpIdx) {
|
|
|
5465
5647
|
let startOpIdx = 0;
|
|
5466
5648
|
for (let i = probeIdx - 1; i >= 0; i--) {
|
|
5467
5649
|
const op = ops[i];
|
|
5468
|
-
if (!op || !
|
|
5650
|
+
if (!op || !isInsert6(op)) {
|
|
5469
5651
|
startOpIdx = i + 1;
|
|
5470
5652
|
break;
|
|
5471
5653
|
}
|