@orkestrel/markdown 0.0.8 → 0.0.10
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/src/core/index.cjs +146 -146
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +5 -5
- package/dist/src/core/index.d.ts +5 -5
- package/dist/src/core/index.js +146 -146
- package/dist/src/core/index.js.map +1 -1
- package/package.json +16 -13
package/dist/src/core/index.cjs
CHANGED
|
@@ -544,152 +544,6 @@ function parseBlocks(lines, depth) {
|
|
|
544
544
|
return blocks;
|
|
545
545
|
}
|
|
546
546
|
/**
|
|
547
|
-
* Collects a GFM table starting at a header row, parsing the header, the
|
|
548
|
-
* alignment row, and every contiguous body row that follows.
|
|
549
|
-
*
|
|
550
|
-
* @param lines - The markdown lines to scan.
|
|
551
|
-
* @param start - The index of the header row.
|
|
552
|
-
* @returns The parsed table node and the index of the first line after it.
|
|
553
|
-
*
|
|
554
|
-
* @example
|
|
555
|
-
* ```ts
|
|
556
|
-
* collectTable(['| a |', '| - |'], 0) // { node: { element: 'table', ... }, next: 2 }
|
|
557
|
-
* ```
|
|
558
|
-
*/
|
|
559
|
-
function collectTable(lines, start) {
|
|
560
|
-
const headerCells = splitTableRow(lines[start] ?? "");
|
|
561
|
-
const columns = headerCells.length;
|
|
562
|
-
const header = headerCells.map((cell) => parseInline(cell.trim()));
|
|
563
|
-
const align = delimiterToAlignments(lines[start + 1] ?? "");
|
|
564
|
-
const padded = [];
|
|
565
|
-
for (let column = 0; column < columns; column += 1) padded.push(align[column] ?? null);
|
|
566
|
-
const rows = [];
|
|
567
|
-
let index = start + 2;
|
|
568
|
-
while (index < lines.length && !isBlankLine(lines[index] ?? "") && (lines[index] ?? "").includes("|")) {
|
|
569
|
-
const cells = splitTableRow(lines[index] ?? "");
|
|
570
|
-
const row = [];
|
|
571
|
-
for (let column = 0; column < columns; column += 1) row.push(parseInline((cells[column] ?? "").trim()));
|
|
572
|
-
rows.push(row);
|
|
573
|
-
index += 1;
|
|
574
|
-
}
|
|
575
|
-
return {
|
|
576
|
-
node: {
|
|
577
|
-
element: "table",
|
|
578
|
-
header,
|
|
579
|
-
rows,
|
|
580
|
-
align: padded
|
|
581
|
-
},
|
|
582
|
-
next: index
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
/**
|
|
586
|
-
* Collects a list starting at the first item, gathering sibling items at the
|
|
587
|
-
* same indent/ordering and recursing into each item's own block content.
|
|
588
|
-
*
|
|
589
|
-
* @param lines - The markdown lines to scan.
|
|
590
|
-
* @param start - The index of the first list item.
|
|
591
|
-
* @param depth - The current recursion depth (each item recurses at `depth + 1`).
|
|
592
|
-
* @returns The parsed list node and the index of the first line after it.
|
|
593
|
-
*
|
|
594
|
-
* @example
|
|
595
|
-
* ```ts
|
|
596
|
-
* collectList(['- item'], 0, 0) // { node: { element: 'list', ... }, next: 1 }
|
|
597
|
-
* ```
|
|
598
|
-
*/
|
|
599
|
-
function collectList(lines, start, depth) {
|
|
600
|
-
const first = extractListItem(lines[start] ?? "");
|
|
601
|
-
const ordered = first?.ordered ?? false;
|
|
602
|
-
const startOrdinal = first?.start ?? 1;
|
|
603
|
-
const topIndent = first?.indent ?? 0;
|
|
604
|
-
const items = [];
|
|
605
|
-
const chain = [];
|
|
606
|
-
let nested = true;
|
|
607
|
-
for (let cursor = start; cursor < lines.length; cursor += 1) {
|
|
608
|
-
const parsed = extractListItem(lines[cursor] ?? "");
|
|
609
|
-
const previous = chain[chain.length - 1];
|
|
610
|
-
if (parsed === void 0 || previous !== void 0 && (previous.content.length > 0 || parsed.indent !== previous.marker)) {
|
|
611
|
-
nested = false;
|
|
612
|
-
break;
|
|
613
|
-
}
|
|
614
|
-
chain.push(parsed);
|
|
615
|
-
}
|
|
616
|
-
const remaining = 64 - depth;
|
|
617
|
-
if (nested && remaining > 0 && chain.length > remaining) {
|
|
618
|
-
const terminal = chain[remaining - 1];
|
|
619
|
-
if (terminal !== void 0) {
|
|
620
|
-
const source = [terminal.content];
|
|
621
|
-
for (let cursor = start + remaining; cursor < lines.length; cursor += 1) source.push((lines[cursor] ?? "").slice(terminal.marker));
|
|
622
|
-
let children = [{
|
|
623
|
-
element: "paragraph",
|
|
624
|
-
children: [{
|
|
625
|
-
element: "text",
|
|
626
|
-
value: source.join("\n")
|
|
627
|
-
}]
|
|
628
|
-
}];
|
|
629
|
-
let node;
|
|
630
|
-
for (let cursor = remaining - 1; cursor >= 0; cursor -= 1) {
|
|
631
|
-
const parsed = chain[cursor];
|
|
632
|
-
if (parsed === void 0) continue;
|
|
633
|
-
node = {
|
|
634
|
-
element: "list",
|
|
635
|
-
ordered: parsed.ordered,
|
|
636
|
-
start: parsed.start,
|
|
637
|
-
items: [{
|
|
638
|
-
element: "listItem",
|
|
639
|
-
children
|
|
640
|
-
}]
|
|
641
|
-
};
|
|
642
|
-
children = [node];
|
|
643
|
-
}
|
|
644
|
-
if (node !== void 0) return {
|
|
645
|
-
node,
|
|
646
|
-
next: lines.length
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
let index = start;
|
|
651
|
-
while (index < lines.length) {
|
|
652
|
-
const parsed = extractListItem(lines[index] ?? "");
|
|
653
|
-
if (!parsed || parsed.indent > topIndent || parsed.ordered !== ordered) break;
|
|
654
|
-
const itemLines = [parsed.content];
|
|
655
|
-
const continuation = parsed.marker;
|
|
656
|
-
index += 1;
|
|
657
|
-
while (index < lines.length) {
|
|
658
|
-
const next = lines[index] ?? "";
|
|
659
|
-
if (isBlankLine(next)) {
|
|
660
|
-
const after = lines[index + 1] ?? "";
|
|
661
|
-
if (index + 1 < lines.length && !isBlankLine(after) && countIndent(after) >= continuation) {
|
|
662
|
-
itemLines.push("");
|
|
663
|
-
index += 1;
|
|
664
|
-
continue;
|
|
665
|
-
}
|
|
666
|
-
break;
|
|
667
|
-
}
|
|
668
|
-
if (countIndent(next) >= continuation) {
|
|
669
|
-
itemLines.push(next.slice(continuation));
|
|
670
|
-
index += 1;
|
|
671
|
-
continue;
|
|
672
|
-
}
|
|
673
|
-
if (extractListItem(next) || startsBlock(lines, index)) break;
|
|
674
|
-
itemLines.push(next.trim());
|
|
675
|
-
index += 1;
|
|
676
|
-
}
|
|
677
|
-
items.push({
|
|
678
|
-
element: "listItem",
|
|
679
|
-
children: parseBlocks(itemLines, depth + 1)
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
return {
|
|
683
|
-
node: {
|
|
684
|
-
element: "list",
|
|
685
|
-
ordered,
|
|
686
|
-
start: startOrdinal,
|
|
687
|
-
items
|
|
688
|
-
},
|
|
689
|
-
next: index
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
547
|
* Parses a markdown string into a typed {@link MarkdownDocument} AST via the
|
|
694
548
|
* block phase.
|
|
695
549
|
*
|
|
@@ -1644,6 +1498,152 @@ function scanInline(source, from, to, depth = 0) {
|
|
|
1644
1498
|
return nodes;
|
|
1645
1499
|
}
|
|
1646
1500
|
/**
|
|
1501
|
+
* Collects a GFM table starting at a header row, parsing the header, the
|
|
1502
|
+
* alignment row, and every contiguous body row that follows.
|
|
1503
|
+
*
|
|
1504
|
+
* @param lines - The markdown lines to scan.
|
|
1505
|
+
* @param start - The index of the header row.
|
|
1506
|
+
* @returns The parsed table node and the index of the first line after it.
|
|
1507
|
+
*
|
|
1508
|
+
* @example
|
|
1509
|
+
* ```ts
|
|
1510
|
+
* collectTable(['| a |', '| - |'], 0) // { node: { element: 'table', ... }, next: 2 }
|
|
1511
|
+
* ```
|
|
1512
|
+
*/
|
|
1513
|
+
function collectTable(lines, start) {
|
|
1514
|
+
const headerCells = splitTableRow(lines[start] ?? "");
|
|
1515
|
+
const columns = headerCells.length;
|
|
1516
|
+
const header = headerCells.map((cell) => parseInline(cell.trim()));
|
|
1517
|
+
const align = delimiterToAlignments(lines[start + 1] ?? "");
|
|
1518
|
+
const padded = [];
|
|
1519
|
+
for (let column = 0; column < columns; column += 1) padded.push(align[column] ?? null);
|
|
1520
|
+
const rows = [];
|
|
1521
|
+
let index = start + 2;
|
|
1522
|
+
while (index < lines.length && !isBlankLine(lines[index] ?? "") && (lines[index] ?? "").includes("|")) {
|
|
1523
|
+
const cells = splitTableRow(lines[index] ?? "");
|
|
1524
|
+
const row = [];
|
|
1525
|
+
for (let column = 0; column < columns; column += 1) row.push(parseInline((cells[column] ?? "").trim()));
|
|
1526
|
+
rows.push(row);
|
|
1527
|
+
index += 1;
|
|
1528
|
+
}
|
|
1529
|
+
return {
|
|
1530
|
+
node: {
|
|
1531
|
+
element: "table",
|
|
1532
|
+
header,
|
|
1533
|
+
rows,
|
|
1534
|
+
align: padded
|
|
1535
|
+
},
|
|
1536
|
+
next: index
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
/**
|
|
1540
|
+
* Collects a list starting at the first item, gathering sibling items at the
|
|
1541
|
+
* same indent/ordering and recursing into each item's own block content.
|
|
1542
|
+
*
|
|
1543
|
+
* @param lines - The markdown lines to scan.
|
|
1544
|
+
* @param start - The index of the first list item.
|
|
1545
|
+
* @param depth - The current recursion depth (each item recurses at `depth + 1`).
|
|
1546
|
+
* @returns The parsed list node and the index of the first line after it.
|
|
1547
|
+
*
|
|
1548
|
+
* @example
|
|
1549
|
+
* ```ts
|
|
1550
|
+
* collectList(['- item'], 0, 0) // { node: { element: 'list', ... }, next: 1 }
|
|
1551
|
+
* ```
|
|
1552
|
+
*/
|
|
1553
|
+
function collectList(lines, start, depth) {
|
|
1554
|
+
const first = extractListItem(lines[start] ?? "");
|
|
1555
|
+
const ordered = first?.ordered ?? false;
|
|
1556
|
+
const startOrdinal = first?.start ?? 1;
|
|
1557
|
+
const topIndent = first?.indent ?? 0;
|
|
1558
|
+
const items = [];
|
|
1559
|
+
const chain = [];
|
|
1560
|
+
let nested = true;
|
|
1561
|
+
for (let cursor = start; cursor < lines.length; cursor += 1) {
|
|
1562
|
+
const parsed = extractListItem(lines[cursor] ?? "");
|
|
1563
|
+
const previous = chain[chain.length - 1];
|
|
1564
|
+
if (parsed === void 0 || previous !== void 0 && (previous.content.length > 0 || parsed.indent !== previous.marker)) {
|
|
1565
|
+
nested = false;
|
|
1566
|
+
break;
|
|
1567
|
+
}
|
|
1568
|
+
chain.push(parsed);
|
|
1569
|
+
}
|
|
1570
|
+
const remaining = 64 - depth;
|
|
1571
|
+
if (nested && remaining > 0 && chain.length > remaining) {
|
|
1572
|
+
const terminal = chain[remaining - 1];
|
|
1573
|
+
if (terminal !== void 0) {
|
|
1574
|
+
const source = [terminal.content];
|
|
1575
|
+
for (let cursor = start + remaining; cursor < lines.length; cursor += 1) source.push((lines[cursor] ?? "").slice(terminal.marker));
|
|
1576
|
+
let children = [{
|
|
1577
|
+
element: "paragraph",
|
|
1578
|
+
children: [{
|
|
1579
|
+
element: "text",
|
|
1580
|
+
value: source.join("\n")
|
|
1581
|
+
}]
|
|
1582
|
+
}];
|
|
1583
|
+
let node;
|
|
1584
|
+
for (let cursor = remaining - 1; cursor >= 0; cursor -= 1) {
|
|
1585
|
+
const parsed = chain[cursor];
|
|
1586
|
+
if (parsed === void 0) continue;
|
|
1587
|
+
node = {
|
|
1588
|
+
element: "list",
|
|
1589
|
+
ordered: parsed.ordered,
|
|
1590
|
+
start: parsed.start,
|
|
1591
|
+
items: [{
|
|
1592
|
+
element: "listItem",
|
|
1593
|
+
children
|
|
1594
|
+
}]
|
|
1595
|
+
};
|
|
1596
|
+
children = [node];
|
|
1597
|
+
}
|
|
1598
|
+
if (node !== void 0) return {
|
|
1599
|
+
node,
|
|
1600
|
+
next: lines.length
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
let index = start;
|
|
1605
|
+
while (index < lines.length) {
|
|
1606
|
+
const parsed = extractListItem(lines[index] ?? "");
|
|
1607
|
+
if (!parsed || parsed.indent > topIndent || parsed.ordered !== ordered) break;
|
|
1608
|
+
const itemLines = [parsed.content];
|
|
1609
|
+
const continuation = parsed.marker;
|
|
1610
|
+
index += 1;
|
|
1611
|
+
while (index < lines.length) {
|
|
1612
|
+
const next = lines[index] ?? "";
|
|
1613
|
+
if (isBlankLine(next)) {
|
|
1614
|
+
const after = lines[index + 1] ?? "";
|
|
1615
|
+
if (index + 1 < lines.length && !isBlankLine(after) && countIndent(after) >= continuation) {
|
|
1616
|
+
itemLines.push("");
|
|
1617
|
+
index += 1;
|
|
1618
|
+
continue;
|
|
1619
|
+
}
|
|
1620
|
+
break;
|
|
1621
|
+
}
|
|
1622
|
+
if (countIndent(next) >= continuation) {
|
|
1623
|
+
itemLines.push(next.slice(continuation));
|
|
1624
|
+
index += 1;
|
|
1625
|
+
continue;
|
|
1626
|
+
}
|
|
1627
|
+
if (extractListItem(next) || startsBlock(lines, index)) break;
|
|
1628
|
+
itemLines.push(next.trim());
|
|
1629
|
+
index += 1;
|
|
1630
|
+
}
|
|
1631
|
+
items.push({
|
|
1632
|
+
element: "listItem",
|
|
1633
|
+
children: parseBlocks(itemLines, depth + 1)
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
return {
|
|
1637
|
+
node: {
|
|
1638
|
+
element: "list",
|
|
1639
|
+
ordered,
|
|
1640
|
+
start: startOrdinal,
|
|
1641
|
+
items
|
|
1642
|
+
},
|
|
1643
|
+
next: index
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
1647
|
* Project a {@link MarkdownNode} into an unsanitized {@link HTMLDocument}.
|
|
1648
1648
|
*
|
|
1649
1649
|
* @remarks
|