markdown-codec 6.7.4 → 6.7.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 (72) hide show
  1. package/README.md +2 -1
  2. package/dist/block/block.cjs +19 -37
  3. package/dist/block/block.js +20 -38
  4. package/dist/block/definitions.cjs +1 -5
  5. package/dist/block/definitions.js +1 -5
  6. package/dist/block/line.cjs +2 -2
  7. package/dist/block/line.js +2 -2
  8. package/dist/block/list.cjs +7 -14
  9. package/dist/block/list.js +7 -14
  10. package/dist/block/node.cjs +3 -3
  11. package/dist/block/node.d.cts +2 -2
  12. package/dist/block/node.d.ts +2 -2
  13. package/dist/block/node.js +3 -3
  14. package/dist/block/table.cjs +3 -4
  15. package/dist/block/table.js +3 -4
  16. package/dist/codec.d.cts +36 -36
  17. package/dist/codec.d.ts +36 -36
  18. package/dist/emit/emit.cjs +58 -62
  19. package/dist/emit/emit.js +58 -62
  20. package/dist/emit/inline.cjs +18 -12
  21. package/dist/emit/inline.js +18 -12
  22. package/dist/emit/table.cjs +2 -2
  23. package/dist/emit/table.js +2 -2
  24. package/dist/html/html-table.cjs +14 -22
  25. package/dist/html/html-table.js +14 -22
  26. package/dist/html/html.cjs +0 -2
  27. package/dist/html/html.js +0 -2
  28. package/dist/html/render.cjs +3 -11
  29. package/dist/html/render.js +3 -11
  30. package/dist/image/image.cjs +8 -57
  31. package/dist/image/image.d.cts +2 -2
  32. package/dist/image/image.d.ts +2 -2
  33. package/dist/image/image.js +9 -56
  34. package/dist/{image-BtmTG4_a.d.cts → image-83yql5ES.d.cts} +1 -3
  35. package/dist/{image-BtmTG4_a.d.ts → image-83yql5ES.d.ts} +1 -3
  36. package/dist/{image-B5L0HpAJ.d.cts → image-B6p0Ovgy.d.cts} +1 -1
  37. package/dist/{image-C390OIB3.d.ts → image-gR1vISI0.d.ts} +1 -1
  38. package/dist/index.d.cts +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/inline/chars.cjs +3 -6
  41. package/dist/inline/chars.js +3 -6
  42. package/dist/inline/delimiter.cjs +5 -16
  43. package/dist/inline/delimiter.d.cts +2 -2
  44. package/dist/inline/delimiter.d.ts +2 -2
  45. package/dist/inline/delimiter.js +5 -16
  46. package/dist/inline/entity.cjs +6 -10
  47. package/dist/inline/entity.js +6 -10
  48. package/dist/inline/gfm-autolink.cjs +20 -19
  49. package/dist/inline/gfm-autolink.js +20 -19
  50. package/dist/inline/inline.cjs +29 -39
  51. package/dist/inline/inline.js +30 -40
  52. package/dist/inline/link.cjs +4 -5
  53. package/dist/inline/link.js +4 -5
  54. package/dist/lower/front-matter.cjs +4 -8
  55. package/dist/lower/front-matter.js +4 -8
  56. package/dist/lower/image.cjs +3 -2
  57. package/dist/lower/image.d.cts +1 -1
  58. package/dist/lower/image.d.ts +1 -1
  59. package/dist/lower/image.js +2 -1
  60. package/dist/lower/inline.cjs +0 -2
  61. package/dist/lower/inline.js +0 -2
  62. package/dist/lower/lower.cjs +7 -10
  63. package/dist/lower/lower.js +7 -10
  64. package/dist/options/options.d.cts +1 -1
  65. package/dist/options/options.d.ts +1 -1
  66. package/dist/read.cjs +2 -2
  67. package/dist/read.js +2 -2
  68. package/dist/scan/scan.cjs +1 -3
  69. package/dist/scan/scan.js +1 -3
  70. package/dist/shared/list-id.cjs +1 -1
  71. package/dist/shared/list-id.js +1 -1
  72. package/package.json +2 -1
@@ -1,7 +1,6 @@
1
1
  import { InlineNode } from "./node.js";
2
2
  //#region src/inline/delimiter.d.ts
3
3
  type DelimiterChar = "*" | "_" | "~";
4
- declare function isDelimiterChar(char: string): char is DelimiterChar;
5
4
  interface Delimiter {
6
5
  readonly char: DelimiterChar;
7
6
  count: number;
@@ -23,7 +22,8 @@ declare class DelimiterStack {
23
22
  push(char: DelimiterChar, run: DelimiterRun, node: InlineNode): void;
24
23
  remove(delimiter: Delimiter): void;
25
24
  }
25
+ declare function closerSignature(closer: Delimiter): string;
26
26
  type EmphasisWrapperFactory = (kind: "emphasis" | "strong" | "strikethrough", marker: DelimiterChar) => InlineNode;
27
27
  declare function processEmphasis(stack: DelimiterStack, stackBottom: Delimiter | undefined, createWrapper: EmphasisWrapperFactory): void;
28
28
  //#endregion
29
- export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, isDelimiterChar, processEmphasis, scanDelimiterRun };
29
+ export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature, processEmphasis, scanDelimiterRun };
@@ -1,8 +1,5 @@
1
1
  import { codePointAt, codePointBefore, isUnicodePunctuation, isUnicodeWhitespace } from "./chars.js";
2
2
  //#region src/inline/delimiter.ts
3
- function isDelimiterChar(char) {
4
- return char === "*" || char === "_" || char === "~";
5
- }
6
3
  const MAX_STRIKETHROUGH_RUN = 2;
7
4
  function scanDelimiterRun(text, start, char) {
8
5
  let count = 0;
@@ -62,7 +59,6 @@ function canMatch(opener, closer) {
62
59
  return !isRuleOfThreeBlocked(opener, closer);
63
60
  }
64
61
  function delimitersConsumedByMatch(opener, closer) {
65
- if (closer.char === "~") return closer.count;
66
62
  return closer.count >= 2 && opener.count >= 2 ? 2 : 1;
67
63
  }
68
64
  function wrapperKindFor(closer, used) {
@@ -82,7 +78,7 @@ function processEmphasis(stack, stackBottom, createWrapper) {
82
78
  const floor = openersFloor.has(signature) ? openersFloor.get(signature) : stackBottom;
83
79
  let opener = closer.previous;
84
80
  let matchedOpener;
85
- while (opener !== void 0 && opener !== stackBottom && opener !== floor) {
81
+ while (opener !== void 0 && opener !== floor) {
86
82
  if (canMatch(opener, closer)) {
87
83
  matchedOpener = opener;
88
84
  break;
@@ -93,7 +89,6 @@ function processEmphasis(stack, stackBottom, createWrapper) {
93
89
  if (matchedOpener === void 0) {
94
90
  closer = closer.next;
95
91
  openersFloor.set(signature, failedCloser.previous);
96
- if (!failedCloser.canOpen) stack.remove(failedCloser);
97
92
  continue;
98
93
  }
99
94
  const used = delimitersConsumedByMatch(matchedOpener, closer);
@@ -111,16 +106,10 @@ function processEmphasis(stack, stackBottom, createWrapper) {
111
106
  moving = following;
112
107
  }
113
108
  openerNode.insertAfter(wrapper);
114
- if (matchedOpener.next !== closer) {
115
- matchedOpener.next = closer;
116
- closer.previous = matchedOpener;
117
- }
118
- if (matchedOpener.count === 0) {
119
- openerNode.unlink();
120
- stack.remove(matchedOpener);
121
- }
109
+ matchedOpener.next = closer;
110
+ closer.previous = matchedOpener;
111
+ if (matchedOpener.count === 0) stack.remove(matchedOpener);
122
112
  if (closer.count === 0) {
123
- closerNode.unlink();
124
113
  const following = closer.next;
125
114
  stack.remove(closer);
126
115
  closer = following;
@@ -129,4 +118,4 @@ function processEmphasis(stack, stackBottom, createWrapper) {
129
118
  while (stack.top !== void 0 && stack.top !== stackBottom) stack.remove(stack.top);
130
119
  }
131
120
  //#endregion
132
- export { DelimiterStack, isDelimiterChar, processEmphasis, scanDelimiterRun };
121
+ export { DelimiterStack, closerSignature, processEmphasis, scanDelimiterRun };
@@ -12,7 +12,6 @@ function codepointToString(codepoint) {
12
12
  return String.fromCodePoint(codepoint);
13
13
  }
14
14
  function matchEntity(text, start) {
15
- if (text.charAt(start) !== "&") return;
16
15
  const match = ENTITY_PATTERN.exec(text.slice(start));
17
16
  if (match === null) return;
18
17
  const [raw, hex, decimal, name] = match;
@@ -33,10 +32,9 @@ function matchEntity(text, start) {
33
32
  };
34
33
  }
35
34
  function unescapeString(text) {
36
- if (!text.includes("\\") && !text.includes("&")) return text;
37
35
  let result = "";
38
36
  let index = 0;
39
- while (index < text.length) {
37
+ while (text.charAt(index) !== "") {
40
38
  const char = text.charAt(index);
41
39
  if (char === "\\") {
42
40
  const next = text.charAt(index + 1);
@@ -49,13 +47,11 @@ function unescapeString(text) {
49
47
  index += 1;
50
48
  continue;
51
49
  }
52
- if (char === "&") {
53
- const entity = matchEntity(text, index);
54
- if (entity !== void 0) {
55
- result += entity.value;
56
- index += entity.raw.length;
57
- continue;
58
- }
50
+ const entity = matchEntity(text, index);
51
+ if (entity !== void 0) {
52
+ result += entity.value;
53
+ index += entity.raw.length;
54
+ continue;
59
55
  }
60
56
  result += char;
61
57
  index += 1;
@@ -11,7 +11,6 @@ function codepointToString(codepoint) {
11
11
  return String.fromCodePoint(codepoint);
12
12
  }
13
13
  function matchEntity(text, start) {
14
- if (text.charAt(start) !== "&") return;
15
14
  const match = ENTITY_PATTERN.exec(text.slice(start));
16
15
  if (match === null) return;
17
16
  const [raw, hex, decimal, name] = match;
@@ -32,10 +31,9 @@ function matchEntity(text, start) {
32
31
  };
33
32
  }
34
33
  function unescapeString(text) {
35
- if (!text.includes("\\") && !text.includes("&")) return text;
36
34
  let result = "";
37
35
  let index = 0;
38
- while (index < text.length) {
36
+ while (text.charAt(index) !== "") {
39
37
  const char = text.charAt(index);
40
38
  if (char === "\\") {
41
39
  const next = text.charAt(index + 1);
@@ -48,13 +46,11 @@ function unescapeString(text) {
48
46
  index += 1;
49
47
  continue;
50
48
  }
51
- if (char === "&") {
52
- const entity = matchEntity(text, index);
53
- if (entity !== void 0) {
54
- result += entity.value;
55
- index += entity.raw.length;
56
- continue;
57
- }
49
+ const entity = matchEntity(text, index);
50
+ if (entity !== void 0) {
51
+ result += entity.value;
52
+ index += entity.raw.length;
53
+ continue;
58
54
  }
59
55
  result += char;
60
56
  index += 1;
@@ -37,7 +37,7 @@ const OPAQUE_KINDS = /* @__PURE__ */ new Set([
37
37
  "autolink"
38
38
  ]);
39
39
  function isWhitespace(char) {
40
- return char === "" || char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
40
+ return char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
41
41
  }
42
42
  function isValidStartBoundary(text, index) {
43
43
  if (index === 0) return true;
@@ -54,28 +54,31 @@ function trimTrailingPunctuation(candidate) {
54
54
  let end = candidate.length;
55
55
  for (;;) {
56
56
  const before = end;
57
- while (end > 0 && TRAILING_PUNCTUATION.has(candidate.charAt(end - 1))) end -= 1;
58
- if (end > 0 && candidate.charAt(end - 1) === ")") {
57
+ while (TRAILING_PUNCTUATION.has(candidate.charAt(end - 1))) end -= 1;
58
+ if (candidate.charAt(end - 1) === ")") {
59
59
  const slice = candidate.slice(0, end);
60
60
  if (slice.split(")").length > slice.split("(").length) end -= 1;
61
61
  }
62
- if (end > 0 && candidate.charAt(end - 1) === ";") {
63
- const entityTail = ENTITY_TAIL_PATTERN.exec(candidate.slice(0, end));
64
- if (entityTail !== null) end -= entityTail[0].length;
65
- }
62
+ const entityTail = ENTITY_TAIL_PATTERN.exec(candidate.slice(0, end));
63
+ if (entityTail !== null) end -= entityTail[0].length;
66
64
  if (end === before) return candidate.slice(0, end);
67
65
  }
68
66
  }
69
67
  function scanRawCandidate(text, start) {
70
68
  let end = start;
71
- while (end < text.length && !isWhitespace(text.charAt(end)) && text.charAt(end) !== "<") end += 1;
72
- return text.slice(start, end);
69
+ for (;;) {
70
+ const char = text.charAt(end);
71
+ if (char === "" || isWhitespace(char) || char === "<") return text.slice(start, end);
72
+ end += 1;
73
+ }
73
74
  }
74
75
  function matchPrefixed(text, index, prefixLength, destinationPrefix, requireValidDomain) {
75
76
  const trimmed = trimTrailingPunctuation(scanRawCandidate(text, index));
76
- if (trimmed.length <= prefixLength) return;
77
+ const afterPrefix = trimmed.slice(prefixLength);
78
+ if (afterPrefix === "") return;
77
79
  if (requireValidDomain) {
78
- if (!isValidDomain(trimmed.slice(prefixLength).split(/[/?#]/)[0] ?? "")) return;
80
+ const domain = afterPrefix.split(/[/?#]/)[0];
81
+ if (!isValidDomain(domain)) return;
79
82
  }
80
83
  return {
81
84
  text: trimmed,
@@ -85,17 +88,17 @@ function matchPrefixed(text, index, prefixLength, destinationPrefix, requireVali
85
88
  }
86
89
  function scanEmailDomain(text, start) {
87
90
  let end = start;
88
- while (end < text.length && EMAIL_DOMAIN_PATTERN.test(text.charAt(end))) end += 1;
91
+ while (EMAIL_DOMAIN_PATTERN.test(text.charAt(end))) end += 1;
89
92
  return text.slice(start, end);
90
93
  }
91
94
  function matchEmailAt(text, atIndex) {
92
95
  let start = atIndex;
93
- while (start > 0 && EMAIL_LOCAL_PART_PATTERN.test(text.charAt(start - 1))) start -= 1;
96
+ while (EMAIL_LOCAL_PART_PATTERN.test(text.charAt(start - 1))) start -= 1;
94
97
  if (start === atIndex || !isValidStartBoundary(text, start)) return;
95
98
  const local = text.slice(start, atIndex);
96
99
  if (local.startsWith(".") || local.endsWith(".")) return;
97
100
  const domain = scanEmailDomain(text, atIndex + 1).replace(/\.+$/, "");
98
- if (domain.endsWith("-") || domain.endsWith("_") || !isValidDomain(domain)) return;
101
+ if (domain.endsWith("-") || !isValidDomain(domain)) return;
99
102
  const address = `${local}@${domain}`;
100
103
  return {
101
104
  text: address,
@@ -117,11 +120,10 @@ function expandTextNode(node) {
117
120
  const text = node.literal;
118
121
  let cursor = 0;
119
122
  let anchor = node;
120
- let matches = 0;
121
123
  let index = 0;
122
- while (index < text.length) {
124
+ while (text.charAt(index) !== "") {
123
125
  const found = findAutolinkAt(text, index);
124
- if (found === void 0 || found.start < cursor) {
126
+ if (found === void 0) {
125
127
  index += 1;
126
128
  continue;
127
129
  }
@@ -136,10 +138,9 @@ function expandTextNode(node) {
136
138
  anchor.insertAfter(link);
137
139
  anchor = link;
138
140
  cursor = found.start + found.text.length;
139
- matches += 1;
140
141
  index = cursor;
141
142
  }
142
- if (matches === 0) return;
143
+ if (anchor === node) return;
143
144
  if (cursor < text.length) anchor.insertAfter(require_inline_node.createTextNode(text.slice(cursor)));
144
145
  node.unlink();
145
146
  }
@@ -36,7 +36,7 @@ const OPAQUE_KINDS = /* @__PURE__ */ new Set([
36
36
  "autolink"
37
37
  ]);
38
38
  function isWhitespace(char) {
39
- return char === "" || char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
39
+ return char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
40
40
  }
41
41
  function isValidStartBoundary(text, index) {
42
42
  if (index === 0) return true;
@@ -53,28 +53,31 @@ function trimTrailingPunctuation(candidate) {
53
53
  let end = candidate.length;
54
54
  for (;;) {
55
55
  const before = end;
56
- while (end > 0 && TRAILING_PUNCTUATION.has(candidate.charAt(end - 1))) end -= 1;
57
- if (end > 0 && candidate.charAt(end - 1) === ")") {
56
+ while (TRAILING_PUNCTUATION.has(candidate.charAt(end - 1))) end -= 1;
57
+ if (candidate.charAt(end - 1) === ")") {
58
58
  const slice = candidate.slice(0, end);
59
59
  if (slice.split(")").length > slice.split("(").length) end -= 1;
60
60
  }
61
- if (end > 0 && candidate.charAt(end - 1) === ";") {
62
- const entityTail = ENTITY_TAIL_PATTERN.exec(candidate.slice(0, end));
63
- if (entityTail !== null) end -= entityTail[0].length;
64
- }
61
+ const entityTail = ENTITY_TAIL_PATTERN.exec(candidate.slice(0, end));
62
+ if (entityTail !== null) end -= entityTail[0].length;
65
63
  if (end === before) return candidate.slice(0, end);
66
64
  }
67
65
  }
68
66
  function scanRawCandidate(text, start) {
69
67
  let end = start;
70
- while (end < text.length && !isWhitespace(text.charAt(end)) && text.charAt(end) !== "<") end += 1;
71
- return text.slice(start, end);
68
+ for (;;) {
69
+ const char = text.charAt(end);
70
+ if (char === "" || isWhitespace(char) || char === "<") return text.slice(start, end);
71
+ end += 1;
72
+ }
72
73
  }
73
74
  function matchPrefixed(text, index, prefixLength, destinationPrefix, requireValidDomain) {
74
75
  const trimmed = trimTrailingPunctuation(scanRawCandidate(text, index));
75
- if (trimmed.length <= prefixLength) return;
76
+ const afterPrefix = trimmed.slice(prefixLength);
77
+ if (afterPrefix === "") return;
76
78
  if (requireValidDomain) {
77
- if (!isValidDomain(trimmed.slice(prefixLength).split(/[/?#]/)[0] ?? "")) return;
79
+ const domain = afterPrefix.split(/[/?#]/)[0];
80
+ if (!isValidDomain(domain)) return;
78
81
  }
79
82
  return {
80
83
  text: trimmed,
@@ -84,17 +87,17 @@ function matchPrefixed(text, index, prefixLength, destinationPrefix, requireVali
84
87
  }
85
88
  function scanEmailDomain(text, start) {
86
89
  let end = start;
87
- while (end < text.length && EMAIL_DOMAIN_PATTERN.test(text.charAt(end))) end += 1;
90
+ while (EMAIL_DOMAIN_PATTERN.test(text.charAt(end))) end += 1;
88
91
  return text.slice(start, end);
89
92
  }
90
93
  function matchEmailAt(text, atIndex) {
91
94
  let start = atIndex;
92
- while (start > 0 && EMAIL_LOCAL_PART_PATTERN.test(text.charAt(start - 1))) start -= 1;
95
+ while (EMAIL_LOCAL_PART_PATTERN.test(text.charAt(start - 1))) start -= 1;
93
96
  if (start === atIndex || !isValidStartBoundary(text, start)) return;
94
97
  const local = text.slice(start, atIndex);
95
98
  if (local.startsWith(".") || local.endsWith(".")) return;
96
99
  const domain = scanEmailDomain(text, atIndex + 1).replace(/\.+$/, "");
97
- if (domain.endsWith("-") || domain.endsWith("_") || !isValidDomain(domain)) return;
100
+ if (domain.endsWith("-") || !isValidDomain(domain)) return;
98
101
  const address = `${local}@${domain}`;
99
102
  return {
100
103
  text: address,
@@ -116,11 +119,10 @@ function expandTextNode(node) {
116
119
  const text = node.literal;
117
120
  let cursor = 0;
118
121
  let anchor = node;
119
- let matches = 0;
120
122
  let index = 0;
121
- while (index < text.length) {
123
+ while (text.charAt(index) !== "") {
122
124
  const found = findAutolinkAt(text, index);
123
- if (found === void 0 || found.start < cursor) {
125
+ if (found === void 0) {
124
126
  index += 1;
125
127
  continue;
126
128
  }
@@ -135,10 +137,9 @@ function expandTextNode(node) {
135
137
  anchor.insertAfter(link);
136
138
  anchor = link;
137
139
  cursor = found.start + found.text.length;
138
- matches += 1;
139
140
  index = cursor;
140
141
  }
141
- if (matches === 0) return;
142
+ if (anchor === node) return;
142
143
  if (cursor < text.length) anchor.insertAfter(createTextNode(text.slice(cursor)));
143
144
  node.unlink();
144
145
  }
@@ -12,7 +12,7 @@ const require_inline_math = require("./math.cjs");
12
12
  const PLAIN_TEXT_PATTERN = /[^\n`[\]\\!<&*_~]+/y;
13
13
  const URI_AUTOLINK_PATTERN = /<[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>]*>/y;
14
14
  const EMAIL_AUTOLINK_PATTERN = /<([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/y;
15
- const HARD_BREAK_SPACES = " ";
15
+ const HARD_BREAK_SPACE_COUNT = 2;
16
16
  const EMPTY_LABEL_LENGTH = 2;
17
17
  function stripOneSurroundingSpace(content) {
18
18
  if (content.startsWith(" ") && content.endsWith(" ") && /[^ ]/.test(content)) return content.slice(1, content.length - 1);
@@ -45,6 +45,13 @@ var InlineParser = class {
45
45
  return this.container;
46
46
  }
47
47
  step() {
48
+ PLAIN_TEXT_PATTERN.lastIndex = this.pos;
49
+ const plain = PLAIN_TEXT_PATTERN.exec(this.text);
50
+ if (plain !== null) {
51
+ this.appendText(plain[0]);
52
+ this.pos += plain[0].length;
53
+ return;
54
+ }
48
55
  const char = this.text.charAt(this.pos);
49
56
  switch (char) {
50
57
  case "\n":
@@ -71,12 +78,9 @@ var InlineParser = class {
71
78
  case "]":
72
79
  this.parseCloseBracket();
73
80
  return;
74
- default:
75
- if (require_inline_delimiter.isDelimiterChar(char)) {
76
- this.parseDelimiterRun(char);
77
- return;
78
- }
79
- this.parsePlainText();
81
+ case "*":
82
+ case "_":
83
+ case "~": this.parseDelimiterRun(char);
80
84
  }
81
85
  }
82
86
  appendText(literal) {
@@ -84,25 +88,16 @@ var InlineParser = class {
84
88
  this.container.appendChild(node);
85
89
  return node;
86
90
  }
87
- parsePlainText() {
88
- PLAIN_TEXT_PATTERN.lastIndex = this.pos;
89
- const match = PLAIN_TEXT_PATTERN.exec(this.text);
90
- if (match === null) {
91
- this.appendText(this.text.charAt(this.pos));
92
- this.pos += 1;
93
- return;
94
- }
95
- this.appendText(match[0]);
96
- this.pos += match[0].length;
97
- }
98
91
  parseLineBreak() {
99
92
  this.pos += 1;
100
93
  const last = this.container.lastChild;
101
- if (last?.kind === "text" && last.literal.endsWith(" ")) {
102
- const hard = last.literal.endsWith(HARD_BREAK_SPACES);
103
- last.literal = last.literal.replace(/ +$/, "");
104
- this.container.appendChild(new require_inline_node.InlineNode(hard ? "hardBreak" : "softBreak"));
105
- } else this.container.appendChild(new require_inline_node.InlineNode("softBreak"));
94
+ let hard = false;
95
+ if (last?.kind === "text") {
96
+ const withoutTrailingSpaces = last.literal.replace(/ +$/, "");
97
+ hard = last.literal.length - withoutTrailingSpaces.length >= HARD_BREAK_SPACE_COUNT;
98
+ last.literal = withoutTrailingSpaces;
99
+ }
100
+ this.container.appendChild(new require_inline_node.InlineNode(hard ? "hardBreak" : "softBreak"));
106
101
  while (this.text.charAt(this.pos) === " ") this.pos += 1;
107
102
  }
108
103
  parseBackslash() {
@@ -114,15 +109,13 @@ var InlineParser = class {
114
109
  this.container.appendChild(new require_inline_node.InlineNode("hardBreak"));
115
110
  return;
116
111
  }
117
- if (next === "(") {
118
- const span = require_inline_math.matchMathInlineSpan(this.text, backslashIndex);
119
- if (span !== void 0) {
120
- const node = new require_inline_node.InlineNode("mathInline");
121
- node.literal = span.slice(2, span.length - 2);
122
- this.container.appendChild(node);
123
- this.pos = backslashIndex + span.length;
124
- return;
125
- }
112
+ const span = require_inline_math.matchMathInlineSpan(this.text, backslashIndex);
113
+ if (span !== void 0) {
114
+ const node = new require_inline_node.InlineNode("mathInline");
115
+ node.literal = span.slice(2, span.length - 2);
116
+ this.container.appendChild(node);
117
+ this.pos = backslashIndex + span.length;
118
+ return;
126
119
  }
127
120
  if (require_inline_chars.isAsciiPunctuation(next)) {
128
121
  this.appendText(next);
@@ -137,7 +130,7 @@ var InlineParser = class {
137
130
  while (this.text.charAt(start + openLength) === "`") openLength += 1;
138
131
  const afterOpen = start + openLength;
139
132
  let scan = afterOpen;
140
- while (scan < this.text.length) {
133
+ while (this.text.charAt(scan) !== "") {
141
134
  if (this.text.charAt(scan) !== "`") {
142
135
  scan += 1;
143
136
  continue;
@@ -219,7 +212,7 @@ var InlineParser = class {
219
212
  }
220
213
  const node = this.appendText(this.text.slice(this.pos, this.pos + run.count));
221
214
  this.pos += run.count;
222
- if (run.canOpen || run.canClose) this.delimiters.push(char, run, node);
215
+ this.delimiters.push(char, run, node);
223
216
  }
224
217
  parseLiteralRun(char) {
225
218
  let length = 0;
@@ -343,7 +336,7 @@ var InlineParser = class {
343
336
  let label;
344
337
  if (labelLength > EMPTY_LABEL_LENGTH) label = this.text.slice(labelStart, labelStart + labelLength);
345
338
  else if (!opener.bracketAfter) label = this.text.slice(opener.index, afterCloseBracket);
346
- if (labelLength > 0) this.pos = labelStart + labelLength;
339
+ this.pos = labelStart + labelLength;
347
340
  if (label === void 0) return;
348
341
  const definition = this.references.get(require_inline_link.normalizeLinkLabel(label));
349
342
  if (definition === void 0) {
@@ -488,10 +481,7 @@ function toAstNode(node) {
488
481
  }
489
482
  function parseInlines(content, references, footnotes, options = {}) {
490
483
  const root = new InlineParser(content, references, footnotes, options).parse();
491
- if (options.gfmAutolinks ?? true) {
492
- require_inline_gfm_autolink.applyGfmAutolinks(root);
493
- mergeAdjacentText(root);
494
- }
484
+ if (options.gfmAutolinks ?? true) require_inline_gfm_autolink.applyGfmAutolinks(root);
495
485
  return toChildAstNodes(root);
496
486
  }
497
487
  //#endregion
@@ -2,7 +2,7 @@ import { matchFootnoteLabel } from "./footnote.js";
2
2
  import { matchHtmlTag } from "../html/html.js";
3
3
  import { containsAsciiControlOrSpace, isAsciiPunctuation } from "./chars.js";
4
4
  import { matchEntity } from "./entity.js";
5
- import { DelimiterStack, isDelimiterChar, processEmphasis, scanDelimiterRun } from "./delimiter.js";
5
+ import { DelimiterStack, processEmphasis, scanDelimiterRun } from "./delimiter.js";
6
6
  import { InlineNode, createTextNode } from "./node.js";
7
7
  import { applyGfmAutolinks } from "./gfm-autolink.js";
8
8
  import { matchLinkLabel, normalizeLinkLabel, parseLinkDestination, parseLinkTitle, skipInlineWhitespace } from "./link.js";
@@ -11,7 +11,7 @@ import { matchMathInlineSpan } from "./math.js";
11
11
  const PLAIN_TEXT_PATTERN = /[^\n`[\]\\!<&*_~]+/y;
12
12
  const URI_AUTOLINK_PATTERN = /<[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>]*>/y;
13
13
  const EMAIL_AUTOLINK_PATTERN = /<([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/y;
14
- const HARD_BREAK_SPACES = " ";
14
+ const HARD_BREAK_SPACE_COUNT = 2;
15
15
  const EMPTY_LABEL_LENGTH = 2;
16
16
  function stripOneSurroundingSpace(content) {
17
17
  if (content.startsWith(" ") && content.endsWith(" ") && /[^ ]/.test(content)) return content.slice(1, content.length - 1);
@@ -44,6 +44,13 @@ var InlineParser = class {
44
44
  return this.container;
45
45
  }
46
46
  step() {
47
+ PLAIN_TEXT_PATTERN.lastIndex = this.pos;
48
+ const plain = PLAIN_TEXT_PATTERN.exec(this.text);
49
+ if (plain !== null) {
50
+ this.appendText(plain[0]);
51
+ this.pos += plain[0].length;
52
+ return;
53
+ }
47
54
  const char = this.text.charAt(this.pos);
48
55
  switch (char) {
49
56
  case "\n":
@@ -70,12 +77,9 @@ var InlineParser = class {
70
77
  case "]":
71
78
  this.parseCloseBracket();
72
79
  return;
73
- default:
74
- if (isDelimiterChar(char)) {
75
- this.parseDelimiterRun(char);
76
- return;
77
- }
78
- this.parsePlainText();
80
+ case "*":
81
+ case "_":
82
+ case "~": this.parseDelimiterRun(char);
79
83
  }
80
84
  }
81
85
  appendText(literal) {
@@ -83,25 +87,16 @@ var InlineParser = class {
83
87
  this.container.appendChild(node);
84
88
  return node;
85
89
  }
86
- parsePlainText() {
87
- PLAIN_TEXT_PATTERN.lastIndex = this.pos;
88
- const match = PLAIN_TEXT_PATTERN.exec(this.text);
89
- if (match === null) {
90
- this.appendText(this.text.charAt(this.pos));
91
- this.pos += 1;
92
- return;
93
- }
94
- this.appendText(match[0]);
95
- this.pos += match[0].length;
96
- }
97
90
  parseLineBreak() {
98
91
  this.pos += 1;
99
92
  const last = this.container.lastChild;
100
- if (last?.kind === "text" && last.literal.endsWith(" ")) {
101
- const hard = last.literal.endsWith(HARD_BREAK_SPACES);
102
- last.literal = last.literal.replace(/ +$/, "");
103
- this.container.appendChild(new InlineNode(hard ? "hardBreak" : "softBreak"));
104
- } else this.container.appendChild(new InlineNode("softBreak"));
93
+ let hard = false;
94
+ if (last?.kind === "text") {
95
+ const withoutTrailingSpaces = last.literal.replace(/ +$/, "");
96
+ hard = last.literal.length - withoutTrailingSpaces.length >= HARD_BREAK_SPACE_COUNT;
97
+ last.literal = withoutTrailingSpaces;
98
+ }
99
+ this.container.appendChild(new InlineNode(hard ? "hardBreak" : "softBreak"));
105
100
  while (this.text.charAt(this.pos) === " ") this.pos += 1;
106
101
  }
107
102
  parseBackslash() {
@@ -113,15 +108,13 @@ var InlineParser = class {
113
108
  this.container.appendChild(new InlineNode("hardBreak"));
114
109
  return;
115
110
  }
116
- if (next === "(") {
117
- const span = matchMathInlineSpan(this.text, backslashIndex);
118
- if (span !== void 0) {
119
- const node = new InlineNode("mathInline");
120
- node.literal = span.slice(2, span.length - 2);
121
- this.container.appendChild(node);
122
- this.pos = backslashIndex + span.length;
123
- return;
124
- }
111
+ const span = matchMathInlineSpan(this.text, backslashIndex);
112
+ if (span !== void 0) {
113
+ const node = new InlineNode("mathInline");
114
+ node.literal = span.slice(2, span.length - 2);
115
+ this.container.appendChild(node);
116
+ this.pos = backslashIndex + span.length;
117
+ return;
125
118
  }
126
119
  if (isAsciiPunctuation(next)) {
127
120
  this.appendText(next);
@@ -136,7 +129,7 @@ var InlineParser = class {
136
129
  while (this.text.charAt(start + openLength) === "`") openLength += 1;
137
130
  const afterOpen = start + openLength;
138
131
  let scan = afterOpen;
139
- while (scan < this.text.length) {
132
+ while (this.text.charAt(scan) !== "") {
140
133
  if (this.text.charAt(scan) !== "`") {
141
134
  scan += 1;
142
135
  continue;
@@ -218,7 +211,7 @@ var InlineParser = class {
218
211
  }
219
212
  const node = this.appendText(this.text.slice(this.pos, this.pos + run.count));
220
213
  this.pos += run.count;
221
- if (run.canOpen || run.canClose) this.delimiters.push(char, run, node);
214
+ this.delimiters.push(char, run, node);
222
215
  }
223
216
  parseLiteralRun(char) {
224
217
  let length = 0;
@@ -342,7 +335,7 @@ var InlineParser = class {
342
335
  let label;
343
336
  if (labelLength > EMPTY_LABEL_LENGTH) label = this.text.slice(labelStart, labelStart + labelLength);
344
337
  else if (!opener.bracketAfter) label = this.text.slice(opener.index, afterCloseBracket);
345
- if (labelLength > 0) this.pos = labelStart + labelLength;
338
+ this.pos = labelStart + labelLength;
346
339
  if (label === void 0) return;
347
340
  const definition = this.references.get(normalizeLinkLabel(label));
348
341
  if (definition === void 0) {
@@ -487,10 +480,7 @@ function toAstNode(node) {
487
480
  }
488
481
  function parseInlines(content, references, footnotes, options = {}) {
489
482
  const root = new InlineParser(content, references, footnotes, options).parse();
490
- if (options.gfmAutolinks ?? true) {
491
- applyGfmAutolinks(root);
492
- mergeAdjacentText(root);
493
- }
483
+ if (options.gfmAutolinks ?? true) applyGfmAutolinks(root);
494
484
  return toChildAstNodes(root);
495
485
  }
496
486
  //#endregion
@@ -9,7 +9,7 @@ function normalizeLinkLabel(labelWithBrackets) {
9
9
  function matchLinkLabel(text, start) {
10
10
  if (text.charAt(start) !== "[") return 0;
11
11
  let index = start + 1;
12
- while (index < text.length) {
12
+ while (text.charAt(index) !== "") {
13
13
  const char = text.charAt(index);
14
14
  if (char === "\\") {
15
15
  index += 2;
@@ -27,7 +27,7 @@ function matchLinkLabel(text, start) {
27
27
  function parseLinkDestination(text, start) {
28
28
  if (text.charAt(start) === "<") {
29
29
  let index = start + 1;
30
- while (index < text.length) {
30
+ while (text.charAt(index) !== "") {
31
31
  const char = text.charAt(index);
32
32
  if (char === "\\") {
33
33
  index += 2;
@@ -79,9 +79,8 @@ const TITLE_DELIMITERS = /* @__PURE__ */ new Map([
79
79
  function parseLinkTitle(text, start) {
80
80
  const opener = text.charAt(start);
81
81
  const closer = TITLE_DELIMITERS.get(opener);
82
- if (closer === void 0) return;
83
82
  let index = start + 1;
84
- while (index < text.length) {
83
+ while (text.charAt(index) !== "") {
85
84
  const char = text.charAt(index);
86
85
  if (char === "\\") {
87
86
  index += 2;
@@ -98,7 +97,7 @@ function parseLinkTitle(text, start) {
98
97
  function skipInlineWhitespace(text, start) {
99
98
  let index = start;
100
99
  let seenLineEnding = false;
101
- while (index < text.length) {
100
+ for (;;) {
102
101
  const char = text.charAt(index);
103
102
  if (char === "\n") {
104
103
  if (seenLineEnding) break;