markdown-codec 6.7.4 → 6.7.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.
Files changed (56) hide show
  1. package/README.md +2 -1
  2. package/dist/block/definitions.cjs +1 -5
  3. package/dist/block/definitions.js +1 -5
  4. package/dist/block/line.cjs +2 -2
  5. package/dist/block/line.js +2 -2
  6. package/dist/block/list.cjs +7 -14
  7. package/dist/block/list.js +7 -14
  8. package/dist/block/table.cjs +3 -4
  9. package/dist/block/table.js +3 -4
  10. package/dist/codec.d.cts +9 -9
  11. package/dist/codec.d.ts +9 -9
  12. package/dist/emit/emit.cjs +35 -37
  13. package/dist/emit/emit.js +35 -37
  14. package/dist/emit/table.cjs +2 -2
  15. package/dist/emit/table.js +2 -2
  16. package/dist/html/html.cjs +0 -2
  17. package/dist/html/html.js +0 -2
  18. package/dist/html/render.cjs +3 -11
  19. package/dist/html/render.js +3 -11
  20. package/dist/image/image.cjs +0 -49
  21. package/dist/image/image.d.cts +2 -2
  22. package/dist/image/image.d.ts +2 -2
  23. package/dist/image/image.js +1 -48
  24. package/dist/{image-BtmTG4_a.d.cts → image-83yql5ES.d.cts} +1 -3
  25. package/dist/{image-BtmTG4_a.d.ts → image-83yql5ES.d.ts} +1 -3
  26. package/dist/{image-B5L0HpAJ.d.cts → image-B6p0Ovgy.d.cts} +1 -1
  27. package/dist/{image-C390OIB3.d.ts → image-gR1vISI0.d.ts} +1 -1
  28. package/dist/index.d.cts +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/inline/chars.cjs +3 -6
  31. package/dist/inline/chars.js +3 -6
  32. package/dist/inline/delimiter.cjs +5 -12
  33. package/dist/inline/delimiter.d.cts +2 -1
  34. package/dist/inline/delimiter.d.ts +2 -1
  35. package/dist/inline/delimiter.js +5 -13
  36. package/dist/inline/entity.cjs +6 -10
  37. package/dist/inline/entity.js +6 -10
  38. package/dist/inline/link.cjs +4 -5
  39. package/dist/inline/link.js +4 -5
  40. package/dist/lower/front-matter.cjs +4 -8
  41. package/dist/lower/front-matter.js +4 -8
  42. package/dist/lower/image.cjs +3 -2
  43. package/dist/lower/image.d.cts +1 -1
  44. package/dist/lower/image.d.ts +1 -1
  45. package/dist/lower/image.js +2 -1
  46. package/dist/lower/inline.cjs +0 -2
  47. package/dist/lower/inline.js +0 -2
  48. package/dist/options/options.d.cts +1 -1
  49. package/dist/options/options.d.ts +1 -1
  50. package/dist/read.cjs +2 -2
  51. package/dist/read.js +2 -2
  52. package/dist/scan/scan.cjs +1 -3
  53. package/dist/scan/scan.js +1 -3
  54. package/dist/shared/list-id.cjs +1 -1
  55. package/dist/shared/list-id.js +1 -1
  56. package/package.json +2 -1
@@ -4,7 +4,6 @@ require("../defaults/defaults.cjs");
4
4
  const require_diagnostics_diagnostics = require("../diagnostics/diagnostics.cjs");
5
5
  const require_html_html = require("../html/html.cjs");
6
6
  const require_shared_line_ending = require("../shared/line-ending.cjs");
7
- require("../scan/scan.cjs");
8
7
  const require_block_line = require("../block/line.cjs");
9
8
  const require_block_list = require("../block/list.cjs");
10
9
  const require_block_table = require("../block/table.cjs");
@@ -24,9 +23,13 @@ const MAX_SETEXT_LEVEL = 2;
24
23
  const SETEXT_LEVEL_1_CHAR = "=";
25
24
  const SETEXT_LEVEL_2_CHAR = "-";
26
25
  const MIN_SETEXT_UNDERLINE_LENGTH = 1;
26
+ function splitLines(text, pattern) {
27
+ const [first, ...rest] = text.split(pattern);
28
+ return [first, ...rest];
29
+ }
27
30
  function renderSetextHeading(level, text) {
28
31
  const underlineChar = level === 1 ? SETEXT_LEVEL_1_CHAR : SETEXT_LEVEL_2_CHAR;
29
- const firstLine = text.split(require_shared_line_ending.LINE_ENDING_PATTERN)[0] ?? "";
32
+ const [firstLine] = splitLines(text, require_shared_line_ending.LINE_ENDING_PATTERN);
30
33
  return `${text}\n${underlineChar.repeat(Math.max(MIN_SETEXT_UNDERLINE_LENGTH, firstLine.length))}`;
31
34
  }
32
35
  const MIN_CODE_FENCE_LENGTH = 3;
@@ -54,19 +57,17 @@ function isQuotableStyle(styleId) {
54
57
  return QUOTABLE_STYLE_IDS.has(styleId) || require_shared_style_constants.parseHeadingStyleId(styleId) !== void 0;
55
58
  }
56
59
  function terminatesCleanly(styleId) {
57
- if (styleId === void 0 || styleId === "Quote" || styleId === "HTMLPreformatted") return false;
58
- return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || require_shared_style_constants.parseHeadingStyleId(styleId) !== void 0;
60
+ return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || styleId !== void 0 && require_shared_style_constants.parseHeadingStyleId(styleId) !== void 0;
59
61
  }
60
62
  const BLANK_OR_WHITESPACE_ONLY_LINE = /^[ \t]*$/;
61
63
  function firstContentLineIndex(text) {
62
64
  return text.split(require_shared_line_ending.LINE_ENDING_PATTERN).findIndex((line) => !BLANK_OR_WHITESPACE_ONLY_LINE.test(line));
63
65
  }
64
- function leadingIndentColumns(line) {
66
+ function leadingIndentReachesCodeThreshold(line) {
65
67
  let column = 0;
66
- for (const char of line) if (char === " ") column += 1;
67
- else if (char === " ") column += 4 - column % 4;
68
- else break;
69
- return column;
68
+ while (column < line.length && line[column] === " ") column += 1;
69
+ if (column >= 4) return true;
70
+ return line[column] === " ";
70
71
  }
71
72
  const MAX_LEADING_BLANK_LINES_FOR_SETEXT = 1;
72
73
  function interruptsSetextParagraph(line, atBlockStart) {
@@ -95,7 +96,7 @@ function unsafeSetextBreakReason(text) {
95
96
  continue;
96
97
  }
97
98
  sawContentLine = true;
98
- if (leadingIndentColumns(line) >= 4) return "leading-indentation";
99
+ if (leadingIndentReachesCodeThreshold(line)) return "leading-indentation";
99
100
  if (interruptsSetextParagraph(line, true)) return "interrupting-line";
100
101
  precedingLine = line;
101
102
  continue;
@@ -124,7 +125,7 @@ function willRenderAsSetext(paragraph, level, context) {
124
125
  }
125
126
  function canInterruptOpenParagraph(paragraph, context) {
126
127
  const styleId = paragraph.styleId;
127
- if (styleId === void 0 || styleId === "Quote" || styleId === "HTMLPreformatted") return false;
128
+ if (styleId === void 0) return false;
128
129
  if (styleId === "CodeBlock" || styleId === "MathBlock") return true;
129
130
  if (styleId === "HorizontalRule") return context.thematicBreakChar !== SETEXT_LEVEL_2_CHAR;
130
131
  const headingLevel = require_shared_style_constants.parseHeadingStyleId(styleId);
@@ -264,24 +265,24 @@ function toEmitItem(item) {
264
265
  function firstBlockCheckbox(first, taskNumId) {
265
266
  if (first.list.checked !== void 0) return {
266
267
  checkboxText: first.list.checked ? "[x] " : "[ ] ",
267
- stripGlyph: false
268
+ strippedFirstBlock: void 0
268
269
  };
269
270
  if (!taskNumId || first.kind !== "paragraph") return {
270
271
  checkboxText: "",
271
- stripGlyph: false
272
+ strippedFirstBlock: void 0
272
273
  };
273
274
  const leading = first.block.runs[0]?.text ?? "";
274
275
  if (leading.startsWith(`☒ `)) return {
275
276
  checkboxText: "[x] ",
276
- stripGlyph: true
277
+ strippedFirstBlock: stripCheckboxRun(first.block)
277
278
  };
278
279
  if (leading.startsWith(`☐ `)) return {
279
280
  checkboxText: "[ ] ",
280
- stripGlyph: true
281
+ strippedFirstBlock: stripCheckboxRun(first.block)
281
282
  };
282
283
  return {
283
284
  checkboxText: "",
284
- stripGlyph: false
285
+ strippedFirstBlock: void 0
285
286
  };
286
287
  }
287
288
  function renderListItemMarker(numId, info, glyph, checkboxText, context) {
@@ -316,7 +317,7 @@ function resolveListGlyph(numId, type, previousSibling, context) {
316
317
  }
317
318
  function consumeSameItemRun(items, from, level, itemId) {
318
319
  let end = from;
319
- while (end < items.length) {
320
+ for (;;) {
320
321
  const candidate = items[end];
321
322
  if (candidate?.list.level !== level || candidate.list.itemId !== itemId) break;
322
323
  end += 1;
@@ -334,7 +335,7 @@ function collectListItem(items, start, level, itemId) {
334
335
  index = ownEnd;
335
336
  for (;;) {
336
337
  let nestedEnd = index;
337
- while (nestedEnd < items.length) {
338
+ for (;;) {
338
339
  const candidateLevel = items[nestedEnd]?.list.level;
339
340
  if (candidateLevel === void 0 || candidateLevel <= level) break;
340
341
  nestedEnd += 1;
@@ -347,7 +348,6 @@ function collectListItem(items, start, level, itemId) {
347
348
  index = nestedEnd;
348
349
  if (itemId === void 0) break;
349
350
  const resumedEnd = consumeSameItemRun(items, index, level, itemId);
350
- if (resumedEnd === index) break;
351
351
  segments.push({
352
352
  kind: "own",
353
353
  blocks: items.slice(index, resumedEnd)
@@ -378,8 +378,8 @@ function regionItemCanInterrupt(item, context) {
378
378
  function lastStyleIdOfRegionItem(item) {
379
379
  return lastStyleIdOf(toEmitItem(item));
380
380
  }
381
- function listRegionItemBody(item, context, stripGlyph) {
382
- if (item.kind === "paragraph") return renderParagraphBody(stripGlyph ? stripCheckboxRun(item.block) : item.block, context);
381
+ function listRegionItemBody(item, context, overrideParagraph) {
382
+ if (item.kind === "paragraph") return renderParagraphBody(overrideParagraph ?? item.block, context);
383
383
  const previousEnclosingItemId = context.enclosingItemId;
384
384
  context.enclosingItemId = item.list.itemId;
385
385
  const body = renderConstruct(item.item, context);
@@ -394,14 +394,14 @@ function renderListRegion(items, context) {
394
394
  const parts = [];
395
395
  let index = 0;
396
396
  let previousSibling;
397
- while (index < items.length) {
397
+ for (;;) {
398
398
  const item = items[index];
399
399
  if (item === void 0) break;
400
400
  const { numId, level, itemId } = item.list;
401
401
  const info = listInfoFor(numId, context);
402
402
  const loose = info?.loose === true;
403
403
  const type = info?.type ?? "bullet";
404
- const glyph = numId === void 0 ? type === "ordered" ? context.orderedDelimiter : context.bulletMarker : resolveListGlyph(numId, type, previousSibling, context);
404
+ const glyph = numId === void 0 ? context.bulletMarker : resolveListGlyph(numId, type, previousSibling, context);
405
405
  if (numId !== void 0) previousSibling = {
406
406
  numId,
407
407
  type,
@@ -410,7 +410,7 @@ function renderListRegion(items, context) {
410
410
  const { segments, next } = collectListItem(items, index, level, itemId);
411
411
  const first = segments[0]?.blocks[0];
412
412
  if (first === void 0) break;
413
- const { checkboxText, stripGlyph } = firstBlockCheckbox(first, info?.task === true);
413
+ const { checkboxText, strippedFirstBlock } = firstBlockCheckbox(first, info?.task === true);
414
414
  const marker = renderListItemMarker(numId, info, glyph, checkboxText, context);
415
415
  const indent = " ".repeat(marker.bareLength);
416
416
  let text = "";
@@ -426,13 +426,13 @@ function renderListRegion(items, context) {
426
426
  }
427
427
  for (const block of segment.blocks) {
428
428
  if (!renderedFirstLine) {
429
- const [firstLine = "", ...restLines] = listRegionItemBody(block, context, stripGlyph).split("\n");
429
+ const [firstLine, ...restLines] = splitLines(listRegionItemBody(block, context, strippedFirstBlock), "\n");
430
430
  text = [`${marker.full}${firstLine}`, ...restLines.map((line) => `${indent}${line}`)].join("\n");
431
431
  renderedFirstLine = true;
432
432
  previousStyleId = lastStyleIdOfRegionItem(block);
433
433
  continue;
434
434
  }
435
- const rendered = listRegionItemBody(block, context, false).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
435
+ const rendered = listRegionItemBody(block, context, void 0).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
436
436
  const blank = loose || requiresBlankLineBefore(block, previousStyleId, context);
437
437
  text += blank ? `\n\n${rendered}` : `\n${rendered}`;
438
438
  previousStyleId = lastStyleIdOfRegionItem(block);
@@ -468,7 +468,7 @@ function isMaterialisedDivision(item) {
468
468
  function groupConstructItems(blocks, start) {
469
469
  const items = [];
470
470
  let index = start;
471
- while (index < blocks.length) {
471
+ for (;;) {
472
472
  const block = blocks[index];
473
473
  if (block === void 0) break;
474
474
  index += 1;
@@ -497,7 +497,7 @@ function renderFootnoteDefinition(name, body) {
497
497
  const marker = `[^${name}]:`;
498
498
  if (body.length === 0) return marker;
499
499
  const indent = " ".repeat(FOOTNOTE_CONTINUATION_INDENT);
500
- const [firstLine = "", ...restLines] = body.split("\n");
500
+ const [firstLine, ...restLines] = splitLines(body, "\n");
501
501
  return [`${marker} ${firstLine}`, ...restLines.map((line) => line.length === 0 ? line : `${indent}${line}`)].join("\n");
502
502
  }
503
503
  function renderConstruct(item, context) {
@@ -512,13 +512,11 @@ function renderConstruct(item, context) {
512
512
  });
513
513
  return body;
514
514
  }
515
- if (descriptor.kind === "division") {
516
- if (isMaterialisedDivision(item)) {
517
- context.divisionDepth += 1;
518
- const body = renderItems(item.children, context);
519
- context.divisionDepth -= 1;
520
- return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
521
- }
515
+ if (isMaterialisedDivision(item)) {
516
+ context.divisionDepth += 1;
517
+ const body = renderItems(item.children, context);
518
+ context.divisionDepth -= 1;
519
+ return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
522
520
  }
523
521
  if (descriptor.kind === "link" && descriptor.target.kind === "external") {
524
522
  const onlyChild = item.children.length === 1 && !isConstructItem(item.children[0]) ? item.children[0].block : void 0;
@@ -549,7 +547,7 @@ function isInheritedListMembership(list, context) {
549
547
  function renderItems(items, context) {
550
548
  const parts = [];
551
549
  let index = 0;
552
- while (index < items.length) {
550
+ for (;;) {
553
551
  const item = items[index];
554
552
  if (item === void 0) break;
555
553
  if (isConstructItem(item)) {
@@ -612,7 +610,7 @@ function emitBlocks(blocks, context) {
612
610
  }
613
611
  function validateRunConstructExtents(blocks) {
614
612
  for (const block of blocks) {
615
- if (block.kind === "paragraph" && block.constructs !== void 0) {
613
+ if (block.kind === "paragraph") {
616
614
  const fault = (0, document_schema_js.findRunConstructFault)(block);
617
615
  if (fault !== void 0) throw new require_diagnostics_diagnostics.MarkdownInvalidRunConstructExtentError(fault.kind, fault.index);
618
616
  }
package/dist/emit/emit.js CHANGED
@@ -3,7 +3,6 @@ import "../defaults/defaults.js";
3
3
  import { MarkdownDiagnosticCodes, MarkdownInvalidRunConstructExtentError, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, NOOP_MARKDOWN_DIAGNOSTIC_SINK } from "../diagnostics/diagnostics.js";
4
4
  import { matchHtmlBlockStart } from "../html/html.js";
5
5
  import { ESCAPED_HARD_BREAK_PATTERN, LINE_ENDING_PATTERN } from "../shared/line-ending.js";
6
- import "../scan/scan.js";
7
6
  import { LineCursor } from "../block/line.js";
8
7
  import { parseListMarker } from "../block/list.js";
9
8
  import { parseTableDelimiterRow, splitTableRow } from "../block/table.js";
@@ -23,9 +22,13 @@ const MAX_SETEXT_LEVEL = 2;
23
22
  const SETEXT_LEVEL_1_CHAR = "=";
24
23
  const SETEXT_LEVEL_2_CHAR = "-";
25
24
  const MIN_SETEXT_UNDERLINE_LENGTH = 1;
25
+ function splitLines(text, pattern) {
26
+ const [first, ...rest] = text.split(pattern);
27
+ return [first, ...rest];
28
+ }
26
29
  function renderSetextHeading(level, text) {
27
30
  const underlineChar = level === 1 ? SETEXT_LEVEL_1_CHAR : SETEXT_LEVEL_2_CHAR;
28
- const firstLine = text.split(LINE_ENDING_PATTERN)[0] ?? "";
31
+ const [firstLine] = splitLines(text, LINE_ENDING_PATTERN);
29
32
  return `${text}\n${underlineChar.repeat(Math.max(MIN_SETEXT_UNDERLINE_LENGTH, firstLine.length))}`;
30
33
  }
31
34
  const MIN_CODE_FENCE_LENGTH = 3;
@@ -53,19 +56,17 @@ function isQuotableStyle(styleId) {
53
56
  return QUOTABLE_STYLE_IDS.has(styleId) || parseHeadingStyleId(styleId) !== void 0;
54
57
  }
55
58
  function terminatesCleanly(styleId) {
56
- if (styleId === void 0 || styleId === "Quote" || styleId === "HTMLPreformatted") return false;
57
- return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || parseHeadingStyleId(styleId) !== void 0;
59
+ return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || styleId !== void 0 && parseHeadingStyleId(styleId) !== void 0;
58
60
  }
59
61
  const BLANK_OR_WHITESPACE_ONLY_LINE = /^[ \t]*$/;
60
62
  function firstContentLineIndex(text) {
61
63
  return text.split(LINE_ENDING_PATTERN).findIndex((line) => !BLANK_OR_WHITESPACE_ONLY_LINE.test(line));
62
64
  }
63
- function leadingIndentColumns(line) {
65
+ function leadingIndentReachesCodeThreshold(line) {
64
66
  let column = 0;
65
- for (const char of line) if (char === " ") column += 1;
66
- else if (char === " ") column += 4 - column % 4;
67
- else break;
68
- return column;
67
+ while (column < line.length && line[column] === " ") column += 1;
68
+ if (column >= 4) return true;
69
+ return line[column] === " ";
69
70
  }
70
71
  const MAX_LEADING_BLANK_LINES_FOR_SETEXT = 1;
71
72
  function interruptsSetextParagraph(line, atBlockStart) {
@@ -94,7 +95,7 @@ function unsafeSetextBreakReason(text) {
94
95
  continue;
95
96
  }
96
97
  sawContentLine = true;
97
- if (leadingIndentColumns(line) >= 4) return "leading-indentation";
98
+ if (leadingIndentReachesCodeThreshold(line)) return "leading-indentation";
98
99
  if (interruptsSetextParagraph(line, true)) return "interrupting-line";
99
100
  precedingLine = line;
100
101
  continue;
@@ -123,7 +124,7 @@ function willRenderAsSetext(paragraph, level, context) {
123
124
  }
124
125
  function canInterruptOpenParagraph(paragraph, context) {
125
126
  const styleId = paragraph.styleId;
126
- if (styleId === void 0 || styleId === "Quote" || styleId === "HTMLPreformatted") return false;
127
+ if (styleId === void 0) return false;
127
128
  if (styleId === "CodeBlock" || styleId === "MathBlock") return true;
128
129
  if (styleId === "HorizontalRule") return context.thematicBreakChar !== SETEXT_LEVEL_2_CHAR;
129
130
  const headingLevel = parseHeadingStyleId(styleId);
@@ -263,24 +264,24 @@ function toEmitItem(item) {
263
264
  function firstBlockCheckbox(first, taskNumId) {
264
265
  if (first.list.checked !== void 0) return {
265
266
  checkboxText: first.list.checked ? "[x] " : "[ ] ",
266
- stripGlyph: false
267
+ strippedFirstBlock: void 0
267
268
  };
268
269
  if (!taskNumId || first.kind !== "paragraph") return {
269
270
  checkboxText: "",
270
- stripGlyph: false
271
+ strippedFirstBlock: void 0
271
272
  };
272
273
  const leading = first.block.runs[0]?.text ?? "";
273
274
  if (leading.startsWith(`☒ `)) return {
274
275
  checkboxText: "[x] ",
275
- stripGlyph: true
276
+ strippedFirstBlock: stripCheckboxRun(first.block)
276
277
  };
277
278
  if (leading.startsWith(`☐ `)) return {
278
279
  checkboxText: "[ ] ",
279
- stripGlyph: true
280
+ strippedFirstBlock: stripCheckboxRun(first.block)
280
281
  };
281
282
  return {
282
283
  checkboxText: "",
283
- stripGlyph: false
284
+ strippedFirstBlock: void 0
284
285
  };
285
286
  }
286
287
  function renderListItemMarker(numId, info, glyph, checkboxText, context) {
@@ -315,7 +316,7 @@ function resolveListGlyph(numId, type, previousSibling, context) {
315
316
  }
316
317
  function consumeSameItemRun(items, from, level, itemId) {
317
318
  let end = from;
318
- while (end < items.length) {
319
+ for (;;) {
319
320
  const candidate = items[end];
320
321
  if (candidate?.list.level !== level || candidate.list.itemId !== itemId) break;
321
322
  end += 1;
@@ -333,7 +334,7 @@ function collectListItem(items, start, level, itemId) {
333
334
  index = ownEnd;
334
335
  for (;;) {
335
336
  let nestedEnd = index;
336
- while (nestedEnd < items.length) {
337
+ for (;;) {
337
338
  const candidateLevel = items[nestedEnd]?.list.level;
338
339
  if (candidateLevel === void 0 || candidateLevel <= level) break;
339
340
  nestedEnd += 1;
@@ -346,7 +347,6 @@ function collectListItem(items, start, level, itemId) {
346
347
  index = nestedEnd;
347
348
  if (itemId === void 0) break;
348
349
  const resumedEnd = consumeSameItemRun(items, index, level, itemId);
349
- if (resumedEnd === index) break;
350
350
  segments.push({
351
351
  kind: "own",
352
352
  blocks: items.slice(index, resumedEnd)
@@ -377,8 +377,8 @@ function regionItemCanInterrupt(item, context) {
377
377
  function lastStyleIdOfRegionItem(item) {
378
378
  return lastStyleIdOf(toEmitItem(item));
379
379
  }
380
- function listRegionItemBody(item, context, stripGlyph) {
381
- if (item.kind === "paragraph") return renderParagraphBody(stripGlyph ? stripCheckboxRun(item.block) : item.block, context);
380
+ function listRegionItemBody(item, context, overrideParagraph) {
381
+ if (item.kind === "paragraph") return renderParagraphBody(overrideParagraph ?? item.block, context);
382
382
  const previousEnclosingItemId = context.enclosingItemId;
383
383
  context.enclosingItemId = item.list.itemId;
384
384
  const body = renderConstruct(item.item, context);
@@ -393,14 +393,14 @@ function renderListRegion(items, context) {
393
393
  const parts = [];
394
394
  let index = 0;
395
395
  let previousSibling;
396
- while (index < items.length) {
396
+ for (;;) {
397
397
  const item = items[index];
398
398
  if (item === void 0) break;
399
399
  const { numId, level, itemId } = item.list;
400
400
  const info = listInfoFor(numId, context);
401
401
  const loose = info?.loose === true;
402
402
  const type = info?.type ?? "bullet";
403
- const glyph = numId === void 0 ? type === "ordered" ? context.orderedDelimiter : context.bulletMarker : resolveListGlyph(numId, type, previousSibling, context);
403
+ const glyph = numId === void 0 ? context.bulletMarker : resolveListGlyph(numId, type, previousSibling, context);
404
404
  if (numId !== void 0) previousSibling = {
405
405
  numId,
406
406
  type,
@@ -409,7 +409,7 @@ function renderListRegion(items, context) {
409
409
  const { segments, next } = collectListItem(items, index, level, itemId);
410
410
  const first = segments[0]?.blocks[0];
411
411
  if (first === void 0) break;
412
- const { checkboxText, stripGlyph } = firstBlockCheckbox(first, info?.task === true);
412
+ const { checkboxText, strippedFirstBlock } = firstBlockCheckbox(first, info?.task === true);
413
413
  const marker = renderListItemMarker(numId, info, glyph, checkboxText, context);
414
414
  const indent = " ".repeat(marker.bareLength);
415
415
  let text = "";
@@ -425,13 +425,13 @@ function renderListRegion(items, context) {
425
425
  }
426
426
  for (const block of segment.blocks) {
427
427
  if (!renderedFirstLine) {
428
- const [firstLine = "", ...restLines] = listRegionItemBody(block, context, stripGlyph).split("\n");
428
+ const [firstLine, ...restLines] = splitLines(listRegionItemBody(block, context, strippedFirstBlock), "\n");
429
429
  text = [`${marker.full}${firstLine}`, ...restLines.map((line) => `${indent}${line}`)].join("\n");
430
430
  renderedFirstLine = true;
431
431
  previousStyleId = lastStyleIdOfRegionItem(block);
432
432
  continue;
433
433
  }
434
- const rendered = listRegionItemBody(block, context, false).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
434
+ const rendered = listRegionItemBody(block, context, void 0).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
435
435
  const blank = loose || requiresBlankLineBefore(block, previousStyleId, context);
436
436
  text += blank ? `\n\n${rendered}` : `\n${rendered}`;
437
437
  previousStyleId = lastStyleIdOfRegionItem(block);
@@ -467,7 +467,7 @@ function isMaterialisedDivision(item) {
467
467
  function groupConstructItems(blocks, start) {
468
468
  const items = [];
469
469
  let index = start;
470
- while (index < blocks.length) {
470
+ for (;;) {
471
471
  const block = blocks[index];
472
472
  if (block === void 0) break;
473
473
  index += 1;
@@ -496,7 +496,7 @@ function renderFootnoteDefinition(name, body) {
496
496
  const marker = `[^${name}]:`;
497
497
  if (body.length === 0) return marker;
498
498
  const indent = " ".repeat(FOOTNOTE_CONTINUATION_INDENT);
499
- const [firstLine = "", ...restLines] = body.split("\n");
499
+ const [firstLine, ...restLines] = splitLines(body, "\n");
500
500
  return [`${marker} ${firstLine}`, ...restLines.map((line) => line.length === 0 ? line : `${indent}${line}`)].join("\n");
501
501
  }
502
502
  function renderConstruct(item, context) {
@@ -511,13 +511,11 @@ function renderConstruct(item, context) {
511
511
  });
512
512
  return body;
513
513
  }
514
- if (descriptor.kind === "division") {
515
- if (isMaterialisedDivision(item)) {
516
- context.divisionDepth += 1;
517
- const body = renderItems(item.children, context);
518
- context.divisionDepth -= 1;
519
- return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
520
- }
514
+ if (isMaterialisedDivision(item)) {
515
+ context.divisionDepth += 1;
516
+ const body = renderItems(item.children, context);
517
+ context.divisionDepth -= 1;
518
+ return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
521
519
  }
522
520
  if (descriptor.kind === "link" && descriptor.target.kind === "external") {
523
521
  const onlyChild = item.children.length === 1 && !isConstructItem(item.children[0]) ? item.children[0].block : void 0;
@@ -548,7 +546,7 @@ function isInheritedListMembership(list, context) {
548
546
  function renderItems(items, context) {
549
547
  const parts = [];
550
548
  let index = 0;
551
- while (index < items.length) {
549
+ for (;;) {
552
550
  const item = items[index];
553
551
  if (item === void 0) break;
554
552
  if (isConstructItem(item)) {
@@ -611,7 +609,7 @@ function emitBlocks(blocks, context) {
611
609
  }
612
610
  function validateRunConstructExtents(blocks) {
613
611
  for (const block of blocks) {
614
- if (block.kind === "paragraph" && block.constructs !== void 0) {
612
+ if (block.kind === "paragraph") {
615
613
  const fault = findRunConstructFault(block);
616
614
  if (fault !== void 0) throw new MarkdownInvalidRunConstructExtentError(fault.kind, fault.index);
617
615
  }
@@ -18,9 +18,9 @@ function delimiterCell(alignment) {
18
18
  function escapeUnescapedPipes(text) {
19
19
  let out = "";
20
20
  let index = 0;
21
- while (index < text.length) {
21
+ while (text.charAt(index) !== "") {
22
22
  const char = text.charAt(index);
23
- if (char === "\\" && index + 1 < text.length) {
23
+ if (char === "\\") {
24
24
  out += char + text.charAt(index + 1);
25
25
  index += 2;
26
26
  continue;
@@ -17,9 +17,9 @@ function delimiterCell(alignment) {
17
17
  function escapeUnescapedPipes(text) {
18
18
  let out = "";
19
19
  let index = 0;
20
- while (index < text.length) {
20
+ while (text.charAt(index) !== "") {
21
21
  const char = text.charAt(index);
22
- if (char === "\\" && index + 1 < text.length) {
22
+ if (char === "\\") {
23
23
  out += char + text.charAt(index + 1);
24
24
  index += 2;
25
25
  continue;
@@ -5,7 +5,6 @@ const OPEN_TAG = `<${TAG_NAME}(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^
5
5
  const CLOSING_TAG = `</${TAG_NAME}\\s*>`;
6
6
  const HTML_TAG_PATTERN = new RegExp(`^(?:${OPEN_TAG}|${CLOSING_TAG}|<!-->|<!--->|<!--[\\s\\S]*?-->|<\\?[\\s\\S]*?\\?>|<![A-Za-z][^>]*>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>)`);
7
7
  function matchHtmlTag(text, start) {
8
- if (text.charAt(start) !== "<") return;
9
8
  const match = HTML_TAG_PATTERN.exec(text.slice(start));
10
9
  return match === null ? void 0 : match[0];
11
10
  }
@@ -101,7 +100,6 @@ const HTML_BLOCK_TYPES = [
101
100
  ];
102
101
  const LAST_HTML_BLOCK_TYPE = 7;
103
102
  function matchHtmlBlockStart(line, interruptsParagraph) {
104
- if (!line.startsWith("<")) return;
105
103
  for (const type of HTML_BLOCK_TYPES) {
106
104
  if (type === LAST_HTML_BLOCK_TYPE && interruptsParagraph) continue;
107
105
  if (HTML_BLOCK_START_PATTERNS[type]?.test(line) === true) return type;
package/dist/html/html.js CHANGED
@@ -4,7 +4,6 @@ const OPEN_TAG = `<${TAG_NAME}(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^
4
4
  const CLOSING_TAG = `</${TAG_NAME}\\s*>`;
5
5
  const HTML_TAG_PATTERN = new RegExp(`^(?:${OPEN_TAG}|${CLOSING_TAG}|<!-->|<!--->|<!--[\\s\\S]*?-->|<\\?[\\s\\S]*?\\?>|<![A-Za-z][^>]*>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>)`);
6
6
  function matchHtmlTag(text, start) {
7
- if (text.charAt(start) !== "<") return;
8
7
  const match = HTML_TAG_PATTERN.exec(text.slice(start));
9
8
  return match === null ? void 0 : match[0];
10
9
  }
@@ -100,7 +99,6 @@ const HTML_BLOCK_TYPES = [
100
99
  ];
101
100
  const LAST_HTML_BLOCK_TYPE = 7;
102
101
  function matchHtmlBlockStart(line, interruptsParagraph) {
103
- if (!line.startsWith("<")) return;
104
102
  for (const type of HTML_BLOCK_TYPES) {
105
103
  if (type === LAST_HTML_BLOCK_TYPE && interruptsParagraph) continue;
106
104
  if (HTML_BLOCK_START_PATTERNS[type]?.test(line) === true) return type;
@@ -40,7 +40,7 @@ function escapeHref(href) {
40
40
  let result = "";
41
41
  for (const byte of bytes) {
42
42
  const char = String.fromCharCode(byte);
43
- if (byte < 128 && (ALPHANUMERIC_PATTERN.test(char) || HREF_SAFE_PUNCTUATION.has(char))) {
43
+ if (ALPHANUMERIC_PATTERN.test(char) || HREF_SAFE_PUNCTUATION.has(char)) {
44
44
  result += char;
45
45
  continue;
46
46
  }
@@ -67,7 +67,7 @@ function renderTaskCheckbox(checked) {
67
67
  }
68
68
  function renderInline(node) {
69
69
  switch (node.type) {
70
- case "text": return escapeHtml(node.value);
70
+ case "text":
71
71
  case "entity": return escapeHtml(node.value);
72
72
  case "codeSpan": return `<code>${escapeHtml(node.literal)}</code>`;
73
73
  case "emphasis": return `<em>${renderInlines(node.children)}</em>`;
@@ -127,7 +127,6 @@ var HtmlRenderer = class {
127
127
  this.cr();
128
128
  this.out += "<blockquote>\n";
129
129
  this.render(node.children, false);
130
- this.cr();
131
130
  this.out += "</blockquote>\n";
132
131
  return;
133
132
  case "list":
@@ -139,23 +138,17 @@ var HtmlRenderer = class {
139
138
  case "mathBlock":
140
139
  this.cr();
141
140
  this.out += `$$\n${escapeHtml(node.literal)}\n$$\n`;
142
- this.cr();
143
141
  return;
144
142
  case "footnoteDefinition":
145
143
  this.cr();
146
144
  this.out += `${escapeHtml(`[^${node.label}]:`)}\n`;
147
145
  this.render(node.children, false);
148
- this.cr();
149
146
  return;
150
- case "document":
151
- case "listItem":
152
- case "tableRow":
153
- case "tableCell": return;
154
147
  }
155
148
  }
156
149
  renderCodeBlock(infoString, literal) {
157
150
  this.cr();
158
- const language = infoString === void 0 ? "" : infoString.split(/[ \t]/)[0] ?? "";
151
+ const language = infoString === void 0 ? "" : infoString.split(/[ \t]/)[0];
159
152
  const attribute = language.length === 0 ? "" : ` class="language-${escapeHtml(language)}"`;
160
153
  this.out += `<pre><code${attribute}>${escapeHtml(literal)}</code></pre>\n`;
161
154
  }
@@ -165,7 +158,6 @@ var HtmlRenderer = class {
165
158
  const orderedOpenTag = start === DEFAULT_ORDERED_LIST_START ? "<ol>" : `<ol start="${String(start)}">`;
166
159
  this.out += `${node.markerType === "bullet" ? "<ul>" : orderedOpenTag}\n`;
167
160
  for (const item of node.children) {
168
- this.cr();
169
161
  this.out += "<li>";
170
162
  if (item.checked !== void 0) this.out += renderTaskCheckbox(item.checked);
171
163
  this.render(item.children, node.tight);
@@ -39,7 +39,7 @@ function escapeHref(href) {
39
39
  let result = "";
40
40
  for (const byte of bytes) {
41
41
  const char = String.fromCharCode(byte);
42
- if (byte < 128 && (ALPHANUMERIC_PATTERN.test(char) || HREF_SAFE_PUNCTUATION.has(char))) {
42
+ if (ALPHANUMERIC_PATTERN.test(char) || HREF_SAFE_PUNCTUATION.has(char)) {
43
43
  result += char;
44
44
  continue;
45
45
  }
@@ -66,7 +66,7 @@ function renderTaskCheckbox(checked) {
66
66
  }
67
67
  function renderInline(node) {
68
68
  switch (node.type) {
69
- case "text": return escapeHtml(node.value);
69
+ case "text":
70
70
  case "entity": return escapeHtml(node.value);
71
71
  case "codeSpan": return `<code>${escapeHtml(node.literal)}</code>`;
72
72
  case "emphasis": return `<em>${renderInlines(node.children)}</em>`;
@@ -126,7 +126,6 @@ var HtmlRenderer = class {
126
126
  this.cr();
127
127
  this.out += "<blockquote>\n";
128
128
  this.render(node.children, false);
129
- this.cr();
130
129
  this.out += "</blockquote>\n";
131
130
  return;
132
131
  case "list":
@@ -138,23 +137,17 @@ var HtmlRenderer = class {
138
137
  case "mathBlock":
139
138
  this.cr();
140
139
  this.out += `$$\n${escapeHtml(node.literal)}\n$$\n`;
141
- this.cr();
142
140
  return;
143
141
  case "footnoteDefinition":
144
142
  this.cr();
145
143
  this.out += `${escapeHtml(`[^${node.label}]:`)}\n`;
146
144
  this.render(node.children, false);
147
- this.cr();
148
145
  return;
149
- case "document":
150
- case "listItem":
151
- case "tableRow":
152
- case "tableCell": return;
153
146
  }
154
147
  }
155
148
  renderCodeBlock(infoString, literal) {
156
149
  this.cr();
157
- const language = infoString === void 0 ? "" : infoString.split(/[ \t]/)[0] ?? "";
150
+ const language = infoString === void 0 ? "" : infoString.split(/[ \t]/)[0];
158
151
  const attribute = language.length === 0 ? "" : ` class="language-${escapeHtml(language)}"`;
159
152
  this.out += `<pre><code${attribute}>${escapeHtml(literal)}</code></pre>\n`;
160
153
  }
@@ -164,7 +157,6 @@ var HtmlRenderer = class {
164
157
  const orderedOpenTag = start === DEFAULT_ORDERED_LIST_START ? "<ol>" : `<ol start="${String(start)}">`;
165
158
  this.out += `${node.markerType === "bullet" ? "<ul>" : orderedOpenTag}\n`;
166
159
  for (const item of node.children) {
167
- this.cr();
168
160
  this.out += "<li>";
169
161
  if (item.checked !== void 0) this.out += renderTaskCheckbox(item.checked);
170
162
  this.render(item.children, node.tight);