markdown-codec 6.7.5 → 7.0.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.
@@ -39,11 +39,12 @@ const ESCAPE_CHARS = /* @__PURE__ */ new Set([
39
39
  function escapeMarkdownText(text) {
40
40
  let out = "";
41
41
  let index = 0;
42
- while (index < text.length) {
43
- const char = text.charAt(index);
42
+ for (;;) {
43
+ const char = text[index];
44
+ if (char === void 0) break;
44
45
  if (char === "\n" || char === "\r") {
45
46
  out += "\\\n";
46
- index += char === "\r" && text.charAt(index + 1) === "\n" ? 2 : 1;
47
+ index += char === "\r" && text[index + 1] === "\n" ? 2 : 1;
47
48
  continue;
48
49
  }
49
50
  if (ESCAPE_CHARS.has(char)) {
@@ -64,9 +65,8 @@ function renderCodeSpan(text) {
64
65
  longestBacktickRun = Math.max(longestBacktickRun, current);
65
66
  } else current = 0;
66
67
  const fence = "`".repeat(longestBacktickRun + 1);
67
- const isAllSpaces = text.length > 0 && text.trim().length === 0;
68
68
  const risksFenceCollision = text.startsWith("`") || text.endsWith("`");
69
- const wouldBeStrippedOnReparse = !isAllSpaces && text.startsWith(" ") && text.endsWith(" ");
69
+ const wouldBeStrippedOnReparse = text.startsWith(" ") && text.endsWith(" ") && text.trim().length > 0;
70
70
  return risksFenceCollision || wouldBeStrippedOnReparse ? `${fence} ${text} ${fence}` : `${fence}${text}${fence}`;
71
71
  }
72
72
  function footnoteReferenceAt(constructs, index) {
@@ -102,12 +102,11 @@ function styleActive(run, key) {
102
102
  }
103
103
  const WORD_CHAR_PATTERN = /[\p{L}\p{N}]/u;
104
104
  function isIntrawordRisk(body) {
105
- if (body.length === 0) return false;
106
105
  return WORD_CHAR_PATTERN.test(body.charAt(0)) || WORD_CHAR_PATTERN.test(body.charAt(body.length - 1));
107
106
  }
108
107
  function hasMarkerConflict(body, candidate, precedingText) {
109
108
  if (candidate === "_" && isIntrawordRisk(body)) return true;
110
- if (body.length > 0 && (body.startsWith(candidate) || body.endsWith(candidate))) return true;
109
+ if (body.startsWith(candidate) || body.endsWith(candidate)) return true;
111
110
  return precedingText.endsWith(candidate);
112
111
  }
113
112
  function pickEmphasisMarker(body, configured, precedingText) {
@@ -135,7 +134,7 @@ function groupCount(runs, key) {
135
134
  function pickSplitKey(runs, remaining) {
136
135
  let best = remaining[0];
137
136
  let bestCount = groupCount(runs, best);
138
- for (const key of remaining.slice(1)) {
137
+ for (const key of remaining) {
139
138
  const count = groupCount(runs, key);
140
139
  if (count < bestCount) {
141
140
  best = key;
@@ -150,7 +149,7 @@ function renderNestedStyles(runs, remainingKeys, context, base, constructs) {
150
149
  const rest = remainingKeys.filter((candidate) => candidate !== key);
151
150
  let out = "";
152
151
  let index = 0;
153
- while (index < runs.length) {
152
+ for (;;) {
154
153
  const current = runs[index];
155
154
  if (current === void 0) break;
156
155
  const active = styleActive(current, key);
@@ -186,19 +185,26 @@ function linkTitleCovering(constructs, start, end) {
186
185
  function emitRuns(runs, context, constructs) {
187
186
  let out = "";
188
187
  let index = 0;
189
- while (index < runs.length) {
188
+ for (;;) {
190
189
  const run = runs[index];
191
190
  if (run === void 0) break;
192
191
  if (run.hyperlink === void 0) {
193
192
  let end = index + 1;
194
- while (end < runs.length && runs[end]?.hyperlink === void 0) end += 1;
193
+ for (;;) {
194
+ const next = runs[end];
195
+ if (next === void 0 || next.hyperlink !== void 0) break;
196
+ end += 1;
197
+ }
195
198
  out += renderNestedStyles(runs.slice(index, end), STYLE_KEYS, context, index, constructs);
196
199
  index = end;
197
200
  continue;
198
201
  }
199
202
  const hyperlink = run.hyperlink;
200
203
  let groupEnd = index + 1;
201
- while (groupEnd < runs.length && runs[groupEnd]?.hyperlink === hyperlink) groupEnd += 1;
204
+ for (;;) {
205
+ if (runs[groupEnd]?.hyperlink !== hyperlink) break;
206
+ groupEnd += 1;
207
+ }
202
208
  const group = runs.slice(index, groupEnd);
203
209
  if (group.length > 1) context.sink({
204
210
  code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.ADJACENT_LINKS_MERGED,
@@ -38,11 +38,12 @@ const ESCAPE_CHARS = /* @__PURE__ */ new Set([
38
38
  function escapeMarkdownText(text) {
39
39
  let out = "";
40
40
  let index = 0;
41
- while (index < text.length) {
42
- const char = text.charAt(index);
41
+ for (;;) {
42
+ const char = text[index];
43
+ if (char === void 0) break;
43
44
  if (char === "\n" || char === "\r") {
44
45
  out += "\\\n";
45
- index += char === "\r" && text.charAt(index + 1) === "\n" ? 2 : 1;
46
+ index += char === "\r" && text[index + 1] === "\n" ? 2 : 1;
46
47
  continue;
47
48
  }
48
49
  if (ESCAPE_CHARS.has(char)) {
@@ -63,9 +64,8 @@ function renderCodeSpan(text) {
63
64
  longestBacktickRun = Math.max(longestBacktickRun, current);
64
65
  } else current = 0;
65
66
  const fence = "`".repeat(longestBacktickRun + 1);
66
- const isAllSpaces = text.length > 0 && text.trim().length === 0;
67
67
  const risksFenceCollision = text.startsWith("`") || text.endsWith("`");
68
- const wouldBeStrippedOnReparse = !isAllSpaces && text.startsWith(" ") && text.endsWith(" ");
68
+ const wouldBeStrippedOnReparse = text.startsWith(" ") && text.endsWith(" ") && text.trim().length > 0;
69
69
  return risksFenceCollision || wouldBeStrippedOnReparse ? `${fence} ${text} ${fence}` : `${fence}${text}${fence}`;
70
70
  }
71
71
  function footnoteReferenceAt(constructs, index) {
@@ -101,12 +101,11 @@ function styleActive(run, key) {
101
101
  }
102
102
  const WORD_CHAR_PATTERN = /[\p{L}\p{N}]/u;
103
103
  function isIntrawordRisk(body) {
104
- if (body.length === 0) return false;
105
104
  return WORD_CHAR_PATTERN.test(body.charAt(0)) || WORD_CHAR_PATTERN.test(body.charAt(body.length - 1));
106
105
  }
107
106
  function hasMarkerConflict(body, candidate, precedingText) {
108
107
  if (candidate === "_" && isIntrawordRisk(body)) return true;
109
- if (body.length > 0 && (body.startsWith(candidate) || body.endsWith(candidate))) return true;
108
+ if (body.startsWith(candidate) || body.endsWith(candidate)) return true;
110
109
  return precedingText.endsWith(candidate);
111
110
  }
112
111
  function pickEmphasisMarker(body, configured, precedingText) {
@@ -134,7 +133,7 @@ function groupCount(runs, key) {
134
133
  function pickSplitKey(runs, remaining) {
135
134
  let best = remaining[0];
136
135
  let bestCount = groupCount(runs, best);
137
- for (const key of remaining.slice(1)) {
136
+ for (const key of remaining) {
138
137
  const count = groupCount(runs, key);
139
138
  if (count < bestCount) {
140
139
  best = key;
@@ -149,7 +148,7 @@ function renderNestedStyles(runs, remainingKeys, context, base, constructs) {
149
148
  const rest = remainingKeys.filter((candidate) => candidate !== key);
150
149
  let out = "";
151
150
  let index = 0;
152
- while (index < runs.length) {
151
+ for (;;) {
153
152
  const current = runs[index];
154
153
  if (current === void 0) break;
155
154
  const active = styleActive(current, key);
@@ -185,19 +184,26 @@ function linkTitleCovering(constructs, start, end) {
185
184
  function emitRuns(runs, context, constructs) {
186
185
  let out = "";
187
186
  let index = 0;
188
- while (index < runs.length) {
187
+ for (;;) {
189
188
  const run = runs[index];
190
189
  if (run === void 0) break;
191
190
  if (run.hyperlink === void 0) {
192
191
  let end = index + 1;
193
- while (end < runs.length && runs[end]?.hyperlink === void 0) end += 1;
192
+ for (;;) {
193
+ const next = runs[end];
194
+ if (next === void 0 || next.hyperlink !== void 0) break;
195
+ end += 1;
196
+ }
194
197
  out += renderNestedStyles(runs.slice(index, end), STYLE_KEYS, context, index, constructs);
195
198
  index = end;
196
199
  continue;
197
200
  }
198
201
  const hyperlink = run.hyperlink;
199
202
  let groupEnd = index + 1;
200
- while (groupEnd < runs.length && runs[groupEnd]?.hyperlink === hyperlink) groupEnd += 1;
203
+ for (;;) {
204
+ if (runs[groupEnd]?.hyperlink !== hyperlink) break;
205
+ groupEnd += 1;
206
+ }
201
207
  const group = runs.slice(index, groupEnd);
202
208
  if (group.length > 1) context.sink({
203
209
  code: MarkdownDiagnosticCodes.ADJACENT_LINKS_MERGED,
@@ -5,25 +5,21 @@ let document_schema_js = require("document-schema.js");
5
5
  //#region src/html/html-table.ts
6
6
  function findBalancedClose(text, openEnd, tagNames) {
7
7
  const names = tagNames.join("|");
8
- const openPattern = new RegExp(`<(?:${names})(?=[\\s/>])`, "gi");
9
- const closePattern = new RegExp(`</(?:${names})\\s*>`, "gi");
8
+ const tagPattern = new RegExp(`</(?:${names})\\s*>|<(?:${names})(?=[\\s/>])`, "gi");
10
9
  let depth = 1;
11
10
  let pos = openEnd;
12
- while (depth > 0) {
13
- openPattern.lastIndex = pos;
14
- closePattern.lastIndex = pos;
15
- const openMatch = openPattern.exec(text);
16
- const closeMatch = closePattern.exec(text);
17
- if (closeMatch === null) return;
18
- if (openMatch !== null && openMatch.index < closeMatch.index) {
11
+ for (;;) {
12
+ tagPattern.lastIndex = pos;
13
+ const match = tagPattern.exec(text);
14
+ if (match === null) return;
15
+ pos = match.index + match[0].length;
16
+ if (!match[0].startsWith("</")) {
19
17
  depth += 1;
20
- pos = openMatch.index + openMatch[0].length;
21
18
  continue;
22
19
  }
23
20
  depth -= 1;
24
- pos = closeMatch.index + closeMatch[0].length;
25
21
  if (depth === 0) return {
26
- start: closeMatch.index,
22
+ start: match.index,
27
23
  end: pos
28
24
  };
29
25
  }
@@ -37,7 +33,7 @@ function extractTopLevelElements(text, tagNames) {
37
33
  const match = openPattern.exec(text);
38
34
  if (match === null) break;
39
35
  if (text.slice(pos, match.index).trim().length > 0) return;
40
- const attrs = match[1] ?? "";
36
+ const attrs = match[1];
41
37
  const openEnd = match.index + match[0].length;
42
38
  const close = findBalancedClose(text, openEnd, tagNames);
43
39
  if (close === void 0) return;
@@ -136,15 +132,15 @@ function parseInlineHtml(text, style) {
136
132
  pushPlainRun(runs, rest, style);
137
133
  return runs;
138
134
  }
139
- pushPlainRun(runs, rest.slice(0, match.index), style);
140
135
  const tagName = match[1].toLowerCase();
141
- const attrs = match[2] ?? "";
136
+ const attrs = match[2];
142
137
  const openEnd = pos + match.index + match[0].length;
143
138
  const close = findBalancedClose(text, openEnd, [tagName]);
144
139
  if (close === void 0) {
145
140
  pushPlainRun(runs, rest, style);
146
141
  return runs;
147
142
  }
143
+ pushPlainRun(runs, rest.slice(0, match.index), style);
148
144
  runs.push(...parseInlineHtml(text.slice(openEnd, close.start), applyTagStyle(style, tagName, attrs)));
149
145
  pos = close.end;
150
146
  }
@@ -168,12 +164,10 @@ function parseHtmlImage(piece) {
168
164
  };
169
165
  }
170
166
  function parseCellBlocks(inner, contentWidthPt) {
171
- const trimmed = inner.trim();
172
- if (trimmed.length === 0) return [];
173
- const nestedTable = parseWholeTable(trimmed, contentWidthPt);
167
+ const nestedTable = parseWholeTable(inner, contentWidthPt);
174
168
  if (nestedTable !== void 0) return [nestedTable];
175
169
  const blocks = [];
176
- for (const segment of trimmed.split(/<br\s*\/?>/i)) {
170
+ for (const segment of inner.split(/<br\s*\/?>/i)) {
177
171
  const piece = segment.trim();
178
172
  if (piece.length === 0) continue;
179
173
  const image = parseHtmlImage(piece);
@@ -235,9 +229,7 @@ function parseWholeTable(text, contentWidthPt) {
235
229
  return rows === void 0 ? void 0 : buildContentTable(rows, contentWidthPt);
236
230
  }
237
231
  function parseHtmlTable(literal, contentWidthPt) {
238
- const trimmed = literal.trim();
239
- if (!/^<table\b/i.test(trimmed)) return;
240
- return parseWholeTable(trimmed, contentWidthPt);
232
+ return parseWholeTable(literal, contentWidthPt);
241
233
  }
242
234
  //#endregion
243
235
  exports.parseHtmlTable = parseHtmlTable;
@@ -4,25 +4,21 @@ import { rgbHexToColor } from "document-schema.js";
4
4
  //#region src/html/html-table.ts
5
5
  function findBalancedClose(text, openEnd, tagNames) {
6
6
  const names = tagNames.join("|");
7
- const openPattern = new RegExp(`<(?:${names})(?=[\\s/>])`, "gi");
8
- const closePattern = new RegExp(`</(?:${names})\\s*>`, "gi");
7
+ const tagPattern = new RegExp(`</(?:${names})\\s*>|<(?:${names})(?=[\\s/>])`, "gi");
9
8
  let depth = 1;
10
9
  let pos = openEnd;
11
- while (depth > 0) {
12
- openPattern.lastIndex = pos;
13
- closePattern.lastIndex = pos;
14
- const openMatch = openPattern.exec(text);
15
- const closeMatch = closePattern.exec(text);
16
- if (closeMatch === null) return;
17
- if (openMatch !== null && openMatch.index < closeMatch.index) {
10
+ for (;;) {
11
+ tagPattern.lastIndex = pos;
12
+ const match = tagPattern.exec(text);
13
+ if (match === null) return;
14
+ pos = match.index + match[0].length;
15
+ if (!match[0].startsWith("</")) {
18
16
  depth += 1;
19
- pos = openMatch.index + openMatch[0].length;
20
17
  continue;
21
18
  }
22
19
  depth -= 1;
23
- pos = closeMatch.index + closeMatch[0].length;
24
20
  if (depth === 0) return {
25
- start: closeMatch.index,
21
+ start: match.index,
26
22
  end: pos
27
23
  };
28
24
  }
@@ -36,7 +32,7 @@ function extractTopLevelElements(text, tagNames) {
36
32
  const match = openPattern.exec(text);
37
33
  if (match === null) break;
38
34
  if (text.slice(pos, match.index).trim().length > 0) return;
39
- const attrs = match[1] ?? "";
35
+ const attrs = match[1];
40
36
  const openEnd = match.index + match[0].length;
41
37
  const close = findBalancedClose(text, openEnd, tagNames);
42
38
  if (close === void 0) return;
@@ -135,15 +131,15 @@ function parseInlineHtml(text, style) {
135
131
  pushPlainRun(runs, rest, style);
136
132
  return runs;
137
133
  }
138
- pushPlainRun(runs, rest.slice(0, match.index), style);
139
134
  const tagName = match[1].toLowerCase();
140
- const attrs = match[2] ?? "";
135
+ const attrs = match[2];
141
136
  const openEnd = pos + match.index + match[0].length;
142
137
  const close = findBalancedClose(text, openEnd, [tagName]);
143
138
  if (close === void 0) {
144
139
  pushPlainRun(runs, rest, style);
145
140
  return runs;
146
141
  }
142
+ pushPlainRun(runs, rest.slice(0, match.index), style);
147
143
  runs.push(...parseInlineHtml(text.slice(openEnd, close.start), applyTagStyle(style, tagName, attrs)));
148
144
  pos = close.end;
149
145
  }
@@ -167,12 +163,10 @@ function parseHtmlImage(piece) {
167
163
  };
168
164
  }
169
165
  function parseCellBlocks(inner, contentWidthPt) {
170
- const trimmed = inner.trim();
171
- if (trimmed.length === 0) return [];
172
- const nestedTable = parseWholeTable(trimmed, contentWidthPt);
166
+ const nestedTable = parseWholeTable(inner, contentWidthPt);
173
167
  if (nestedTable !== void 0) return [nestedTable];
174
168
  const blocks = [];
175
- for (const segment of trimmed.split(/<br\s*\/?>/i)) {
169
+ for (const segment of inner.split(/<br\s*\/?>/i)) {
176
170
  const piece = segment.trim();
177
171
  if (piece.length === 0) continue;
178
172
  const image = parseHtmlImage(piece);
@@ -234,9 +228,7 @@ function parseWholeTable(text, contentWidthPt) {
234
228
  return rows === void 0 ? void 0 : buildContentTable(rows, contentWidthPt);
235
229
  }
236
230
  function parseHtmlTable(literal, contentWidthPt) {
237
- const trimmed = literal.trim();
238
- if (!/^<table\b/i.test(trimmed)) return;
239
- return parseWholeTable(trimmed, contentWidthPt);
231
+ return parseWholeTable(literal, contentWidthPt);
240
232
  }
241
233
  //#endregion
242
234
  export { parseHtmlTable };
@@ -18,9 +18,11 @@ const PNG_SIGNATURE = [
18
18
  ];
19
19
  const PNG_HEADER_BYTES = 24;
20
20
  function isPng(bytes) {
21
- if (bytes.length < PNG_SIGNATURE.length) return false;
22
21
  return PNG_SIGNATURE.every((byte, index) => bytes[index] === byte);
23
22
  }
23
+ function isJpeg(bytes) {
24
+ return bytes[0] === 255 && bytes[1] === 216;
25
+ }
24
26
  function readPngDimensions(bytes) {
25
27
  if (bytes.length < PNG_HEADER_BYTES) return;
26
28
  if (bytes[12] !== 73 || bytes[13] !== 72 || bytes[14] !== 68 || bytes[15] !== 82) return;
@@ -37,10 +39,12 @@ function hasNoLengthField(marker) {
37
39
  return marker === 216 || marker === 217 || marker === 1 || marker >= 208 && marker <= 215;
38
40
  }
39
41
  function readJpegDimensions(bytes) {
40
- if (bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) return;
42
+ if (!isJpeg(bytes)) return;
41
43
  let offset = 2;
42
- while (offset < bytes.length) {
43
- if (bytes[offset] !== 255) {
44
+ for (;;) {
45
+ const byte = bytes[offset];
46
+ if (byte === void 0) return;
47
+ if (byte !== 255) {
44
48
  offset += 1;
45
49
  continue;
46
50
  }
@@ -50,7 +54,6 @@ function readJpegDimensions(bytes) {
50
54
  if (marker === void 0) return;
51
55
  offset = markerOffset + 1;
52
56
  if (hasNoLengthField(marker)) continue;
53
- if (offset + 2 > bytes.length) return;
54
57
  const length = readUint16BE(bytes, offset);
55
58
  if (isStartOfFrameMarker(marker)) {
56
59
  if (offset + 7 > bytes.length) return;
@@ -64,9 +67,6 @@ function readJpegDimensions(bytes) {
64
67
  offset += length;
65
68
  }
66
69
  }
67
- function isJpeg(bytes) {
68
- return bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 216;
69
- }
70
70
  function detectImageFormat(bytes) {
71
71
  if (isPng(bytes)) return "png";
72
72
  return isJpeg(bytes) ? "jpeg" : void 0;
@@ -17,9 +17,11 @@ const PNG_SIGNATURE = [
17
17
  ];
18
18
  const PNG_HEADER_BYTES = 24;
19
19
  function isPng(bytes) {
20
- if (bytes.length < PNG_SIGNATURE.length) return false;
21
20
  return PNG_SIGNATURE.every((byte, index) => bytes[index] === byte);
22
21
  }
22
+ function isJpeg(bytes) {
23
+ return bytes[0] === 255 && bytes[1] === 216;
24
+ }
23
25
  function readPngDimensions(bytes) {
24
26
  if (bytes.length < PNG_HEADER_BYTES) return;
25
27
  if (bytes[12] !== 73 || bytes[13] !== 72 || bytes[14] !== 68 || bytes[15] !== 82) return;
@@ -36,10 +38,12 @@ function hasNoLengthField(marker) {
36
38
  return marker === 216 || marker === 217 || marker === 1 || marker >= 208 && marker <= 215;
37
39
  }
38
40
  function readJpegDimensions(bytes) {
39
- if (bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) return;
41
+ if (!isJpeg(bytes)) return;
40
42
  let offset = 2;
41
- while (offset < bytes.length) {
42
- if (bytes[offset] !== 255) {
43
+ for (;;) {
44
+ const byte = bytes[offset];
45
+ if (byte === void 0) return;
46
+ if (byte !== 255) {
43
47
  offset += 1;
44
48
  continue;
45
49
  }
@@ -49,7 +53,6 @@ function readJpegDimensions(bytes) {
49
53
  if (marker === void 0) return;
50
54
  offset = markerOffset + 1;
51
55
  if (hasNoLengthField(marker)) continue;
52
- if (offset + 2 > bytes.length) return;
53
56
  const length = readUint16BE(bytes, offset);
54
57
  if (isStartOfFrameMarker(marker)) {
55
58
  if (offset + 7 > bytes.length) return;
@@ -63,9 +66,6 @@ function readJpegDimensions(bytes) {
63
66
  offset += length;
64
67
  }
65
68
  }
66
- function isJpeg(bytes) {
67
- return bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 216;
68
- }
69
69
  function detectImageFormat(bytes) {
70
70
  if (isPng(bytes)) return "png";
71
71
  return isJpeg(bytes) ? "jpeg" : void 0;
@@ -1,9 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_inline_chars = require("./chars.cjs");
3
3
  //#region src/inline/delimiter.ts
4
- function isDelimiterChar(char) {
5
- return char === "*" || char === "_" || char === "~";
6
- }
7
4
  const MAX_STRIKETHROUGH_RUN = 2;
8
5
  function scanDelimiterRun(text, start, char) {
9
6
  let count = 0;
@@ -124,6 +121,5 @@ function processEmphasis(stack, stackBottom, createWrapper) {
124
121
  //#endregion
125
122
  exports.DelimiterStack = DelimiterStack;
126
123
  exports.closerSignature = closerSignature;
127
- exports.isDelimiterChar = isDelimiterChar;
128
124
  exports.processEmphasis = processEmphasis;
129
125
  exports.scanDelimiterRun = scanDelimiterRun;
@@ -1,7 +1,6 @@
1
1
  import { InlineNode } from "./node.cjs";
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;
@@ -27,4 +26,4 @@ declare function closerSignature(closer: Delimiter): string;
27
26
  type EmphasisWrapperFactory = (kind: "emphasis" | "strong" | "strikethrough", marker: DelimiterChar) => InlineNode;
28
27
  declare function processEmphasis(stack: DelimiterStack, stackBottom: Delimiter | undefined, createWrapper: EmphasisWrapperFactory): void;
29
28
  //#endregion
30
- export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature, isDelimiterChar, processEmphasis, scanDelimiterRun };
29
+ export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature, processEmphasis, scanDelimiterRun };
@@ -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;
@@ -27,4 +26,4 @@ declare function closerSignature(closer: Delimiter): string;
27
26
  type EmphasisWrapperFactory = (kind: "emphasis" | "strong" | "strikethrough", marker: DelimiterChar) => InlineNode;
28
27
  declare function processEmphasis(stack: DelimiterStack, stackBottom: Delimiter | undefined, createWrapper: EmphasisWrapperFactory): void;
29
28
  //#endregion
30
- export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature, 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;
@@ -121,4 +118,4 @@ function processEmphasis(stack, stackBottom, createWrapper) {
121
118
  while (stack.top !== void 0 && stack.top !== stackBottom) stack.remove(stack.top);
122
119
  }
123
120
  //#endregion
124
- export { DelimiterStack, closerSignature, isDelimiterChar, processEmphasis, scanDelimiterRun };
121
+ export { DelimiterStack, closerSignature, processEmphasis, scanDelimiterRun };
@@ -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
  }