@meowdown/core 0.65.4 → 0.65.5
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 +30 -58
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1456,6 +1456,9 @@ var MdOut = class {
|
|
|
1456
1456
|
suppressBlank() {
|
|
1457
1457
|
this.deferredBlankPrefix = null;
|
|
1458
1458
|
}
|
|
1459
|
+
get atContentStart() {
|
|
1460
|
+
return this.atLineStart && !this.pendingFirst?.endsWith("] ");
|
|
1461
|
+
}
|
|
1459
1462
|
/**
|
|
1460
1463
|
* Run `fn` with `linePrefix` extended by `continuation`.
|
|
1461
1464
|
* If `firstLine` is given, it replaces the prefix on the NEXT line only -
|
|
@@ -1695,6 +1698,7 @@ const HTML_BLOCK_OPEN = [
|
|
|
1695
1698
|
* line round-trips all the same, so one check serves both callers.
|
|
1696
1699
|
*/
|
|
1697
1700
|
function opensHTMLBlock(text) {
|
|
1701
|
+
if (text.charCodeAt(0) !== 60) return false;
|
|
1698
1702
|
const lineEnd = text.indexOf("\n");
|
|
1699
1703
|
const line = lineEnd < 0 ? text : text.slice(0, lineEnd);
|
|
1700
1704
|
for (const pattern of HTML_BLOCK_OPEN) if (pattern.test(line)) return true;
|
|
@@ -1799,7 +1803,7 @@ function emitInlineChildren(node, out) {
|
|
|
1799
1803
|
const count = node.childCount;
|
|
1800
1804
|
if (count === 0) return;
|
|
1801
1805
|
const first = node.child(0).text;
|
|
1802
|
-
const lazy = first == null ||
|
|
1806
|
+
const lazy = first == null || !out.atContentStart || !opensHTMLBlock(first);
|
|
1803
1807
|
for (let i = 0; i < count; i++) {
|
|
1804
1808
|
const child = node.child(i);
|
|
1805
1809
|
if (child.isText && child.text) out.write(child.text, lazy);
|
|
@@ -6365,7 +6369,7 @@ function convertTaskItem(nodes, cursor, text, column) {
|
|
|
6365
6369
|
cursor.parent();
|
|
6366
6370
|
}
|
|
6367
6371
|
if (isSpaceChar(text.charCodeAt(taskStart))) taskStart += 1;
|
|
6368
|
-
const paragraph = buildParagraph(nodes, text
|
|
6372
|
+
const paragraph = buildParagraph(nodes, readLeafText(cursor, text, taskStart, taskEnd), column);
|
|
6369
6373
|
return {
|
|
6370
6374
|
checked,
|
|
6371
6375
|
taskMarker,
|
|
@@ -6567,68 +6571,36 @@ function trimTrailingNewlines(text) {
|
|
|
6567
6571
|
while (end > 0 && text.charCodeAt(end - 1) === 10) end--;
|
|
6568
6572
|
return text.slice(0, end);
|
|
6569
6573
|
}
|
|
6570
|
-
const CONTAINER_PREFIX_RE = /^(?:[\s>]|[-+*](?=\s|$)|\d{1,9}[.)](?=\s|$))+/u;
|
|
6571
|
-
function stripWhitespace(line) {
|
|
6572
|
-
return line.replaceAll(/\s/gu, "");
|
|
6573
|
-
}
|
|
6574
|
-
function shortenFenceRun(line) {
|
|
6575
|
-
const fence = line.charCodeAt(0);
|
|
6576
|
-
if (fence !== 96 && fence !== 126) return line;
|
|
6577
|
-
let width = 1;
|
|
6578
|
-
while (line.charCodeAt(width) === fence) width++;
|
|
6579
|
-
return width > 3 ? line.slice(0, 3) + line.slice(width) : line;
|
|
6580
|
-
}
|
|
6581
|
-
const DELIMITER_CELL_RE = /^:?-+:?$/u;
|
|
6582
|
-
function reduceCell(cell) {
|
|
6583
|
-
return stripWhitespace(shortenFenceRun(cell.replace(CONTAINER_PREFIX_RE, "")));
|
|
6584
|
-
}
|
|
6585
|
-
function canonicalizeTableRow(line) {
|
|
6586
|
-
if (!line.includes("|")) return void 0;
|
|
6587
|
-
const cells = line.replace(/^\s*\|/u, "").replace(/\|\s*$/u, "").split("|").map(reduceCell);
|
|
6588
|
-
if (cells.every((cell) => cell === "" || DELIMITER_CELL_RE.test(cell))) return "";
|
|
6589
|
-
return cells.filter((cell) => cell !== "").join("|");
|
|
6590
|
-
}
|
|
6591
|
-
/**
|
|
6592
|
-
* The lines of `text` that carry content, each reduced to that content. A line
|
|
6593
|
-
* left empty by dropping its markers, whitespace, and table structure (a blank
|
|
6594
|
-
* line, a bare `>`, a list marker whose content is on the next line, a
|
|
6595
|
-
* delimiter row or a lone delimiter cell) carries none and is skipped.
|
|
6596
|
-
*/
|
|
6597
|
-
function contentLines(text) {
|
|
6598
|
-
const lines = [];
|
|
6599
|
-
for (const line of text.split("\n")) {
|
|
6600
|
-
const bare = line.replace(CONTAINER_PREFIX_RE, "");
|
|
6601
|
-
const content = canonicalizeTableRow(bare) ?? stripWhitespace(shortenFenceRun(bare));
|
|
6602
|
-
if (content !== "" && !DELIMITER_CELL_RE.test(content)) lines.push(content);
|
|
6603
|
-
}
|
|
6604
|
-
return lines;
|
|
6605
|
-
}
|
|
6606
|
-
/**
|
|
6607
|
-
* Whether `wanted` appears in `found` as an ordered subsequence.
|
|
6608
|
-
*
|
|
6609
|
-
* The serializer may write a line the source never had: an unterminated fenced
|
|
6610
|
-
* block gets the closing fence it was missing. Such a line carries no content,
|
|
6611
|
-
* which the document comparison proves - so only a content line that fails to
|
|
6612
|
-
* come back out is loss.
|
|
6613
|
-
*/
|
|
6614
|
-
function containsInOrder(found, wanted) {
|
|
6615
|
-
let index = 0;
|
|
6616
|
-
for (const line of found) {
|
|
6617
|
-
if (index === wanted.length) return true;
|
|
6618
|
-
if (line === wanted[index]) index++;
|
|
6619
|
-
}
|
|
6620
|
-
return index === wanted.length;
|
|
6621
|
-
}
|
|
6622
6574
|
/**
|
|
6623
6575
|
* Classify how `markdown` survives the editor's parse-then-serialize round trip.
|
|
6624
6576
|
*/
|
|
6625
6577
|
function checkRoundTrip(markdown, options = {}) {
|
|
6626
6578
|
const { frontmatter } = options;
|
|
6627
6579
|
const doc = markdownToDoc(markdown, { frontmatter });
|
|
6628
|
-
|
|
6629
|
-
if (
|
|
6630
|
-
|
|
6631
|
-
|
|
6580
|
+
let serialized = docToMarkdown(doc, { frontmatter });
|
|
6581
|
+
if (markdown === serialized) return "exact";
|
|
6582
|
+
markdown = trimTrailingNewlines(markdown);
|
|
6583
|
+
serialized = trimTrailingNewlines(serialized);
|
|
6584
|
+
if (markdown === serialized) return "exact";
|
|
6585
|
+
markdown = removeMarkdownStructure(markdown);
|
|
6586
|
+
serialized = removeMarkdownStructure(serialized);
|
|
6587
|
+
if (markdown === serialized) return "normalizing";
|
|
6588
|
+
markdown = removeNumberZeroPrefix(markdown);
|
|
6589
|
+
serialized = removeNumberZeroPrefix(serialized);
|
|
6590
|
+
if (markdown === serialized) return "normalizing";
|
|
6591
|
+
markdown = removeMathCodeBlockLanguage(markdown);
|
|
6592
|
+
serialized = removeMathCodeBlockLanguage(serialized);
|
|
6593
|
+
if (markdown === serialized) return "normalizing";
|
|
6594
|
+
return "lossy";
|
|
6595
|
+
}
|
|
6596
|
+
function removeMarkdownStructure(markdown) {
|
|
6597
|
+
return markdown.replaceAll(/[-+=_:|\\/[\]<>()`~$*#\s!]+/gu, "");
|
|
6598
|
+
}
|
|
6599
|
+
function removeNumberZeroPrefix(markdown) {
|
|
6600
|
+
return markdown.replaceAll(/0+/gu, "");
|
|
6601
|
+
}
|
|
6602
|
+
function removeMathCodeBlockLanguage(markdown) {
|
|
6603
|
+
return markdown.replaceAll(/math|latex/giu, "");
|
|
6632
6604
|
}
|
|
6633
6605
|
|
|
6634
6606
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meowdown/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.65.
|
|
4
|
+
"version": "0.65.5",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"remark-stringify": "^11.0.0",
|
|
44
44
|
"unicode-by-name": "^0.2.0",
|
|
45
45
|
"unified": "^11.0.5",
|
|
46
|
-
"@meowdown/markdown": "^0.65.
|
|
46
|
+
"@meowdown/markdown": "^0.65.5"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@ocavue/tsconfig": "^0.7.1",
|