@meowdown/core 0.65.4 → 0.65.6

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.
Files changed (2) hide show
  1. package/dist/index.js +53 -61
  2. 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 || first.charCodeAt(0) !== 60 || !opensHTMLBlock(first);
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);
@@ -2568,6 +2572,15 @@ function defineMeowdownHorizontalRule() {
2568
2572
  return union(defineHorizontalRule(), defineHorizontalRuleMarkerAttr());
2569
2573
  }
2570
2574
 
2575
+ //#endregion
2576
+ //#region src/utils/non-prose-attrs.ts
2577
+ const NON_PROSE_ATTRS = {
2578
+ spellcheck: "false",
2579
+ autocorrect: "off",
2580
+ autocapitalize: "off",
2581
+ writingsuggestions: "false"
2582
+ };
2583
+
2571
2584
  //#endregion
2572
2585
  //#region src/extensions/html-comment.ts
2573
2586
  /**
@@ -2598,7 +2611,8 @@ function defineHTMLComment() {
2598
2611
  attrs: { content: { default: "" } },
2599
2612
  toDOM: (node) => ["div", {
2600
2613
  "data-html-comment": node.attrs.content,
2601
- style: "display: none"
2614
+ style: "display: none",
2615
+ ...NON_PROSE_ATTRS
2602
2616
  }],
2603
2617
  parseDOM: [{
2604
2618
  tag: "div[data-html-comment]",
@@ -3924,7 +3938,11 @@ function defineMdStrong() {
3924
3938
  function defineMdCode() {
3925
3939
  return defineMarkSpec({
3926
3940
  name: "mdCode",
3927
- toDOM: () => ["code", 0],
3941
+ toDOM: () => [
3942
+ "code",
3943
+ { ...NON_PROSE_ATTRS },
3944
+ 0
3945
+ ],
3928
3946
  parseDOM: [{ tag: "code" }]
3929
3947
  });
3930
3948
  }
@@ -3955,7 +3973,10 @@ function defineMdLinkUri() {
3955
3973
  inclusive: false,
3956
3974
  toDOM: () => [
3957
3975
  "span",
3958
- { class: "md-link-uri" },
3976
+ {
3977
+ class: "md-link-uri",
3978
+ ...NON_PROSE_ATTRS
3979
+ },
3959
3980
  0
3960
3981
  ],
3961
3982
  parseDOM: [{ tag: "span.md-link-uri" }]
@@ -5093,6 +5114,7 @@ var MathMarkView = class {
5093
5114
  });
5094
5115
  this.#contentDOM = document.createElement("span");
5095
5116
  this.#contentDOM.className = "md-math-view-content";
5117
+ for (const [name, value] of Object.entries(NON_PROSE_ATTRS)) this.#contentDOM.setAttribute(name, value);
5096
5118
  this.#dom.appendChild(this.#preview);
5097
5119
  this.#dom.appendChild(this.#contentDOM);
5098
5120
  this.#render();
@@ -6365,7 +6387,7 @@ function convertTaskItem(nodes, cursor, text, column) {
6365
6387
  cursor.parent();
6366
6388
  }
6367
6389
  if (isSpaceChar(text.charCodeAt(taskStart))) taskStart += 1;
6368
- const paragraph = buildParagraph(nodes, text.slice(taskStart, taskEnd), column);
6390
+ const paragraph = buildParagraph(nodes, readLeafText(cursor, text, taskStart, taskEnd), column);
6369
6391
  return {
6370
6392
  checked,
6371
6393
  taskMarker,
@@ -6567,68 +6589,36 @@ function trimTrailingNewlines(text) {
6567
6589
  while (end > 0 && text.charCodeAt(end - 1) === 10) end--;
6568
6590
  return text.slice(0, end);
6569
6591
  }
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
6592
  /**
6623
6593
  * Classify how `markdown` survives the editor's parse-then-serialize round trip.
6624
6594
  */
6625
6595
  function checkRoundTrip(markdown, options = {}) {
6626
6596
  const { frontmatter } = options;
6627
6597
  const doc = markdownToDoc(markdown, { frontmatter });
6628
- const serialized = docToMarkdown(doc, { frontmatter });
6629
- if (trimTrailingNewlines(serialized) === trimTrailingNewlines(markdown)) return "exact";
6630
- if (!containsInOrder(contentLines(serialized), contentLines(markdown))) return "lossy";
6631
- return markdownToDoc(serialized, { frontmatter }).eq(doc) ? "normalizing" : "lossy";
6598
+ let serialized = docToMarkdown(doc, { frontmatter });
6599
+ if (markdown === serialized) return "exact";
6600
+ markdown = trimTrailingNewlines(markdown);
6601
+ serialized = trimTrailingNewlines(serialized);
6602
+ if (markdown === serialized) return "exact";
6603
+ markdown = removeMarkdownStructure(markdown);
6604
+ serialized = removeMarkdownStructure(serialized);
6605
+ if (markdown === serialized) return "normalizing";
6606
+ markdown = removeNumberZeroPrefix(markdown);
6607
+ serialized = removeNumberZeroPrefix(serialized);
6608
+ if (markdown === serialized) return "normalizing";
6609
+ markdown = removeMathCodeBlockLanguage(markdown);
6610
+ serialized = removeMathCodeBlockLanguage(serialized);
6611
+ if (markdown === serialized) return "normalizing";
6612
+ return "lossy";
6613
+ }
6614
+ function removeMarkdownStructure(markdown) {
6615
+ return markdown.replaceAll(/[-+=_:|\\/[\]<>()`~$*#\s!]+/gu, "");
6616
+ }
6617
+ function removeNumberZeroPrefix(markdown) {
6618
+ return markdown.replaceAll(/0+/gu, "");
6619
+ }
6620
+ function removeMathCodeBlockLanguage(markdown) {
6621
+ return markdown.replaceAll(/math|latex/giu, "");
6632
6622
  }
6633
6623
 
6634
6624
  //#endregion
@@ -7734,6 +7724,8 @@ var ImageMarkView = class {
7734
7724
  this.#dom.className = "md-image-view md-atom-view";
7735
7725
  this.#contentDOM = document.createElement("span");
7736
7726
  this.#contentDOM.className = "md-image-view-content md-atom-view-content";
7727
+ this.#contentDOM.dataset.testid = "image-source";
7728
+ for (const [name, value] of Object.entries(NON_PROSE_ATTRS)) this.#contentDOM.setAttribute(name, value);
7737
7729
  const preview = this.#renderPreview();
7738
7730
  if (preview) {
7739
7731
  preview.contentEditable = "false";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/core",
3
3
  "type": "module",
4
- "version": "0.65.4",
4
+ "version": "0.65.6",
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.4"
46
+ "@meowdown/markdown": "^0.65.6"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@ocavue/tsconfig": "^0.7.1",