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.
- package/README.md +2 -1
- package/dist/block/block.cjs +19 -37
- package/dist/block/block.js +20 -38
- package/dist/block/definitions.cjs +1 -5
- package/dist/block/definitions.js +1 -5
- package/dist/block/line.cjs +2 -2
- package/dist/block/line.js +2 -2
- package/dist/block/list.cjs +7 -14
- package/dist/block/list.js +7 -14
- package/dist/block/node.cjs +3 -3
- package/dist/block/node.d.cts +2 -2
- package/dist/block/node.d.ts +2 -2
- package/dist/block/node.js +3 -3
- package/dist/block/table.cjs +3 -4
- package/dist/block/table.js +3 -4
- package/dist/codec.d.cts +36 -36
- package/dist/codec.d.ts +36 -36
- package/dist/emit/emit.cjs +58 -62
- package/dist/emit/emit.js +58 -62
- package/dist/emit/inline.cjs +18 -12
- package/dist/emit/inline.js +18 -12
- package/dist/emit/table.cjs +2 -2
- package/dist/emit/table.js +2 -2
- package/dist/html/html-table.cjs +14 -22
- package/dist/html/html-table.js +14 -22
- package/dist/html/html.cjs +0 -2
- package/dist/html/html.js +0 -2
- package/dist/html/render.cjs +3 -11
- package/dist/html/render.js +3 -11
- package/dist/image/image.cjs +8 -57
- package/dist/image/image.d.cts +2 -2
- package/dist/image/image.d.ts +2 -2
- package/dist/image/image.js +9 -56
- package/dist/{image-BtmTG4_a.d.cts → image-83yql5ES.d.cts} +1 -3
- package/dist/{image-BtmTG4_a.d.ts → image-83yql5ES.d.ts} +1 -3
- package/dist/{image-B5L0HpAJ.d.cts → image-B6p0Ovgy.d.cts} +1 -1
- package/dist/{image-C390OIB3.d.ts → image-gR1vISI0.d.ts} +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/inline/chars.cjs +3 -6
- package/dist/inline/chars.js +3 -6
- package/dist/inline/delimiter.cjs +5 -16
- package/dist/inline/delimiter.d.cts +2 -2
- package/dist/inline/delimiter.d.ts +2 -2
- package/dist/inline/delimiter.js +5 -16
- package/dist/inline/entity.cjs +6 -10
- package/dist/inline/entity.js +6 -10
- package/dist/inline/gfm-autolink.cjs +20 -19
- package/dist/inline/gfm-autolink.js +20 -19
- package/dist/inline/inline.cjs +29 -39
- package/dist/inline/inline.js +30 -40
- package/dist/inline/link.cjs +4 -5
- package/dist/inline/link.js +4 -5
- package/dist/lower/front-matter.cjs +4 -8
- package/dist/lower/front-matter.js +4 -8
- package/dist/lower/image.cjs +3 -2
- package/dist/lower/image.d.cts +1 -1
- package/dist/lower/image.d.ts +1 -1
- package/dist/lower/image.js +2 -1
- package/dist/lower/inline.cjs +0 -2
- package/dist/lower/inline.js +0 -2
- package/dist/lower/lower.cjs +7 -10
- package/dist/lower/lower.js +7 -10
- package/dist/options/options.d.cts +1 -1
- package/dist/options/options.d.ts +1 -1
- package/dist/read.cjs +2 -2
- package/dist/read.js +2 -2
- package/dist/scan/scan.cjs +1 -3
- package/dist/scan/scan.js +1 -3
- package/dist/shared/list-id.cjs +1 -1
- package/dist/shared/list-id.js +1 -1
- package/package.json +2 -1
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,11 +22,19 @@ 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
|
|
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
|
}
|
|
34
|
+
function renderAtxHeading(level, text) {
|
|
35
|
+
const collapsed = text.replace(ESCAPED_HARD_BREAK_PATTERN, " ").split(LINE_ENDING_PATTERN).join(" ");
|
|
36
|
+
return `${"#".repeat(level)} ${collapsed}`;
|
|
37
|
+
}
|
|
31
38
|
const MIN_CODE_FENCE_LENGTH = 3;
|
|
32
39
|
function longestRunLength(text, char) {
|
|
33
40
|
let longest = 0;
|
|
@@ -53,19 +60,17 @@ function isQuotableStyle(styleId) {
|
|
|
53
60
|
return QUOTABLE_STYLE_IDS.has(styleId) || parseHeadingStyleId(styleId) !== void 0;
|
|
54
61
|
}
|
|
55
62
|
function terminatesCleanly(styleId) {
|
|
56
|
-
|
|
57
|
-
return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || parseHeadingStyleId(styleId) !== void 0;
|
|
63
|
+
return styleId === "CodeBlock" || styleId === "MathBlock" || styleId === "HorizontalRule" || styleId !== void 0 && parseHeadingStyleId(styleId) !== void 0;
|
|
58
64
|
}
|
|
59
65
|
const BLANK_OR_WHITESPACE_ONLY_LINE = /^[ \t]*$/;
|
|
60
66
|
function firstContentLineIndex(text) {
|
|
61
67
|
return text.split(LINE_ENDING_PATTERN).findIndex((line) => !BLANK_OR_WHITESPACE_ONLY_LINE.test(line));
|
|
62
68
|
}
|
|
63
|
-
function
|
|
69
|
+
function leadingIndentReachesCodeThreshold(line) {
|
|
64
70
|
let column = 0;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return column;
|
|
71
|
+
while (line[column] === " ") column += 1;
|
|
72
|
+
if (column >= 4) return true;
|
|
73
|
+
return line[column] === " ";
|
|
69
74
|
}
|
|
70
75
|
const MAX_LEADING_BLANK_LINES_FOR_SETEXT = 1;
|
|
71
76
|
function interruptsSetextParagraph(line, atBlockStart) {
|
|
@@ -82,19 +87,17 @@ function tableDelimiterRowPromotesPrecedingLine(line, precedingLine) {
|
|
|
82
87
|
return parseTableDelimiterRow(cursor.restFromNextNonspace())?.length === splitTableRow(precedingLine).length;
|
|
83
88
|
}
|
|
84
89
|
function unsafeSetextBreakReason(text) {
|
|
85
|
-
let sawContentLine = false;
|
|
86
90
|
let leadingBlankLines = 0;
|
|
87
|
-
let precedingLine
|
|
91
|
+
let precedingLine;
|
|
88
92
|
for (const line of text.split(LINE_ENDING_PATTERN)) {
|
|
89
93
|
const isBlank = BLANK_OR_WHITESPACE_ONLY_LINE.test(line);
|
|
90
|
-
if (
|
|
94
|
+
if (precedingLine === void 0) {
|
|
91
95
|
if (isBlank) {
|
|
92
96
|
leadingBlankLines += 1;
|
|
93
97
|
if (leadingBlankLines > MAX_LEADING_BLANK_LINES_FOR_SETEXT) return "blank-line";
|
|
94
98
|
continue;
|
|
95
99
|
}
|
|
96
|
-
|
|
97
|
-
if (leadingIndentColumns(line) >= 4) return "leading-indentation";
|
|
100
|
+
if (leadingIndentReachesCodeThreshold(line)) return "leading-indentation";
|
|
98
101
|
if (interruptsSetextParagraph(line, true)) return "interrupting-line";
|
|
99
102
|
precedingLine = line;
|
|
100
103
|
continue;
|
|
@@ -103,7 +106,7 @@ function unsafeSetextBreakReason(text) {
|
|
|
103
106
|
if (interruptsSetextParagraph(line, false) || tableDelimiterRowPromotesPrecedingLine(line, precedingLine)) return "interrupting-line";
|
|
104
107
|
precedingLine = line;
|
|
105
108
|
}
|
|
106
|
-
return
|
|
109
|
+
return precedingLine === void 0 ? "blank-line" : void 0;
|
|
107
110
|
}
|
|
108
111
|
function embedsUnsafeBreakForSetext(text) {
|
|
109
112
|
return unsafeSetextBreakReason(text) !== void 0;
|
|
@@ -123,7 +126,7 @@ function willRenderAsSetext(paragraph, level, context) {
|
|
|
123
126
|
}
|
|
124
127
|
function canInterruptOpenParagraph(paragraph, context) {
|
|
125
128
|
const styleId = paragraph.styleId;
|
|
126
|
-
if (styleId === void 0
|
|
129
|
+
if (styleId === void 0) return false;
|
|
127
130
|
if (styleId === "CodeBlock" || styleId === "MathBlock") return true;
|
|
128
131
|
if (styleId === "HorizontalRule") return context.thematicBreakChar !== SETEXT_LEVEL_2_CHAR;
|
|
129
132
|
const headingLevel = parseHeadingStyleId(styleId);
|
|
@@ -176,18 +179,14 @@ function renderParagraphBody(paragraph, context) {
|
|
|
176
179
|
severity: "info",
|
|
177
180
|
message: unsafeSetextDiagnosticMessage(level, unsafeSetextReason, embedsLineBreak)
|
|
178
181
|
});
|
|
179
|
-
|
|
180
|
-
return `${"#".repeat(level)} ${text}`;
|
|
181
|
-
}
|
|
182
|
-
if (embedsLineBreak) {
|
|
183
|
-
context.sink({
|
|
184
|
-
code: MarkdownDiagnosticCodes.HEADING_LINE_BREAK_COLLAPSED,
|
|
185
|
-
severity: "info",
|
|
186
|
-
message: `a level ${String(level)} heading's own content contains a line break; only setext's own level-1/2 grammar can hold one, so ATX collapses it to a single space`
|
|
187
|
-
});
|
|
188
|
-
return `${"#".repeat(level)} ${text.replace(ESCAPED_HARD_BREAK_PATTERN, " ").split(LINE_ENDING_PATTERN).join(" ")}`;
|
|
182
|
+
return renderAtxHeading(level, text);
|
|
189
183
|
}
|
|
190
|
-
|
|
184
|
+
if (embedsLineBreak) context.sink({
|
|
185
|
+
code: MarkdownDiagnosticCodes.HEADING_LINE_BREAK_COLLAPSED,
|
|
186
|
+
severity: "info",
|
|
187
|
+
message: `a level ${String(level)} heading's own content contains a line break; only setext's own level-1/2 grammar can hold one, so ATX collapses it to a single space`
|
|
188
|
+
});
|
|
189
|
+
return renderAtxHeading(level, text);
|
|
191
190
|
}
|
|
192
191
|
return emitRuns(paragraph.runs, context, paragraph.constructs);
|
|
193
192
|
}
|
|
@@ -263,24 +262,24 @@ function toEmitItem(item) {
|
|
|
263
262
|
function firstBlockCheckbox(first, taskNumId) {
|
|
264
263
|
if (first.list.checked !== void 0) return {
|
|
265
264
|
checkboxText: first.list.checked ? "[x] " : "[ ] ",
|
|
266
|
-
|
|
265
|
+
strippedFirstBlock: void 0
|
|
267
266
|
};
|
|
268
267
|
if (!taskNumId || first.kind !== "paragraph") return {
|
|
269
268
|
checkboxText: "",
|
|
270
|
-
|
|
269
|
+
strippedFirstBlock: void 0
|
|
271
270
|
};
|
|
272
|
-
const leading = first.block.runs[0]?.text
|
|
273
|
-
if (leading
|
|
271
|
+
const leading = first.block.runs[0]?.text;
|
|
272
|
+
if (leading?.startsWith(`☒ `) === true) return {
|
|
274
273
|
checkboxText: "[x] ",
|
|
275
|
-
|
|
274
|
+
strippedFirstBlock: stripCheckboxRun(first.block)
|
|
276
275
|
};
|
|
277
|
-
if (leading
|
|
276
|
+
if (leading?.startsWith(`☐ `) === true) return {
|
|
278
277
|
checkboxText: "[ ] ",
|
|
279
|
-
|
|
278
|
+
strippedFirstBlock: stripCheckboxRun(first.block)
|
|
280
279
|
};
|
|
281
280
|
return {
|
|
282
281
|
checkboxText: "",
|
|
283
|
-
|
|
282
|
+
strippedFirstBlock: void 0
|
|
284
283
|
};
|
|
285
284
|
}
|
|
286
285
|
function renderListItemMarker(numId, info, glyph, checkboxText, context) {
|
|
@@ -315,7 +314,7 @@ function resolveListGlyph(numId, type, previousSibling, context) {
|
|
|
315
314
|
}
|
|
316
315
|
function consumeSameItemRun(items, from, level, itemId) {
|
|
317
316
|
let end = from;
|
|
318
|
-
|
|
317
|
+
for (;;) {
|
|
319
318
|
const candidate = items[end];
|
|
320
319
|
if (candidate?.list.level !== level || candidate.list.itemId !== itemId) break;
|
|
321
320
|
end += 1;
|
|
@@ -333,7 +332,7 @@ function collectListItem(items, start, level, itemId) {
|
|
|
333
332
|
index = ownEnd;
|
|
334
333
|
for (;;) {
|
|
335
334
|
let nestedEnd = index;
|
|
336
|
-
|
|
335
|
+
for (;;) {
|
|
337
336
|
const candidateLevel = items[nestedEnd]?.list.level;
|
|
338
337
|
if (candidateLevel === void 0 || candidateLevel <= level) break;
|
|
339
338
|
nestedEnd += 1;
|
|
@@ -346,7 +345,6 @@ function collectListItem(items, start, level, itemId) {
|
|
|
346
345
|
index = nestedEnd;
|
|
347
346
|
if (itemId === void 0) break;
|
|
348
347
|
const resumedEnd = consumeSameItemRun(items, index, level, itemId);
|
|
349
|
-
if (resumedEnd === index) break;
|
|
350
348
|
segments.push({
|
|
351
349
|
kind: "own",
|
|
352
350
|
blocks: items.slice(index, resumedEnd)
|
|
@@ -377,8 +375,8 @@ function regionItemCanInterrupt(item, context) {
|
|
|
377
375
|
function lastStyleIdOfRegionItem(item) {
|
|
378
376
|
return lastStyleIdOf(toEmitItem(item));
|
|
379
377
|
}
|
|
380
|
-
function listRegionItemBody(item, context,
|
|
381
|
-
if (item.kind === "paragraph") return renderParagraphBody(
|
|
378
|
+
function listRegionItemBody(item, context, overrideParagraph) {
|
|
379
|
+
if (item.kind === "paragraph") return renderParagraphBody(overrideParagraph ?? item.block, context);
|
|
382
380
|
const previousEnclosingItemId = context.enclosingItemId;
|
|
383
381
|
context.enclosingItemId = item.list.itemId;
|
|
384
382
|
const body = renderConstruct(item.item, context);
|
|
@@ -393,14 +391,14 @@ function renderListRegion(items, context) {
|
|
|
393
391
|
const parts = [];
|
|
394
392
|
let index = 0;
|
|
395
393
|
let previousSibling;
|
|
396
|
-
|
|
394
|
+
for (;;) {
|
|
397
395
|
const item = items[index];
|
|
398
396
|
if (item === void 0) break;
|
|
399
397
|
const { numId, level, itemId } = item.list;
|
|
400
398
|
const info = listInfoFor(numId, context);
|
|
401
399
|
const loose = info?.loose === true;
|
|
402
400
|
const type = info?.type ?? "bullet";
|
|
403
|
-
const glyph = numId === void 0 ?
|
|
401
|
+
const glyph = numId === void 0 ? context.bulletMarker : resolveListGlyph(numId, type, previousSibling, context);
|
|
404
402
|
if (numId !== void 0) previousSibling = {
|
|
405
403
|
numId,
|
|
406
404
|
type,
|
|
@@ -409,10 +407,10 @@ function renderListRegion(items, context) {
|
|
|
409
407
|
const { segments, next } = collectListItem(items, index, level, itemId);
|
|
410
408
|
const first = segments[0]?.blocks[0];
|
|
411
409
|
if (first === void 0) break;
|
|
412
|
-
const { checkboxText,
|
|
410
|
+
const { checkboxText, strippedFirstBlock } = firstBlockCheckbox(first, info?.task === true);
|
|
413
411
|
const marker = renderListItemMarker(numId, info, glyph, checkboxText, context);
|
|
414
412
|
const indent = " ".repeat(marker.bareLength);
|
|
415
|
-
let text =
|
|
413
|
+
let text = marker.full;
|
|
416
414
|
let renderedFirstLine = false;
|
|
417
415
|
let previousStyleId;
|
|
418
416
|
for (const segment of segments) {
|
|
@@ -425,13 +423,13 @@ function renderListRegion(items, context) {
|
|
|
425
423
|
}
|
|
426
424
|
for (const block of segment.blocks) {
|
|
427
425
|
if (!renderedFirstLine) {
|
|
428
|
-
const [firstLine
|
|
429
|
-
text
|
|
426
|
+
const [firstLine, ...restLines] = splitLines(listRegionItemBody(block, context, strippedFirstBlock), "\n");
|
|
427
|
+
text += [firstLine, ...restLines.map((line) => `${indent}${line}`)].join("\n");
|
|
430
428
|
renderedFirstLine = true;
|
|
431
429
|
previousStyleId = lastStyleIdOfRegionItem(block);
|
|
432
430
|
continue;
|
|
433
431
|
}
|
|
434
|
-
const rendered = listRegionItemBody(block, context,
|
|
432
|
+
const rendered = listRegionItemBody(block, context, void 0).split("\n").map((line) => line.length === 0 ? line : `${indent}${line}`).join("\n");
|
|
435
433
|
const blank = loose || requiresBlankLineBefore(block, previousStyleId, context);
|
|
436
434
|
text += blank ? `\n\n${rendered}` : `\n${rendered}`;
|
|
437
435
|
previousStyleId = lastStyleIdOfRegionItem(block);
|
|
@@ -447,9 +445,8 @@ function renderListRegion(items, context) {
|
|
|
447
445
|
for (const [partIndex, part] of parts.entries()) {
|
|
448
446
|
if (partIndex > 0) {
|
|
449
447
|
const previous = parts[partIndex - 1];
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
out += sameList && !loose ? "\n" : "\n\n";
|
|
448
|
+
const continuesTightly = previous.numId === part.numId && (previous.numId === void 0 || parseListNumId(previous.numId)?.loose !== true);
|
|
449
|
+
out += continuesTightly ? "\n" : "\n\n";
|
|
453
450
|
}
|
|
454
451
|
out += part.text;
|
|
455
452
|
}
|
|
@@ -458,16 +455,17 @@ function renderListRegion(items, context) {
|
|
|
458
455
|
function isConstructItem(item) {
|
|
459
456
|
return "descriptor" in item;
|
|
460
457
|
}
|
|
458
|
+
const UNINDENTED_PT = 0;
|
|
461
459
|
function isMaterialisedDivision(item) {
|
|
462
460
|
return item.descriptor.kind === "division" && item.children.every((child) => {
|
|
463
461
|
if (isConstructItem(child)) return true;
|
|
464
|
-
return child.block.kind !== "paragraph" || child.block.indentLeftPt
|
|
462
|
+
return child.block.kind !== "paragraph" || (child.block.indentLeftPt ?? UNINDENTED_PT) >= 36;
|
|
465
463
|
});
|
|
466
464
|
}
|
|
467
465
|
function groupConstructItems(blocks, start) {
|
|
468
466
|
const items = [];
|
|
469
467
|
let index = start;
|
|
470
|
-
|
|
468
|
+
for (;;) {
|
|
471
469
|
const block = blocks[index];
|
|
472
470
|
if (block === void 0) break;
|
|
473
471
|
index += 1;
|
|
@@ -496,7 +494,7 @@ function renderFootnoteDefinition(name, body) {
|
|
|
496
494
|
const marker = `[^${name}]:`;
|
|
497
495
|
if (body.length === 0) return marker;
|
|
498
496
|
const indent = " ".repeat(FOOTNOTE_CONTINUATION_INDENT);
|
|
499
|
-
const [firstLine
|
|
497
|
+
const [firstLine, ...restLines] = splitLines(body, "\n");
|
|
500
498
|
return [`${marker} ${firstLine}`, ...restLines.map((line) => line.length === 0 ? line : `${indent}${line}`)].join("\n");
|
|
501
499
|
}
|
|
502
500
|
function renderConstruct(item, context) {
|
|
@@ -511,13 +509,11 @@ function renderConstruct(item, context) {
|
|
|
511
509
|
});
|
|
512
510
|
return body;
|
|
513
511
|
}
|
|
514
|
-
if (
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
|
|
520
|
-
}
|
|
512
|
+
if (isMaterialisedDivision(item)) {
|
|
513
|
+
context.divisionDepth += 1;
|
|
514
|
+
const body = renderItems(item.children, context);
|
|
515
|
+
context.divisionDepth -= 1;
|
|
516
|
+
return body.split("\n").map((line) => line.length === 0 ? ">" : `> ${line}`).join("\n");
|
|
521
517
|
}
|
|
522
518
|
if (descriptor.kind === "link" && descriptor.target.kind === "external") {
|
|
523
519
|
const onlyChild = item.children.length === 1 && !isConstructItem(item.children[0]) ? item.children[0].block : void 0;
|
|
@@ -548,7 +544,7 @@ function isInheritedListMembership(list, context) {
|
|
|
548
544
|
function renderItems(items, context) {
|
|
549
545
|
const parts = [];
|
|
550
546
|
let index = 0;
|
|
551
|
-
|
|
547
|
+
for (;;) {
|
|
552
548
|
const item = items[index];
|
|
553
549
|
if (item === void 0) break;
|
|
554
550
|
if (isConstructItem(item)) {
|
|
@@ -611,7 +607,7 @@ function emitBlocks(blocks, context) {
|
|
|
611
607
|
}
|
|
612
608
|
function validateRunConstructExtents(blocks) {
|
|
613
609
|
for (const block of blocks) {
|
|
614
|
-
if (block.kind === "paragraph"
|
|
610
|
+
if (block.kind === "paragraph") {
|
|
615
611
|
const fault = findRunConstructFault(block);
|
|
616
612
|
if (fault !== void 0) throw new MarkdownInvalidRunConstructExtentError(fault.kind, fault.index);
|
|
617
613
|
}
|
package/dist/emit/inline.cjs
CHANGED
|
@@ -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
|
-
|
|
43
|
-
const char = text
|
|
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
|
|
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 =
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
package/dist/emit/inline.js
CHANGED
|
@@ -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
|
-
|
|
42
|
-
const char = text
|
|
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
|
|
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 =
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
package/dist/emit/table.cjs
CHANGED
|
@@ -18,9 +18,9 @@ function delimiterCell(alignment) {
|
|
|
18
18
|
function escapeUnescapedPipes(text) {
|
|
19
19
|
let out = "";
|
|
20
20
|
let index = 0;
|
|
21
|
-
while (index
|
|
21
|
+
while (text.charAt(index) !== "") {
|
|
22
22
|
const char = text.charAt(index);
|
|
23
|
-
if (char === "\\"
|
|
23
|
+
if (char === "\\") {
|
|
24
24
|
out += char + text.charAt(index + 1);
|
|
25
25
|
index += 2;
|
|
26
26
|
continue;
|
package/dist/emit/table.js
CHANGED
|
@@ -17,9 +17,9 @@ function delimiterCell(alignment) {
|
|
|
17
17
|
function escapeUnescapedPipes(text) {
|
|
18
18
|
let out = "";
|
|
19
19
|
let index = 0;
|
|
20
|
-
while (index
|
|
20
|
+
while (text.charAt(index) !== "") {
|
|
21
21
|
const char = text.charAt(index);
|
|
22
|
-
if (char === "\\"
|
|
22
|
+
if (char === "\\") {
|
|
23
23
|
out += char + text.charAt(index + 1);
|
|
24
24
|
index += 2;
|
|
25
25
|
continue;
|
package/dist/html/html-table.cjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
|
|
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;
|