@descent-vtt/spec-brief 0.2.2 → 0.2.3
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/CHANGELOG.md +31 -0
- package/dist/markdown.d.ts +5 -3
- package/dist/markdown.js +19 -13
- package/dist/markdown.js.map +1 -1
- package/dist/vendor/spec-core/markdown/index.d.ts +1 -1
- package/dist/vendor/spec-core/markdown/index.js.map +1 -1
- package/dist/vendor/spec-core/markdown/links.d.ts +6 -0
- package/dist/vendor/spec-core/markdown/links.js +57 -15
- package/dist/vendor/spec-core/markdown/links.js.map +1 -1
- package/dist/vendor/spec-core/markdown/scan.js +23 -13
- package/dist/vendor/spec-core/markdown/scan.js.map +1 -1
- package/dist/vendor/spec-core/markdown/syntax.d.ts +2 -0
- package/dist/vendor/spec-core/markdown/syntax.js +6 -1
- package/dist/vendor/spec-core/markdown/syntax.js.map +1 -1
- package/dist/vendor/spec-core/markdown/types.d.ts +23 -0
- package/dist/vendor/spec-core/markdown/types.js.map +1 -1
- package/dist/vendor/spec-core/pattern/glob.d.ts +2 -1
- package/dist/vendor/spec-core/pattern/glob.js +61 -2
- package/dist/vendor/spec-core/pattern/glob.js.map +1 -1
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes, newest first. Versions follow [semver](https://semver.org).
|
|
4
4
|
|
|
5
|
+
## 0.2.3
|
|
6
|
+
|
|
7
|
+
spec-core at 119345e. A link inside a link now counts only the inner one, as
|
|
8
|
+
CommonMark and a renderer read it, so archival leaves the outer destination
|
|
9
|
+
as written. The refusal of `**` inside a name suggests patterns built from
|
|
10
|
+
the one written.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- spec-core at 119345e. Its Markdown scanner reads a link inside a link's
|
|
15
|
+
text as CommonMark does: in `[a [b](inner.md) c](outer.md)` the inner pair
|
|
16
|
+
is the link, and the outer brackets and `(outer.md)` are text. `archive`
|
|
17
|
+
and `unarchive` rewrite `inner.md` and leave `(outer.md)` as written,
|
|
18
|
+
where they rewrote both; a renderer links nothing to `outer.md`, so it
|
|
19
|
+
does not move with the brief. spec-brief no longer reads a link's text
|
|
20
|
+
again to find the inner link. It still reads an image's alt text and a
|
|
21
|
+
wiki link's text, which the scanner leaves unread, and keeps each
|
|
22
|
+
destination once.
|
|
23
|
+
- The `glob` error for `**` inside a name suggests the pattern written,
|
|
24
|
+
spelled both ways it may have meant: `docs/**.md` is told `docs/**/*.md`
|
|
25
|
+
for any depth or `docs/*.md` for one level, and `src/a**` `src/a*/**` or
|
|
26
|
+
`src/a*`, where every such pattern was told `docs/**/*.md` or `*.md`. The
|
|
27
|
+
message's first clause is as it was.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Text shaped like a reference definition at the start of a link's text,
|
|
32
|
+
`see [[r]: r.md](z.md)`, is no longer rewritten by `archive`. spec-brief
|
|
33
|
+
read the link's text on its own, where that text starts a line and reads
|
|
34
|
+
as a definition.
|
|
35
|
+
|
|
5
36
|
## 0.2.2
|
|
6
37
|
|
|
7
38
|
A packaging fix: the tarball no longer carries spec-core's internal README.
|
package/dist/markdown.d.ts
CHANGED
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
* space, `x` or `X`. The scanner reads `[~]`, `[?]` and others as well,
|
|
14
14
|
* which a brief does not write.
|
|
15
15
|
* - A link destination is one written in the link or in a definition: the
|
|
16
|
-
* inline form and the definition, images included, an image
|
|
17
|
-
* a link
|
|
18
|
-
*
|
|
16
|
+
* inline form and the definition, images included, an image inside a link's
|
|
17
|
+
* text, and a link or an image in an image's alt text or a wiki link's text
|
|
18
|
+
* too, each once. A link inside a link's text is the link, as CommonMark
|
|
19
|
+
* reads it, and the brackets around it are text. A reference is rewritten
|
|
20
|
+
* through its definition, once.
|
|
19
21
|
*
|
|
20
22
|
* Everything here is in 0-based lines of the brief's `lines`, and columns
|
|
21
23
|
* within them.
|
package/dist/markdown.js
CHANGED
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
* space, `x` or `X`. The scanner reads `[~]`, `[?]` and others as well,
|
|
14
14
|
* which a brief does not write.
|
|
15
15
|
* - A link destination is one written in the link or in a definition: the
|
|
16
|
-
* inline form and the definition, images included, an image
|
|
17
|
-
* a link
|
|
18
|
-
*
|
|
16
|
+
* inline form and the definition, images included, an image inside a link's
|
|
17
|
+
* text, and a link or an image in an image's alt text or a wiki link's text
|
|
18
|
+
* too, each once. A link inside a link's text is the link, as CommonMark
|
|
19
|
+
* reads it, and the brackets around it are text. A reference is rewritten
|
|
20
|
+
* through its definition, once.
|
|
19
21
|
*
|
|
20
22
|
* Everything here is in 0-based lines of the brief's `lines`, and columns
|
|
21
23
|
* within them.
|
|
@@ -31,19 +33,23 @@ function isBox(checkbox) {
|
|
|
31
33
|
* definitions - with offsets into the text scanned `at` that offset, added to
|
|
32
34
|
* `found` by the offset of the destination.
|
|
33
35
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* after the link
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
36
|
+
* spec-core reads a link's text as CommonMark does: a link inside it is the
|
|
37
|
+
* link, so `[a [b](b.md)](c.md)` gives `b.md` alone, and an image inside it,
|
|
38
|
+
* `[](d.md)`, is listed after the link. It reads nothing in
|
|
39
|
+
* an image's alt text or a wiki link's text, where a destination still moves
|
|
40
|
+
* with the brief, so those two are read again here. Each is shorter than the
|
|
41
|
+
* text it came from, so the reading ends.
|
|
42
|
+
*
|
|
43
|
+
* spec-core also reads a definition at the start of any line, where
|
|
44
|
+
* CommonMark lets none interrupt a paragraph, and so lists one that lies in
|
|
45
|
+
* an image's alt text written over lines. Read again, the alt text gives it a
|
|
46
|
+
* second time. It is one destination, kept once, because two rewrites of the
|
|
47
|
+
* same columns would write the second over the first.
|
|
43
48
|
*/
|
|
44
49
|
function written(core, at, found) {
|
|
45
50
|
for (const link of core.links) {
|
|
46
|
-
|
|
51
|
+
if (link.image || link.form === 'wiki')
|
|
52
|
+
written(scanMarkdown(link.text), at + core.text.indexOf(link.text, link.start), found);
|
|
47
53
|
if (link.form === 'inline' || link.form === 'definition') {
|
|
48
54
|
found.set(at + link.targetStart, { ...link, targetStart: at + link.targetStart, targetEnd: at + link.targetEnd });
|
|
49
55
|
}
|
package/dist/markdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A brief's Markdown: spec-core's scanner, copied into `src/vendor/spec-core/`,\n * read in spec-brief's dialect.\n *\n * The scanner is exact about what is code and what is a comment, as CommonMark\n * has it, and reports every heading, list item and link it finds. What of that\n * is a brief's structure is decided here (ADR-0001, amended 2026-09-26):\n *\n * - A heading is an ATX heading outside a block quote. Prose over a `---` is a\n * setext heading to a renderer, and a brief that separates its parts that way\n * must not grow a section from it; a heading in a block quote is quoted.\n * - A task is a list item outside a block quote with a box GFM renders: a\n * space, `x` or `X`. The scanner reads `[~]`, `[?]` and others as well,\n * which a brief does not write.\n * - A link destination is one written in the link or in a definition: the\n * inline form and the definition, images included, an image or a link inside\n * a link's text too, each once. A reference is rewritten through its\n * definition, once.\n *\n * Everything here is in 0-based lines of the brief's `lines`, and columns\n * within them.\n */\n\nimport { type Link, linesOf, type MarkdownScan, scanMarkdown, type ScannedLine } from './vendor/spec-core/markdown/index.js';\nimport { textOfLines } from './text.js';\n\nexport interface Heading {\n /** 0-based line. */\n readonly line: number;\n readonly level: number;\n /** As a reader sees it: without a closing sequence or a comment. */\n readonly text: string;\n}\n\nexport interface Section {\n readonly heading: Heading;\n /** 0-based line after the section's last line. The body starts on the line after the heading. */\n readonly end: number;\n}\n\nexport interface TaskItem {\n /** 0-based line of the box. */\n readonly line: number;\n /** 0-based line after the item's last line: its continuations and what is nested under it. */\n readonly end: number;\n readonly checked: boolean;\n readonly text: string;\n}\n\nexport interface LinkDestination {\n /** 0-based line. */\n readonly line: number;\n /** Columns of the destination within the line, end exclusive. */\n readonly start: number;\n readonly end: number;\n readonly target: string;\n}\n\nexport interface Scan {\n readonly lines: readonly string[];\n /** Lines with front matter and comments blanked, and code kept: what counts as content. */\n readonly prose: readonly string[];\n /** Lines with front matter, code, raw-text HTML and comments blanked: what counts as structure. */\n readonly masked: readonly string[];\n readonly headings: readonly Heading[];\n readonly tasks: readonly TaskItem[];\n /** Destinations outside code and comments, each once, in the order of their lines and columns. */\n readonly links: readonly LinkDestination[];\n}\n\n/** Whether a checkbox is one a task is written with. */\nfunction isBox(checkbox: string | null): boolean {\n return checkbox === ' ' || checkbox === 'x' || checkbox === 'X';\n}\n\n/**\n * The links that write their destination - inline links and images, and\n * definitions - with offsets into the text scanned `at` that offset, added to\n * `found` by the offset of the destination.\n *\n * A link's text may hold an image, `[](d.md)`, whose\n * destination moves with the brief as the link's does. spec-core lists it\n * after the link, and reads nothing else there: not a link in the text,\n * `[a [b](b.md)](c.md)`, which CommonMark takes as the link where spec-core\n * takes the outer pair, nor an image in an image's alt text or a wiki link's.\n * So each text is read again here, which finds spec-core's image a second\n * time. It is one destination, kept once, because two rewrites of the same\n * columns would write the second over the first. Each text is shorter than\n * the one it came from, so the reading ends.\n */\nfunction written(core: MarkdownScan, at: number, found: Map<number, Link>): Map<number, Link> {\n for (const link of core.links) {\n written(scanMarkdown(link.text), at + core.text.indexOf(link.text, link.start), found);\n if (link.form === 'inline' || link.form === 'definition') {\n found.set(at + link.targetStart, { ...link, targetStart: at + link.targetStart, targetEnd: at + link.targetEnd });\n }\n }\n return found;\n}\n\n/** Scans a brief's lines, which carry no byte-order mark. */\nexport function scan(lines: readonly string[]): Scan {\n const core = scanMarkdown(textOfLines(lines));\n const unquoted = (line: number): boolean => (core.lines[line - 1] as ScannedLine).quoteDepth === 0;\n return {\n lines,\n prose: linesOf(core, 'prose'),\n masked: linesOf(core, 'structure'),\n headings: core.headings\n .filter((h) => h.form === 'atx' && unquoted(h.line))\n .map((h) => ({ line: h.line - 1, level: h.level, text: h.text })),\n tasks: core.listItems\n .filter((item) => isBox(item.checkbox) && item.quoteDepth === 0)\n .map((item) => ({ line: item.line - 1, end: item.endLine, checked: item.checkbox !== ' ', text: item.firstLine })),\n links: [...written(core, 0, new Map()).values()]\n .map((link) => {\n // A link's text may run over lines; its destination is on the last.\n const at = core.index.positionAt(link.targetStart);\n const start = at.column - 1;\n return { line: at.line - 1, start, end: start + link.targetEnd - link.targetStart, target: link.target };\n })\n .sort((a, b) => a.line - b.line || a.start - b.start),\n };\n}\n\n/** Sections: every heading below the title, running to the next heading at its level or above. */\nexport function sectionsOf(result: Scan): Section[] {\n const sections: Section[] = [];\n const { headings } = result;\n for (let h = 0; h < headings.length; h += 1) {\n const heading = headings[h] as Heading;\n if (heading.level < 2) continue;\n let end = result.lines.length;\n for (let k = h + 1; k < headings.length; k += 1) {\n const next = headings[k] as Heading;\n if (next.level <= heading.level) {\n end = next.line;\n break;\n }\n }\n sections.push({ heading, end });\n }\n return sections;\n}\n\n/** The first level-one heading, which is what a reader takes as the title. */\nexport function titleOf(result: Scan): Heading | undefined {\n return result.headings.find((h) => h.level === 1);\n}\n\n/** Whether a line carries anything once comments are removed. */\nexport function hasContent(proseLine: string): boolean {\n return proseLine.trim().length > 0;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A brief's Markdown: spec-core's scanner, copied into `src/vendor/spec-core/`,\n * read in spec-brief's dialect.\n *\n * The scanner is exact about what is code and what is a comment, as CommonMark\n * has it, and reports every heading, list item and link it finds. What of that\n * is a brief's structure is decided here (ADR-0001, amended 2026-09-26):\n *\n * - A heading is an ATX heading outside a block quote. Prose over a `---` is a\n * setext heading to a renderer, and a brief that separates its parts that way\n * must not grow a section from it; a heading in a block quote is quoted.\n * - A task is a list item outside a block quote with a box GFM renders: a\n * space, `x` or `X`. The scanner reads `[~]`, `[?]` and others as well,\n * which a brief does not write.\n * - A link destination is one written in the link or in a definition: the\n * inline form and the definition, images included, an image inside a link's\n * text, and a link or an image in an image's alt text or a wiki link's text\n * too, each once. A link inside a link's text is the link, as CommonMark\n * reads it, and the brackets around it are text. A reference is rewritten\n * through its definition, once.\n *\n * Everything here is in 0-based lines of the brief's `lines`, and columns\n * within them.\n */\n\nimport { type Link, linesOf, type MarkdownScan, scanMarkdown, type ScannedLine } from './vendor/spec-core/markdown/index.js';\nimport { textOfLines } from './text.js';\n\nexport interface Heading {\n /** 0-based line. */\n readonly line: number;\n readonly level: number;\n /** As a reader sees it: without a closing sequence or a comment. */\n readonly text: string;\n}\n\nexport interface Section {\n readonly heading: Heading;\n /** 0-based line after the section's last line. The body starts on the line after the heading. */\n readonly end: number;\n}\n\nexport interface TaskItem {\n /** 0-based line of the box. */\n readonly line: number;\n /** 0-based line after the item's last line: its continuations and what is nested under it. */\n readonly end: number;\n readonly checked: boolean;\n readonly text: string;\n}\n\nexport interface LinkDestination {\n /** 0-based line. */\n readonly line: number;\n /** Columns of the destination within the line, end exclusive. */\n readonly start: number;\n readonly end: number;\n readonly target: string;\n}\n\nexport interface Scan {\n readonly lines: readonly string[];\n /** Lines with front matter and comments blanked, and code kept: what counts as content. */\n readonly prose: readonly string[];\n /** Lines with front matter, code, raw-text HTML and comments blanked: what counts as structure. */\n readonly masked: readonly string[];\n readonly headings: readonly Heading[];\n readonly tasks: readonly TaskItem[];\n /** Destinations outside code and comments, each once, in the order of their lines and columns. */\n readonly links: readonly LinkDestination[];\n}\n\n/** Whether a checkbox is one a task is written with. */\nfunction isBox(checkbox: string | null): boolean {\n return checkbox === ' ' || checkbox === 'x' || checkbox === 'X';\n}\n\n/**\n * The links that write their destination - inline links and images, and\n * definitions - with offsets into the text scanned `at` that offset, added to\n * `found` by the offset of the destination.\n *\n * spec-core reads a link's text as CommonMark does: a link inside it is the\n * link, so `[a [b](b.md)](c.md)` gives `b.md` alone, and an image inside it,\n * `[](d.md)`, is listed after the link. It reads nothing in\n * an image's alt text or a wiki link's text, where a destination still moves\n * with the brief, so those two are read again here. Each is shorter than the\n * text it came from, so the reading ends.\n *\n * spec-core also reads a definition at the start of any line, where\n * CommonMark lets none interrupt a paragraph, and so lists one that lies in\n * an image's alt text written over lines. Read again, the alt text gives it a\n * second time. It is one destination, kept once, because two rewrites of the\n * same columns would write the second over the first.\n */\nfunction written(core: MarkdownScan, at: number, found: Map<number, Link>): Map<number, Link> {\n for (const link of core.links) {\n if (link.image || link.form === 'wiki') written(scanMarkdown(link.text), at + core.text.indexOf(link.text, link.start), found);\n if (link.form === 'inline' || link.form === 'definition') {\n found.set(at + link.targetStart, { ...link, targetStart: at + link.targetStart, targetEnd: at + link.targetEnd });\n }\n }\n return found;\n}\n\n/** Scans a brief's lines, which carry no byte-order mark. */\nexport function scan(lines: readonly string[]): Scan {\n const core = scanMarkdown(textOfLines(lines));\n const unquoted = (line: number): boolean => (core.lines[line - 1] as ScannedLine).quoteDepth === 0;\n return {\n lines,\n prose: linesOf(core, 'prose'),\n masked: linesOf(core, 'structure'),\n headings: core.headings\n .filter((h) => h.form === 'atx' && unquoted(h.line))\n .map((h) => ({ line: h.line - 1, level: h.level, text: h.text })),\n tasks: core.listItems\n .filter((item) => isBox(item.checkbox) && item.quoteDepth === 0)\n .map((item) => ({ line: item.line - 1, end: item.endLine, checked: item.checkbox !== ' ', text: item.firstLine })),\n links: [...written(core, 0, new Map()).values()]\n .map((link) => {\n // A link's text may run over lines; its destination is on the last.\n const at = core.index.positionAt(link.targetStart);\n const start = at.column - 1;\n return { line: at.line - 1, start, end: start + link.targetEnd - link.targetStart, target: link.target };\n })\n .sort((a, b) => a.line - b.line || a.start - b.start),\n };\n}\n\n/** Sections: every heading below the title, running to the next heading at its level or above. */\nexport function sectionsOf(result: Scan): Section[] {\n const sections: Section[] = [];\n const { headings } = result;\n for (let h = 0; h < headings.length; h += 1) {\n const heading = headings[h] as Heading;\n if (heading.level < 2) continue;\n let end = result.lines.length;\n for (let k = h + 1; k < headings.length; k += 1) {\n const next = headings[k] as Heading;\n if (next.level <= heading.level) {\n end = next.line;\n break;\n }\n }\n sections.push({ heading, end });\n }\n return sections;\n}\n\n/** The first level-one heading, which is what a reader takes as the title. */\nexport function titleOf(result: Scan): Heading | undefined {\n return result.headings.find((h) => h.level === 1);\n}\n\n/** Whether a line carries anything once comments are removed. */\nexport function hasContent(proseLine: string): boolean {\n return proseLine.trim().length > 0;\n}\n"]}
|
|
@@ -2,4 +2,4 @@ export { linesOf, scanMarkdown } from './scan.js';
|
|
|
2
2
|
export { sectionsOf, slugify, titleOf } from './headings.js';
|
|
3
3
|
export { findEntry, frontMatterCloses, frontMatterKind, isNull, keyName, parseInline, readFrontMatter, removeEntry, renderScalar, setEntry, } from './frontmatter.js';
|
|
4
4
|
export type { FrontMatter, FrontMatterEntry, FrontMatterProblem, ReadOptions, YamlScalar, YamlValue, } from './frontmatter.js';
|
|
5
|
-
export type { Block, BlockKind, FrontMatterBlock, FrontMatterKind, Heading, HeadingForm, HtmlComment, Link, LinkForm, ListItem, MarkdownScan, MaskKind, Masks, ScannedLine, Section, Table, TableCell, TableRow, } from './types.js';
|
|
5
|
+
export type { Block, BlockKind, FrontMatterBlock, FrontMatterKind, Heading, HeadingForm, HtmlComment, Link, LinkForm, ListItem, MarkdownScan, MaskKind, Masks, ScannedLine, Section, Table, TableCell, TableRow, UnclosedFrontMatter, } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/markdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,MAAM,EACN,OAAO,EACP,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,MAAM,kBAAkB,CAAC","sourcesContent":["export { linesOf, scanMarkdown } from './scan.js';\nexport { sectionsOf, slugify, titleOf } from './headings.js';\nexport {\n findEntry,\n frontMatterCloses,\n frontMatterKind,\n isNull,\n keyName,\n parseInline,\n readFrontMatter,\n removeEntry,\n renderScalar,\n setEntry,\n} from './frontmatter.js';\nexport type {\n FrontMatter,\n FrontMatterEntry,\n FrontMatterProblem,\n ReadOptions,\n YamlScalar,\n YamlValue,\n} from './frontmatter.js';\nexport type {\n Block,\n BlockKind,\n FrontMatterBlock,\n FrontMatterKind,\n Heading,\n HeadingForm,\n HtmlComment,\n Link,\n LinkForm,\n ListItem,\n MarkdownScan,\n MaskKind,\n Masks,\n ScannedLine,\n Section,\n Table,\n TableCell,\n TableRow,\n} from './types.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/markdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,MAAM,EACN,OAAO,EACP,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,MAAM,kBAAkB,CAAC","sourcesContent":["export { linesOf, scanMarkdown } from './scan.js';\nexport { sectionsOf, slugify, titleOf } from './headings.js';\nexport {\n findEntry,\n frontMatterCloses,\n frontMatterKind,\n isNull,\n keyName,\n parseInline,\n readFrontMatter,\n removeEntry,\n renderScalar,\n setEntry,\n} from './frontmatter.js';\nexport type {\n FrontMatter,\n FrontMatterEntry,\n FrontMatterProblem,\n ReadOptions,\n YamlScalar,\n YamlValue,\n} from './frontmatter.js';\nexport type {\n Block,\n BlockKind,\n FrontMatterBlock,\n FrontMatterKind,\n Heading,\n HeadingForm,\n HtmlComment,\n Link,\n LinkForm,\n ListItem,\n MarkdownScan,\n MaskKind,\n Masks,\n ScannedLine,\n Section,\n Table,\n TableCell,\n TableRow,\n UnclosedFrontMatter,\n} from './types.js';\n"]}
|
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
* badge wrapped in a link has two destinations - and for nothing else; each
|
|
11
11
|
* is listed after the link it lies in.
|
|
12
12
|
*
|
|
13
|
+
* Links may not contain links, as CommonMark has it: in
|
|
14
|
+
* `[a [b](inner.md) c](outer.md)` the inner pair is the link, and the outer
|
|
15
|
+
* brackets and `(outer.md)` are text. So before a paragraph is read its pairs
|
|
16
|
+
* are read innermost first, as CommonMark reads them, to learn which `[`
|
|
17
|
+
* holds a link at any depth.
|
|
18
|
+
*
|
|
13
19
|
* Brackets are paired once per paragraph with a stack, and the tables that
|
|
14
20
|
* say where a destination or a title ends are built once per paragraph, so
|
|
15
21
|
* no bracket searches the text again for its partner. A document of nothing
|
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
* badge wrapped in a link has two destinations - and for nothing else; each
|
|
11
11
|
* is listed after the link it lies in.
|
|
12
12
|
*
|
|
13
|
+
* Links may not contain links, as CommonMark has it: in
|
|
14
|
+
* `[a [b](inner.md) c](outer.md)` the inner pair is the link, and the outer
|
|
15
|
+
* brackets and `(outer.md)` are text. So before a paragraph is read its pairs
|
|
16
|
+
* are read innermost first, as CommonMark reads them, to learn which `[`
|
|
17
|
+
* holds a link at any depth.
|
|
18
|
+
*
|
|
13
19
|
* Brackets are paired once per paragraph with a stack, and the tables that
|
|
14
20
|
* say where a destination or a title ends are built once per paragraph, so
|
|
15
21
|
* no bracket searches the text again for its partner. A document of nothing
|
|
@@ -112,26 +118,37 @@ function readAutolinks(layout) {
|
|
|
112
118
|
}
|
|
113
119
|
return out;
|
|
114
120
|
}
|
|
115
|
-
/** Pairs `[` with `]` inside a paragraph, innermost first, skipping escaped ones. */
|
|
116
121
|
function pairBrackets(structure, from, to) {
|
|
117
|
-
const
|
|
122
|
+
const brackets = { pairs: new Map(), outer: new Map(), before: new Map(), images: new Set() };
|
|
123
|
+
const { pairs } = brackets;
|
|
118
124
|
const open = [];
|
|
125
|
+
let escaped = -1;
|
|
119
126
|
for (let at = from; at < to; at += 1) {
|
|
120
127
|
const ch = structure.charCodeAt(at);
|
|
121
|
-
if (ch === BACKSLASH)
|
|
128
|
+
if (ch === BACKSLASH) {
|
|
129
|
+
escaped = at + 1;
|
|
122
130
|
at += 1;
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
}
|
|
132
|
+
else if (ch === OPEN_BRACKET) {
|
|
133
|
+
open.push({ at, before: pairs.size });
|
|
134
|
+
if (structure.charCodeAt(at - 1) === BANG && escaped !== at - 1)
|
|
135
|
+
brackets.images.add(at);
|
|
136
|
+
}
|
|
125
137
|
else if (ch === CLOSE_BRACKET) {
|
|
126
138
|
// A `]` with nothing to close pairs with nothing; recorded under
|
|
127
139
|
// `undefined` it would not be found either, so this test changes no
|
|
128
|
-
// answer, only what the
|
|
140
|
+
// answer, only what the maps hold.
|
|
129
141
|
const opened = open.pop();
|
|
130
|
-
if (opened !== undefined)
|
|
131
|
-
pairs.set(opened, at);
|
|
142
|
+
if (opened !== undefined) {
|
|
143
|
+
pairs.set(opened.at, at);
|
|
144
|
+
brackets.before.set(opened.at, opened.before);
|
|
145
|
+
const around = open[open.length - 1];
|
|
146
|
+
if (around !== undefined)
|
|
147
|
+
brackets.outer.set(opened.at, around.at);
|
|
148
|
+
}
|
|
132
149
|
}
|
|
133
150
|
}
|
|
134
|
-
return
|
|
151
|
+
return brackets;
|
|
135
152
|
}
|
|
136
153
|
function endsOf(structure, from, to) {
|
|
137
154
|
const length = to - from;
|
|
@@ -191,7 +208,10 @@ function readBrackets(layout, definitions, defined) {
|
|
|
191
208
|
last += 1;
|
|
192
209
|
const from = lines[first].start;
|
|
193
210
|
const to = lines[last].end;
|
|
194
|
-
const
|
|
211
|
+
const brackets = pairBrackets(structure, from, to);
|
|
212
|
+
const { pairs } = brackets;
|
|
213
|
+
// Each `[` with a link inside it, at any depth.
|
|
214
|
+
const holding = new Set();
|
|
195
215
|
let ends = null;
|
|
196
216
|
// Spaces and tabs, and at most one line ending inside the paragraph. The
|
|
197
217
|
// character at `to` ends the paragraph's last line and is none of these.
|
|
@@ -300,7 +320,8 @@ function readBrackets(layout, definitions, defined) {
|
|
|
300
320
|
};
|
|
301
321
|
const bracket = (at, start, image, line) => {
|
|
302
322
|
const close = pairs.get(at);
|
|
303
|
-
|
|
323
|
+
// A link holding a link is text; an image holding one is still an image.
|
|
324
|
+
if (close === undefined || (!image && holding.has(at)))
|
|
304
325
|
return null;
|
|
305
326
|
const label = () => text.slice(at + 1, close).trim();
|
|
306
327
|
if (structure.charCodeAt(close + 1) === OPEN_PAREN) {
|
|
@@ -329,10 +350,32 @@ function readBrackets(layout, definitions, defined) {
|
|
|
329
350
|
return null;
|
|
330
351
|
return { form: 'shortcut', image, text: label(), label: label(), start, end: close + 1, line: line.line, ...found };
|
|
331
352
|
};
|
|
332
|
-
|
|
353
|
+
const lineAt = (at) => lines[layout.index.positionAt(at).line - 1];
|
|
354
|
+
// CommonMark reads each pair at its `]`, so the pairs inside a `[` are
|
|
355
|
+
// read before it, and a link among them makes it text, and every `[`
|
|
356
|
+
// open around it: the pairs come innermost first, and fill `holding` on
|
|
357
|
+
// the way out. An image among them does not; a link may hold one. What a
|
|
358
|
+
// link or an image reads past its `]` - a destination, a title, a second
|
|
359
|
+
// label - is not read for links again: `reach` is the furthest any of the
|
|
360
|
+
// first so many pairs read to, and a `[` short of it opens nothing.
|
|
361
|
+
const reach = [from];
|
|
362
|
+
for (const at of pairs.keys()) {
|
|
363
|
+
const line = lineAt(at);
|
|
364
|
+
const image = brackets.images.has(at);
|
|
365
|
+
const passed = reach[brackets.before.get(at)] > at;
|
|
366
|
+
const link = passed || defined.has(line.line) ? null : bracket(at, at, image, line);
|
|
367
|
+
reach.push(Math.max(reach[reach.length - 1], link === null ? from : link.end));
|
|
368
|
+
const around = brackets.outer.get(at);
|
|
369
|
+
if (around !== undefined && (holding.has(at) || (link !== null && !image)))
|
|
370
|
+
holding.add(around);
|
|
371
|
+
}
|
|
333
372
|
let at = from;
|
|
334
373
|
// Inside a link's text, up to its `]`, where CommonMark reads an image -
|
|
335
374
|
// a badge wrapped in a link - but no other link; then on past the link.
|
|
375
|
+
// `textEnd` is -1 or a `]` that closes a `[`, so never 0, and the `]` is
|
|
376
|
+
// read as no link. Leaving one step later, past it, resumes at the same
|
|
377
|
+
// place, or ends the paragraph where a shortcut link ended it anyway: the
|
|
378
|
+
// test below reads the same with `textEnd > 0` or `at > textEnd`.
|
|
336
379
|
let textEnd = -1;
|
|
337
380
|
let resume = -1;
|
|
338
381
|
while (at < to) {
|
|
@@ -343,7 +386,6 @@ function readBrackets(layout, definitions, defined) {
|
|
|
343
386
|
}
|
|
344
387
|
const ch = structure.charCodeAt(at);
|
|
345
388
|
if (ch === BACKSLASH) {
|
|
346
|
-
escaped = at + 1;
|
|
347
389
|
at += 2;
|
|
348
390
|
continue;
|
|
349
391
|
}
|
|
@@ -351,14 +393,14 @@ function readBrackets(layout, definitions, defined) {
|
|
|
351
393
|
at += 1;
|
|
352
394
|
continue;
|
|
353
395
|
}
|
|
354
|
-
const line =
|
|
396
|
+
const line = lineAt(at);
|
|
355
397
|
// A definition's line holds its label, its destination and its title,
|
|
356
398
|
// and none of them is a link.
|
|
357
399
|
if (defined.has(line.line)) {
|
|
358
400
|
at = line.end;
|
|
359
401
|
continue;
|
|
360
402
|
}
|
|
361
|
-
const image =
|
|
403
|
+
const image = brackets.images.has(at);
|
|
362
404
|
const start = image ? at - 1 : at;
|
|
363
405
|
const link = wiki(at, start, image, line) ?? bracket(at, start, image, line);
|
|
364
406
|
if (textEnd >= 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/markdown/links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAe,MAAM,aAAa,CAAC;AAGjF,MAAM,IAAI,GAAG,EAAE,CAAC;AAChB,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,EAAE,GAAG,EAAE,CAAC;AACd,MAAM,EAAE,GAAG,EAAE,CAAC;AAEd,6DAA6D;AAC7D,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB,MAAM,UAAU,GAAG,gDAAgD,CAAC;AACpE,wFAAwF;AACxF,MAAM,UAAU,GAAG,kDAAkD,CAAC;AACtE,MAAM,QAAQ,GAAG,qCAAqC,CAAC;AAQvD,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzF,sEAAsE;IACtE,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,MAAc,EAAE,WAAoC;IAC3E,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACnC,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC;YAAE,SAAS;QAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAAE,SAAS;QAChF,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,GAAI,KAAK,CAAC,CAAC,CAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACpF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAW,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;QACjD,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;QACpF,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAClI,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,KAAK,CAAC,CAAC,CAAW;YAC1B,KAAK,EAAE,IAAI;YACX,KAAK;YACL,GAAG;YACH,WAAW,EAAE,KAAK,GAAG,CAAC;YACtB,SAAS,EAAE,GAAG,GAAG,CAAC;YAClB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI;SAC1C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qFAAqF;AACrF,SAAS,YAAY,CAAC,SAAiB,EAAE,IAAY,EAAE,EAAU;IAC/D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,EAAE,KAAK,SAAS;YAAE,EAAE,IAAI,CAAC,CAAC;aACzB,IAAI,EAAE,KAAK,YAAY;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aACvC,IAAI,EAAE,KAAK,aAAa,EAAE,CAAC;YAC9B,iEAAiE;YACjE,oEAAoE;YACpE,mCAAmC;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1B,IAAI,MAAM,KAAK,SAAS;gBAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAkBD,SAAS,MAAM,CAAC,SAAiB,EAAE,IAAY,EAAE,EAAU;IACzD,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3F,CAAC;IACD,oEAAoE;IACpE,0EAA0E;IAC1E,MAAM,IAAI,GAAG,GAAe,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnE,MAAM,IAAI,GAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;IACrI,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;QACpB,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC;QAC5E,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC;QAC9C,IAAI,KAAK,IAAI,EAAE,KAAK,WAAW;YAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;aAC/C,IAAI,KAAK,IAAI,EAAE,KAAK,UAAU;YAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI,CAAW,CAAC;;YAC3F,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC;QAC9F,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC;QAC9F,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC;QAC3F,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAY,CAAC;IAC1F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AASD;;;;GAIG;AACH,SAAS,YAAY,CAAC,MAAc,EAAE,WAA4C,EAAE,OAA4B;IAC9G,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IACrD,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,2EAA2E;IAC3E,6CAA6C;IAC7C,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC;IAErB,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAU,EAA0B,EAAE,CAClE,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE5F,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,WAAW,GAAG,CAAC,CAAS,EAAW,EAAE;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC/D,CAAC,CAAC;IAEF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YAAE,SAAS;QAClC,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,OAAO,WAAW,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YAAE,IAAI,IAAI,CAAC,CAAC;QACnE,MAAM,IAAI,GAAI,KAAK,CAAC,KAAK,CAAiB,CAAC,KAAK,CAAC;QACjD,MAAM,EAAE,GAAI,KAAK,CAAC,IAAI,CAAiB,CAAC,GAAG,CAAC;QAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI,GAAgB,IAAI,CAAC;QAE7B,yEAAyE;QACzE,yEAAyE;QACzE,MAAM,SAAS,GAAG,CAAC,KAAa,EAAU,EAAE;YAC1C,IAAI,EAAE,GAAG,KAAK,CAAC;YACf,OAAO,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC;gBAAE,EAAE,IAAI,CAAC,CAAC;YAC5C,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;gBACZ,IAAI,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;oBAAE,EAAE,IAAI,CAAC,CAAC;gBAC7C,IAAI,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;oBAAE,EAAE,IAAI,CAAC,CAAC;gBAC7C,OAAO,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC;oBAAE,EAAE,IAAI,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,CAAC,IAAY,EAAsB,EAAE;YACvD,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,WAAmB,CAAC;YACxB,IAAI,SAAiB,CAAC;YACtB,IAAI,KAAa,CAAC;YAClB,IAAI,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC3C,wDAAwD;gBACxD,IAAI,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC;gBACnB,SAAS,CAAC;oBACR,IAAI,KAAK,IAAI,EAAE;wBAAE,OAAO,IAAI,CAAC;oBAC7B,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;oBACvC,IAAI,EAAE,KAAK,YAAY;wBAAE,MAAM;oBAC/B,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;wBAAE,OAAO,IAAI,CAAC;oBAC5D,KAAK,IAAI,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,CAAC;gBACD,WAAW,GAAG,EAAE,GAAG,CAAC,CAAC;gBACrB,SAAS,GAAG,KAAK,CAAC;gBAClB,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,IAAI,KAAK,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAW,CAAC;gBAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAW,CAAC;gBAC9C,WAAW,GAAG,EAAE,CAAC;gBACjB,yDAAyD;gBACzD,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC1C,KAAK,GAAG,SAAS,CAAC;gBAClB,2DAA2D;gBAC3D,IAAI,SAAS,KAAK,EAAE;oBAAE,OAAO,IAAI,CAAC;YACpC,CAAC;YACD,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,WAAW;gBAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3F,uEAAuE;YACvE,IAAI,CAAC,KAAK,KAAK;gBAAE,OAAO,IAAI,CAAC;YAC7B,IAAI,KAAK,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YACvB,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,KAAa,CAAC;YAClB,IAAI,KAAK,KAAK,YAAY;gBAAE,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAW,CAAC;iBAC7D,IAAI,KAAK,KAAK,YAAY;gBAAE,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAW,CAAC;YACvE,wDAAwD;iBACnD,IAAI,KAAK,KAAK,UAAU;gBAAE,KAAK,GAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAY,GAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAY,CAAC;;gBACvI,OAAO,IAAI,CAAC;YACjB,uEAAuE;YACvE,+DAA+D;YAC/D,IAAI,KAAK,KAAK,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC9B,CAAC,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACzB,OAAO,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACjG,CAAC,CAAC;QAEF,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,KAAa,EAAE,KAAc,EAAE,IAAiB,EAAe,EAAE;YACzF,IAAI,SAAS,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,YAAY;gBAAE,OAAO,IAAI,CAAC;YAC/D,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,WAAW,GAAG,EAAE,GAAG,CAAC;gBAAE,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;YAC9F,MAAM,KAAK,GAAG,WAAW,CAAC;YAC1B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACpE,mDAAmD;YACnD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACrC,MAAM,WAAW,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;YACrE,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK;gBACL,IAAI,EAAE,OAAO;gBACb,MAAM;gBACN,KAAK,EAAE,IAAI;gBACX,KAAK;gBACL,GAAG,EAAE,KAAK,GAAG,CAAC;gBACd,WAAW;gBACX,SAAS,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM;gBACtC,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,KAAa,EAAE,KAAc,EAAE,IAAiB,EAAe,EAAE;YAC5F,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACrC,MAAM,KAAK,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7D,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;gBACnD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACpC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAClB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC5D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;gBACxG,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,+EAA+E;gBAC/E,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACtC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,0EAA0E;oBAC1E,MAAM,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,CAAC,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;oBACrG,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;oBAC9E,IAAI,KAAK,KAAK,SAAS;wBAAE,OAAO,IAAI,CAAC;oBACrC,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC7E,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;gBAC1H,CAAC;YACH,CAAC;YACD,sFAAsF;YACtF,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACpC,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACrC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;QACtH,CAAC,CAAC;QAEF,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,EAAE,GAAG,IAAI,CAAC;QACd,yEAAyE;QACzE,wEAAwE;QACxE,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;QAChB,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;YACf,IAAI,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;gBAClC,EAAE,GAAG,MAAM,CAAC;gBACZ,OAAO,GAAG,CAAC,CAAC,CAAC;gBACb,SAAS;YACX,CAAC;YACD,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACpC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;gBACrB,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC;gBACjB,EAAE,IAAI,CAAC,CAAC;gBACR,SAAS;YACX,CAAC;YACD,IAAI,EAAE,KAAK,YAAY,EAAE,CAAC;gBACxB,EAAE,IAAI,CAAC,CAAC;gBACR,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAgB,CAAC;YACxE,sEAAsE;YACtE,8BAA8B;YAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3B,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;gBACd,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,IAAI,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC;YAC1E,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7E,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;gBACjB,sEAAsE;gBACtE,kCAAkC;gBAClC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,OAAO,EAAE,CAAC;oBAC/E,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACf,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,EAAE,IAAI,CAAC,CAAC;gBACV,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACzB,EAAE,IAAI,CAAC,CAAC;YACV,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACxC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAW,CAAC;oBAClC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC;oBAClB,EAAE,IAAI,CAAC,CAAC;gBACV,CAAC;qBAAM,CAAC;oBACN,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Links, images and reference definitions, read from the structure mask so\n * that nothing in code or a comment is one.\n *\n * Six forms: inline `[text](dest \"title\")`, full and collapsed reference\n * `[text][label]` and `[label][]`, shortcut `[label]`, autolink `<https://x>`,\n * wiki `[[target|text]]`, and the definition `[label]: dest` the reference\n * forms are read through. Each may be an image, written with a leading `!`.\n * A link's text is read again for images, which CommonMark renders there - a\n * badge wrapped in a link has two destinations - and for nothing else; each\n * is listed after the link it lies in.\n *\n * Brackets are paired once per paragraph with a stack, and the tables that\n * say where a destination or a title ends are built once per paragraph, so\n * no bracket searches the text again for its partner. A document of nothing\n * but brackets costs its length.\n *\n * A paragraph ends at `to`, and the character there is a line terminator,\n * which no loop here acts on; nor is any lookup made at the first three\n * offsets of a paragraph, before the shortest `[](` could end. Mutants that\n * move a bound onto those places change no answer, and are equivalent.\n */\n\nimport { inRanges, mergeRanges } from '../text/index.js';\nimport { isMarkdown, isSpaceOrTab, visibleLead, type Layout } from './layout.js';\nimport type { Link, ScannedLine } from './types.js';\n\nconst BANG = 33;\nconst DOUBLE_QUOTE = 34;\nconst SINGLE_QUOTE = 39;\nconst OPEN_PAREN = 40;\nconst CLOSE_PAREN = 41;\nconst LESS_THAN = 60;\nconst GREATER_THAN = 62;\nconst OPEN_BRACKET = 91;\nconst BACKSLASH = 92;\nconst CLOSE_BRACKET = 93;\nconst LF = 10;\nconst CR = 13;\n\n/** CommonMark: a link label holds at most 999 characters. */\nconst MAX_LABEL = 999;\n\nconst DEFINITION = /^ {0,3}\\[(?!\\^)([^\\]]+)\\]:[ \\t]*(<[^<>]*>|\\S+)/;\n/** What may follow a definition's destination: nothing, or a title after whitespace. */\nconst TITLE_ONLY = /^(?:[ \\t]+(?:\"[^\"]*\"|'[^']*'|\\([^)]*\\)))?[ \\t]*$/;\nconst AUTOLINK = /<((?:https?|ftp|mailto):[^<>\\s]+)>/g;\n\ninterface Definition {\n readonly target: string;\n readonly targetStart: number;\n readonly targetEnd: number;\n}\n\nexport function findLinks(layout: Layout): Link[] {\n const definitions = new Map<string, Definition>();\n const defined = readDefinitions(layout, definitions);\n const bracketed = readBrackets(layout, definitions, new Set(defined.map((d) => d.line)));\n // `<https://x>` as a link's destination or text is part of that link.\n const taken = mergeRanges([...defined, ...bracketed]);\n const autolinks = readAutolinks(layout).filter((link) => !inRanges(taken, link.start));\n return [...defined, ...bracketed, ...autolinks].sort((a, b) => a.start - b.start);\n}\n\n/**\n * How labels compare: trimmed, whitespace collapsed, and case folded as\n * CommonMark's reference implementations fold it, down and then up, so that\n * `ẞ` and `SS` are one label.\n */\nfunction normalizeLabel(label: string): string {\n return label.trim().replace(/\\s+/g, ' ').toLowerCase().toUpperCase();\n}\n\n/**\n * Definitions come first: the reference forms are read through them, and a\n * definition is conventionally written at the foot of the file, after the\n * links that use it. The first definition of a label wins.\n *\n * `[Note]: this matters` is prose that looks like one, so a definition has\n * nothing after its destination but a title. `[^1]: text` is a footnote.\n */\nfunction readDefinitions(layout: Layout, definitions: Map<string, Definition>): Link[] {\n const { text, structure } = layout;\n const out: Link[] = [];\n for (const line of layout.lines) {\n if (!isMarkdown(line) || !visibleLead(layout, line)) continue;\n const masked = structure.slice(line.contentStart, line.end);\n const match = DEFINITION.exec(masked);\n if (match === null || !TITLE_ONLY.test(masked.slice(match[0].length))) continue;\n const start = line.contentStart + match[0].indexOf('[');\n const label = text.slice(start + 1, start + 1 + (match[1] as string).length).trim();\n if (label.length === 0) continue;\n const written = match[2] as string;\n const end = line.contentStart + match[0].length;\n const angle = written.charCodeAt(0) === LESS_THAN ? 1 : 0;\n const targetStart = end - written.length + angle;\n const targetEnd = end - angle;\n const target = text.slice(targetStart, targetEnd);\n const key = normalizeLabel(label);\n if (!definitions.has(key)) definitions.set(key, { target, targetStart, targetEnd });\n out.push({ form: 'definition', image: false, text: label, target, label, start, end, targetStart, targetEnd, line: line.line });\n }\n return out;\n}\n\nfunction readAutolinks(layout: Layout): Link[] {\n const out: Link[] = [];\n for (const match of layout.structure.matchAll(AUTOLINK)) {\n const start = match.index;\n const end = start + match[0].length;\n out.push({\n form: 'autolink',\n image: false,\n text: '',\n target: match[1] as string,\n label: null,\n start,\n end,\n targetStart: start + 1,\n targetEnd: end - 1,\n line: layout.index.positionAt(start).line,\n });\n }\n return out;\n}\n\n/** Pairs `[` with `]` inside a paragraph, innermost first, skipping escaped ones. */\nfunction pairBrackets(structure: string, from: number, to: number): Map<number, number> {\n const pairs = new Map<number, number>();\n const open: number[] = [];\n for (let at = from; at < to; at += 1) {\n const ch = structure.charCodeAt(at);\n if (ch === BACKSLASH) at += 1;\n else if (ch === OPEN_BRACKET) open.push(at);\n else if (ch === CLOSE_BRACKET) {\n // A `]` with nothing to close pairs with nothing; recorded under\n // `undefined` it would not be found either, so this test changes no\n // answer, only what the map holds.\n const opened = open.pop();\n if (opened !== undefined) pairs.set(opened, at);\n }\n }\n return pairs;\n}\n\n/**\n * For every offset of a paragraph, where what starts there ends, or the end\n * of the paragraph when nothing does: a bare destination at the next space or\n * control character, or at the first `)` its own parentheses leave unmatched;\n * a title at its next unescaped closing quote or parenthesis. Filled from the\n * right in one pass, so every lookup is a read.\n */\ninterface Ends {\n readonly space: Int32Array;\n readonly paren: Int32Array;\n readonly doubleQuote: Int32Array;\n readonly singleQuote: Int32Array;\n readonly closeParen: Int32Array;\n readonly openParen: Int32Array;\n}\n\nfunction endsOf(structure: string, from: number, to: number): Ends {\n const length = to - from;\n const escaped = new Uint8Array(length + 1);\n for (let x = 0; x < length; x += 1) {\n if (escaped[x] === 0 && structure.charCodeAt(from + x) === BACKSLASH) escaped[x + 1] = 1;\n }\n // Two past the last offset: a `(` whose `)` is the paragraph's last\n // character looks one further for the next unmatched `)`, and finds none.\n const make = (): Int32Array => new Int32Array(length + 2).fill(to);\n const ends: Ends = { space: make(), paren: make(), doubleQuote: make(), singleQuote: make(), closeParen: make(), openParen: make() };\n for (let x = length - 1; x >= 0; x -= 1) {\n const at = from + x;\n const ch = structure.charCodeAt(at);\n const plain = escaped[x] === 0;\n ends.space[x] = ch <= 32 || ch === 127 ? at : (ends.space[x + 1] as number);\n // From a `(`, the first unmatched `)` is the first one after the `)` that\n // closes it, which is the first unmatched `)` after the `(`.\n const unmatched = ends.paren[x + 1] as number;\n if (plain && ch === CLOSE_PAREN) ends.paren[x] = at;\n else if (plain && ch === OPEN_PAREN) ends.paren[x] = ends.paren[unmatched + 1 - from] as number;\n else ends.paren[x] = unmatched;\n ends.doubleQuote[x] = plain && ch === DOUBLE_QUOTE ? at : (ends.doubleQuote[x + 1] as number);\n ends.singleQuote[x] = plain && ch === SINGLE_QUOTE ? at : (ends.singleQuote[x + 1] as number);\n ends.closeParen[x] = plain && ch === CLOSE_PAREN ? at : (ends.closeParen[x + 1] as number);\n ends.openParen[x] = plain && ch === OPEN_PAREN ? at : (ends.openParen[x + 1] as number);\n }\n return ends;\n}\n\ninterface Destination {\n readonly targetStart: number;\n readonly targetEnd: number;\n /** Offset just past the closing `)`. */\n readonly end: number;\n}\n\n/**\n * The bracket forms, a paragraph at a time. A paragraph here is a run of\n * Markdown lines, none blank, each continuing the one above: a bracket never\n * pairs across a blank line, a heading, or the start of another block.\n */\nfunction readBrackets(layout: Layout, definitions: ReadonlyMap<string, Definition>, defined: ReadonlySet<number>): Link[] {\n const { lines, continues, structure, text } = layout;\n const out: Link[] = [];\n // The first `]]` at or after the last place one was looked for; the cursor\n // only moves forward, so each is found once.\n let doubleClose = -2;\n\n const lookup = (from: number, to: number): Definition | undefined =>\n to - from > MAX_LABEL ? undefined : definitions.get(normalizeLabel(text.slice(from, to)));\n\n // A blank or code line let into a paragraph would bring only characters the\n // structure mask blanks, so this test shapes the runs and changes no link.\n const inParagraph = (i: number): boolean => {\n const line = lines[i];\n return line !== undefined && isMarkdown(line) && !line.blank;\n };\n\n for (let first = 0; first < lines.length; first += 1) {\n if (!inParagraph(first)) continue;\n let last = first;\n while (inParagraph(last + 1) && continues.has(last + 2)) last += 1;\n const from = (lines[first] as ScannedLine).start;\n const to = (lines[last] as ScannedLine).end;\n const pairs = pairBrackets(structure, from, to);\n let ends: Ends | null = null;\n\n // Spaces and tabs, and at most one line ending inside the paragraph. The\n // character at `to` ends the paragraph's last line and is none of these.\n const skipSpace = (start: number): number => {\n let at = start;\n while (isSpaceOrTab(structure, at)) at += 1;\n if (at < to) {\n if (structure.charCodeAt(at) === CR) at += 1;\n if (structure.charCodeAt(at) === LF) at += 1;\n while (isSpaceOrTab(structure, at)) at += 1;\n }\n return at;\n };\n\n const destination = (open: number): Destination | null => {\n const at = skipSpace(open);\n let targetStart: number;\n let targetEnd: number;\n let after: number;\n if (structure.charCodeAt(at) === LESS_THAN) {\n // `<dest>`: no line ending and no unescaped `<` inside.\n let close = at + 1;\n for (;;) {\n if (close >= to) return null;\n const ch = structure.charCodeAt(close);\n if (ch === GREATER_THAN) break;\n if (ch === LESS_THAN || ch === LF || ch === CR) return null;\n close += ch === BACKSLASH ? 2 : 1;\n }\n targetStart = at + 1;\n targetEnd = close;\n after = close + 1;\n } else {\n ends ??= endsOf(structure, from, to);\n const space = ends.space[at - from] as number;\n const paren = ends.paren[at - from] as number;\n targetStart = at;\n // The two are equal only when neither is found, at `to`.\n targetEnd = paren < space ? paren : space;\n after = targetEnd;\n // An empty destination points nowhere a reader can follow.\n if (targetEnd === at) return null;\n }\n let k = skipSpace(after);\n if (structure.charCodeAt(k) === CLOSE_PAREN) return { targetStart, targetEnd, end: k + 1 };\n // A title is separated from the destination by whitespace, and quoted.\n if (k === after) return null;\n ends ??= endsOf(structure, from, to);\n const x = k + 1 - from;\n const quote = structure.charCodeAt(k);\n let close: number;\n if (quote === DOUBLE_QUOTE) close = ends.doubleQuote[x] as number;\n else if (quote === SINGLE_QUOTE) close = ends.singleQuote[x] as number;\n // A title in parentheses may not hold an unescaped `(`.\n else if (quote === OPEN_PAREN) close = (ends.openParen[x] as number) < (ends.closeParen[x] as number) ? to : (ends.closeParen[x] as number);\n else return null;\n // Equal ends are `to`, where the title fails either way. Past `to` the\n // next line opens a block of its own, and none opens with `)`.\n if (close === to) return null;\n k = skipSpace(close + 1);\n return structure.charCodeAt(k) === CLOSE_PAREN ? { targetStart, targetEnd, end: k + 1 } : null;\n };\n\n const wiki = (at: number, start: number, image: boolean, line: ScannedLine): Link | null => {\n if (structure.charCodeAt(at + 1) !== OPEN_BRACKET) return null;\n if (doubleClose !== -1 && doubleClose < at + 2) doubleClose = structure.indexOf(']]', at + 2);\n const close = doubleClose;\n if (close < 0 || close + 2 > line.end) return null;\n const inner = text.slice(at + 2, close);\n const written = inner.trim();\n const pipe = written.indexOf('|');\n const target = (pipe < 0 ? written : written.slice(0, pipe)).trim();\n // `[[ ]]` and `[[|text]]` name nothing to link to.\n if (target.length === 0) return null;\n const targetStart = at + 2 + inner.length - inner.trimStart().length;\n return {\n form: 'wiki',\n image,\n text: written,\n target,\n label: null,\n start,\n end: close + 2,\n targetStart,\n targetEnd: targetStart + target.length,\n line: line.line,\n };\n };\n\n const bracket = (at: number, start: number, image: boolean, line: ScannedLine): Link | null => {\n const close = pairs.get(at);\n if (close === undefined) return null;\n const label = (): string => text.slice(at + 1, close).trim();\n if (structure.charCodeAt(close + 1) === OPEN_PAREN) {\n const dest = destination(close + 2);\n if (dest !== null) {\n const target = text.slice(dest.targetStart, dest.targetEnd);\n return { form: 'inline', image, text: label(), target, label: null, start, line: line.line, ...dest };\n }\n } else {\n // Only a `[` is paired, so a second label follows exactly when this finds one.\n const refClose = pairs.get(close + 1);\n if (refClose !== undefined) {\n // `[text][]` is read through its text; `[text][label]` through its label.\n const collapsed = refClose - close - 2 <= MAX_LABEL && text.slice(close + 2, refClose).trim() === '';\n const found = collapsed ? lookup(at + 1, close) : lookup(close + 2, refClose);\n if (found === undefined) return null;\n const written = collapsed ? label() : text.slice(close + 2, refClose).trim();\n return { form: 'reference', image, text: label(), label: written, start, end: refClose + 1, line: line.line, ...found };\n }\n }\n // `[text](not a destination)` is a shortcut followed by text, as CommonMark reads it.\n const found = lookup(at + 1, close);\n if (found === undefined) return null;\n return { form: 'shortcut', image, text: label(), label: label(), start, end: close + 1, line: line.line, ...found };\n };\n\n let escaped = -1;\n let at = from;\n // Inside a link's text, up to its `]`, where CommonMark reads an image -\n // a badge wrapped in a link - but no other link; then on past the link.\n let textEnd = -1;\n let resume = -1;\n while (at < to) {\n if (textEnd >= 0 && at >= textEnd) {\n at = resume;\n textEnd = -1;\n continue;\n }\n const ch = structure.charCodeAt(at);\n if (ch === BACKSLASH) {\n escaped = at + 1;\n at += 2;\n continue;\n }\n if (ch !== OPEN_BRACKET) {\n at += 1;\n continue;\n }\n const line = lines[layout.index.positionAt(at).line - 1] as ScannedLine;\n // A definition's line holds its label, its destination and its title,\n // and none of them is a link.\n if (defined.has(line.line)) {\n at = line.end;\n continue;\n }\n const image = structure.charCodeAt(at - 1) === BANG && escaped !== at - 1;\n const start = image ? at - 1 : at;\n const link = wiki(at, start, image, line) ?? bracket(at, start, image, line);\n if (textEnd >= 0) {\n // An image that closes inside the text; its own text is alt text, and\n // holds nothing a reader follows.\n if (link !== null && link.image && link.form !== 'wiki' && link.end <= textEnd) {\n out.push(link);\n at = link.end;\n } else {\n at += 1;\n }\n } else if (link === null) {\n at += 1;\n } else {\n out.push(link);\n if (!link.image && link.form !== 'wiki') {\n textEnd = pairs.get(at) as number;\n resume = link.end;\n at += 1;\n } else {\n at = link.end;\n }\n }\n }\n first = last;\n }\n return out;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/markdown/links.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Links, images and reference definitions, read from the structure mask so\n * that nothing in code or a comment is one.\n *\n * Six forms: inline `[text](dest \"title\")`, full and collapsed reference\n * `[text][label]` and `[label][]`, shortcut `[label]`, autolink `<https://x>`,\n * wiki `[[target|text]]`, and the definition `[label]: dest` the reference\n * forms are read through. Each may be an image, written with a leading `!`.\n * A link's text is read again for images, which CommonMark renders there - a\n * badge wrapped in a link has two destinations - and for nothing else; each\n * is listed after the link it lies in.\n *\n * Links may not contain links, as CommonMark has it: in\n * `[a [b](inner.md) c](outer.md)` the inner pair is the link, and the outer\n * brackets and `(outer.md)` are text. So before a paragraph is read its pairs\n * are read innermost first, as CommonMark reads them, to learn which `[`\n * holds a link at any depth.\n *\n * Brackets are paired once per paragraph with a stack, and the tables that\n * say where a destination or a title ends are built once per paragraph, so\n * no bracket searches the text again for its partner. A document of nothing\n * but brackets costs its length.\n *\n * A paragraph ends at `to`, and the character there is a line terminator,\n * which no loop here acts on; nor is any lookup made at the first three\n * offsets of a paragraph, before the shortest `[](` could end. Mutants that\n * move a bound onto those places change no answer, and are equivalent.\n */\n\nimport { inRanges, mergeRanges } from '../text/index.js';\nimport { isMarkdown, isSpaceOrTab, visibleLead, type Layout } from './layout.js';\nimport type { Link, ScannedLine } from './types.js';\n\nconst BANG = 33;\nconst DOUBLE_QUOTE = 34;\nconst SINGLE_QUOTE = 39;\nconst OPEN_PAREN = 40;\nconst CLOSE_PAREN = 41;\nconst LESS_THAN = 60;\nconst GREATER_THAN = 62;\nconst OPEN_BRACKET = 91;\nconst BACKSLASH = 92;\nconst CLOSE_BRACKET = 93;\nconst LF = 10;\nconst CR = 13;\n\n/** CommonMark: a link label holds at most 999 characters. */\nconst MAX_LABEL = 999;\n\nconst DEFINITION = /^ {0,3}\\[(?!\\^)([^\\]]+)\\]:[ \\t]*(<[^<>]*>|\\S+)/;\n/** What may follow a definition's destination: nothing, or a title after whitespace. */\nconst TITLE_ONLY = /^(?:[ \\t]+(?:\"[^\"]*\"|'[^']*'|\\([^)]*\\)))?[ \\t]*$/;\nconst AUTOLINK = /<((?:https?|ftp|mailto):[^<>\\s]+)>/g;\n\ninterface Definition {\n readonly target: string;\n readonly targetStart: number;\n readonly targetEnd: number;\n}\n\nexport function findLinks(layout: Layout): Link[] {\n const definitions = new Map<string, Definition>();\n const defined = readDefinitions(layout, definitions);\n const bracketed = readBrackets(layout, definitions, new Set(defined.map((d) => d.line)));\n // `<https://x>` as a link's destination or text is part of that link.\n const taken = mergeRanges([...defined, ...bracketed]);\n const autolinks = readAutolinks(layout).filter((link) => !inRanges(taken, link.start));\n return [...defined, ...bracketed, ...autolinks].sort((a, b) => a.start - b.start);\n}\n\n/**\n * How labels compare: trimmed, whitespace collapsed, and case folded as\n * CommonMark's reference implementations fold it, down and then up, so that\n * `ẞ` and `SS` are one label.\n */\nfunction normalizeLabel(label: string): string {\n return label.trim().replace(/\\s+/g, ' ').toLowerCase().toUpperCase();\n}\n\n/**\n * Definitions come first: the reference forms are read through them, and a\n * definition is conventionally written at the foot of the file, after the\n * links that use it. The first definition of a label wins.\n *\n * `[Note]: this matters` is prose that looks like one, so a definition has\n * nothing after its destination but a title. `[^1]: text` is a footnote.\n */\nfunction readDefinitions(layout: Layout, definitions: Map<string, Definition>): Link[] {\n const { text, structure } = layout;\n const out: Link[] = [];\n for (const line of layout.lines) {\n if (!isMarkdown(line) || !visibleLead(layout, line)) continue;\n const masked = structure.slice(line.contentStart, line.end);\n const match = DEFINITION.exec(masked);\n if (match === null || !TITLE_ONLY.test(masked.slice(match[0].length))) continue;\n const start = line.contentStart + match[0].indexOf('[');\n const label = text.slice(start + 1, start + 1 + (match[1] as string).length).trim();\n if (label.length === 0) continue;\n const written = match[2] as string;\n const end = line.contentStart + match[0].length;\n const angle = written.charCodeAt(0) === LESS_THAN ? 1 : 0;\n const targetStart = end - written.length + angle;\n const targetEnd = end - angle;\n const target = text.slice(targetStart, targetEnd);\n const key = normalizeLabel(label);\n if (!definitions.has(key)) definitions.set(key, { target, targetStart, targetEnd });\n out.push({ form: 'definition', image: false, text: label, target, label, start, end, targetStart, targetEnd, line: line.line });\n }\n return out;\n}\n\nfunction readAutolinks(layout: Layout): Link[] {\n const out: Link[] = [];\n for (const match of layout.structure.matchAll(AUTOLINK)) {\n const start = match.index;\n const end = start + match[0].length;\n out.push({\n form: 'autolink',\n image: false,\n text: '',\n target: match[1] as string,\n label: null,\n start,\n end,\n targetStart: start + 1,\n targetEnd: end - 1,\n line: layout.index.positionAt(start).line,\n });\n }\n return out;\n}\n\n/** The brackets of a paragraph, `[` paired with `]` as a stack pairs them, escaped ones skipped. */\ninterface Brackets {\n /** Each `[` a `]` closes, to that `]`, in the order of the `]`s: every pair after the pairs inside it. */\n readonly pairs: Map<number, number>;\n /** Each paired `[` to the `[` still open around it, where there is one. */\n readonly outer: Map<number, number>;\n /** Each paired `[` to how many pairs had closed when it opened: the pairs wholly before it. */\n readonly before: Map<number, number>;\n /** Every `[` written after an unescaped `!`: an image's. */\n readonly images: Set<number>;\n}\n\nfunction pairBrackets(structure: string, from: number, to: number): Brackets {\n const brackets: Brackets = { pairs: new Map(), outer: new Map(), before: new Map(), images: new Set() };\n const { pairs } = brackets;\n const open: { readonly at: number; readonly before: number }[] = [];\n let escaped = -1;\n for (let at = from; at < to; at += 1) {\n const ch = structure.charCodeAt(at);\n if (ch === BACKSLASH) {\n escaped = at + 1;\n at += 1;\n } else if (ch === OPEN_BRACKET) {\n open.push({ at, before: pairs.size });\n if (structure.charCodeAt(at - 1) === BANG && escaped !== at - 1) brackets.images.add(at);\n } else if (ch === CLOSE_BRACKET) {\n // A `]` with nothing to close pairs with nothing; recorded under\n // `undefined` it would not be found either, so this test changes no\n // answer, only what the maps hold.\n const opened = open.pop();\n if (opened !== undefined) {\n pairs.set(opened.at, at);\n brackets.before.set(opened.at, opened.before);\n const around = open[open.length - 1];\n if (around !== undefined) brackets.outer.set(opened.at, around.at);\n }\n }\n }\n return brackets;\n}\n\n/**\n * For every offset of a paragraph, where what starts there ends, or the end\n * of the paragraph when nothing does: a bare destination at the next space or\n * control character, or at the first `)` its own parentheses leave unmatched;\n * a title at its next unescaped closing quote or parenthesis. Filled from the\n * right in one pass, so every lookup is a read.\n */\ninterface Ends {\n readonly space: Int32Array;\n readonly paren: Int32Array;\n readonly doubleQuote: Int32Array;\n readonly singleQuote: Int32Array;\n readonly closeParen: Int32Array;\n readonly openParen: Int32Array;\n}\n\nfunction endsOf(structure: string, from: number, to: number): Ends {\n const length = to - from;\n const escaped = new Uint8Array(length + 1);\n for (let x = 0; x < length; x += 1) {\n if (escaped[x] === 0 && structure.charCodeAt(from + x) === BACKSLASH) escaped[x + 1] = 1;\n }\n // Two past the last offset: a `(` whose `)` is the paragraph's last\n // character looks one further for the next unmatched `)`, and finds none.\n const make = (): Int32Array => new Int32Array(length + 2).fill(to);\n const ends: Ends = { space: make(), paren: make(), doubleQuote: make(), singleQuote: make(), closeParen: make(), openParen: make() };\n for (let x = length - 1; x >= 0; x -= 1) {\n const at = from + x;\n const ch = structure.charCodeAt(at);\n const plain = escaped[x] === 0;\n ends.space[x] = ch <= 32 || ch === 127 ? at : (ends.space[x + 1] as number);\n // From a `(`, the first unmatched `)` is the first one after the `)` that\n // closes it, which is the first unmatched `)` after the `(`.\n const unmatched = ends.paren[x + 1] as number;\n if (plain && ch === CLOSE_PAREN) ends.paren[x] = at;\n else if (plain && ch === OPEN_PAREN) ends.paren[x] = ends.paren[unmatched + 1 - from] as number;\n else ends.paren[x] = unmatched;\n ends.doubleQuote[x] = plain && ch === DOUBLE_QUOTE ? at : (ends.doubleQuote[x + 1] as number);\n ends.singleQuote[x] = plain && ch === SINGLE_QUOTE ? at : (ends.singleQuote[x + 1] as number);\n ends.closeParen[x] = plain && ch === CLOSE_PAREN ? at : (ends.closeParen[x + 1] as number);\n ends.openParen[x] = plain && ch === OPEN_PAREN ? at : (ends.openParen[x + 1] as number);\n }\n return ends;\n}\n\ninterface Destination {\n readonly targetStart: number;\n readonly targetEnd: number;\n /** Offset just past the closing `)`. */\n readonly end: number;\n}\n\n/**\n * The bracket forms, a paragraph at a time. A paragraph here is a run of\n * Markdown lines, none blank, each continuing the one above: a bracket never\n * pairs across a blank line, a heading, or the start of another block.\n */\nfunction readBrackets(layout: Layout, definitions: ReadonlyMap<string, Definition>, defined: ReadonlySet<number>): Link[] {\n const { lines, continues, structure, text } = layout;\n const out: Link[] = [];\n // The first `]]` at or after the last place one was looked for; the cursor\n // only moves forward, so each is found once.\n let doubleClose = -2;\n\n const lookup = (from: number, to: number): Definition | undefined =>\n to - from > MAX_LABEL ? undefined : definitions.get(normalizeLabel(text.slice(from, to)));\n\n // A blank or code line let into a paragraph would bring only characters the\n // structure mask blanks, so this test shapes the runs and changes no link.\n const inParagraph = (i: number): boolean => {\n const line = lines[i];\n return line !== undefined && isMarkdown(line) && !line.blank;\n };\n\n for (let first = 0; first < lines.length; first += 1) {\n if (!inParagraph(first)) continue;\n let last = first;\n while (inParagraph(last + 1) && continues.has(last + 2)) last += 1;\n const from = (lines[first] as ScannedLine).start;\n const to = (lines[last] as ScannedLine).end;\n const brackets = pairBrackets(structure, from, to);\n const { pairs } = brackets;\n // Each `[` with a link inside it, at any depth.\n const holding = new Set<number>();\n let ends: Ends | null = null;\n\n // Spaces and tabs, and at most one line ending inside the paragraph. The\n // character at `to` ends the paragraph's last line and is none of these.\n const skipSpace = (start: number): number => {\n let at = start;\n while (isSpaceOrTab(structure, at)) at += 1;\n if (at < to) {\n if (structure.charCodeAt(at) === CR) at += 1;\n if (structure.charCodeAt(at) === LF) at += 1;\n while (isSpaceOrTab(structure, at)) at += 1;\n }\n return at;\n };\n\n const destination = (open: number): Destination | null => {\n const at = skipSpace(open);\n let targetStart: number;\n let targetEnd: number;\n let after: number;\n if (structure.charCodeAt(at) === LESS_THAN) {\n // `<dest>`: no line ending and no unescaped `<` inside.\n let close = at + 1;\n for (;;) {\n if (close >= to) return null;\n const ch = structure.charCodeAt(close);\n if (ch === GREATER_THAN) break;\n if (ch === LESS_THAN || ch === LF || ch === CR) return null;\n close += ch === BACKSLASH ? 2 : 1;\n }\n targetStart = at + 1;\n targetEnd = close;\n after = close + 1;\n } else {\n ends ??= endsOf(structure, from, to);\n const space = ends.space[at - from] as number;\n const paren = ends.paren[at - from] as number;\n targetStart = at;\n // The two are equal only when neither is found, at `to`.\n targetEnd = paren < space ? paren : space;\n after = targetEnd;\n // An empty destination points nowhere a reader can follow.\n if (targetEnd === at) return null;\n }\n let k = skipSpace(after);\n if (structure.charCodeAt(k) === CLOSE_PAREN) return { targetStart, targetEnd, end: k + 1 };\n // A title is separated from the destination by whitespace, and quoted.\n if (k === after) return null;\n ends ??= endsOf(structure, from, to);\n const x = k + 1 - from;\n const quote = structure.charCodeAt(k);\n let close: number;\n if (quote === DOUBLE_QUOTE) close = ends.doubleQuote[x] as number;\n else if (quote === SINGLE_QUOTE) close = ends.singleQuote[x] as number;\n // A title in parentheses may not hold an unescaped `(`.\n else if (quote === OPEN_PAREN) close = (ends.openParen[x] as number) < (ends.closeParen[x] as number) ? to : (ends.closeParen[x] as number);\n else return null;\n // Equal ends are `to`, where the title fails either way. Past `to` the\n // next line opens a block of its own, and none opens with `)`.\n if (close === to) return null;\n k = skipSpace(close + 1);\n return structure.charCodeAt(k) === CLOSE_PAREN ? { targetStart, targetEnd, end: k + 1 } : null;\n };\n\n const wiki = (at: number, start: number, image: boolean, line: ScannedLine): Link | null => {\n if (structure.charCodeAt(at + 1) !== OPEN_BRACKET) return null;\n if (doubleClose !== -1 && doubleClose < at + 2) doubleClose = structure.indexOf(']]', at + 2);\n const close = doubleClose;\n if (close < 0 || close + 2 > line.end) return null;\n const inner = text.slice(at + 2, close);\n const written = inner.trim();\n const pipe = written.indexOf('|');\n const target = (pipe < 0 ? written : written.slice(0, pipe)).trim();\n // `[[ ]]` and `[[|text]]` name nothing to link to.\n if (target.length === 0) return null;\n const targetStart = at + 2 + inner.length - inner.trimStart().length;\n return {\n form: 'wiki',\n image,\n text: written,\n target,\n label: null,\n start,\n end: close + 2,\n targetStart,\n targetEnd: targetStart + target.length,\n line: line.line,\n };\n };\n\n const bracket = (at: number, start: number, image: boolean, line: ScannedLine): Link | null => {\n const close = pairs.get(at);\n // A link holding a link is text; an image holding one is still an image.\n if (close === undefined || (!image && holding.has(at))) return null;\n const label = (): string => text.slice(at + 1, close).trim();\n if (structure.charCodeAt(close + 1) === OPEN_PAREN) {\n const dest = destination(close + 2);\n if (dest !== null) {\n const target = text.slice(dest.targetStart, dest.targetEnd);\n return { form: 'inline', image, text: label(), target, label: null, start, line: line.line, ...dest };\n }\n } else {\n // Only a `[` is paired, so a second label follows exactly when this finds one.\n const refClose = pairs.get(close + 1);\n if (refClose !== undefined) {\n // `[text][]` is read through its text; `[text][label]` through its label.\n const collapsed = refClose - close - 2 <= MAX_LABEL && text.slice(close + 2, refClose).trim() === '';\n const found = collapsed ? lookup(at + 1, close) : lookup(close + 2, refClose);\n if (found === undefined) return null;\n const written = collapsed ? label() : text.slice(close + 2, refClose).trim();\n return { form: 'reference', image, text: label(), label: written, start, end: refClose + 1, line: line.line, ...found };\n }\n }\n // `[text](not a destination)` is a shortcut followed by text, as CommonMark reads it.\n const found = lookup(at + 1, close);\n if (found === undefined) return null;\n return { form: 'shortcut', image, text: label(), label: label(), start, end: close + 1, line: line.line, ...found };\n };\n\n const lineAt = (at: number): ScannedLine => lines[layout.index.positionAt(at).line - 1] as ScannedLine;\n\n // CommonMark reads each pair at its `]`, so the pairs inside a `[` are\n // read before it, and a link among them makes it text, and every `[`\n // open around it: the pairs come innermost first, and fill `holding` on\n // the way out. An image among them does not; a link may hold one. What a\n // link or an image reads past its `]` - a destination, a title, a second\n // label - is not read for links again: `reach` is the furthest any of the\n // first so many pairs read to, and a `[` short of it opens nothing.\n const reach = [from];\n for (const at of pairs.keys()) {\n const line = lineAt(at);\n const image = brackets.images.has(at);\n const passed = (reach[brackets.before.get(at) as number] as number) > at;\n const link = passed || defined.has(line.line) ? null : bracket(at, at, image, line);\n reach.push(Math.max(reach[reach.length - 1] as number, link === null ? from : link.end));\n const around = brackets.outer.get(at);\n if (around !== undefined && (holding.has(at) || (link !== null && !image))) holding.add(around);\n }\n\n let at = from;\n // Inside a link's text, up to its `]`, where CommonMark reads an image -\n // a badge wrapped in a link - but no other link; then on past the link.\n // `textEnd` is -1 or a `]` that closes a `[`, so never 0, and the `]` is\n // read as no link. Leaving one step later, past it, resumes at the same\n // place, or ends the paragraph where a shortcut link ended it anyway: the\n // test below reads the same with `textEnd > 0` or `at > textEnd`.\n let textEnd = -1;\n let resume = -1;\n while (at < to) {\n if (textEnd >= 0 && at >= textEnd) {\n at = resume;\n textEnd = -1;\n continue;\n }\n const ch = structure.charCodeAt(at);\n if (ch === BACKSLASH) {\n at += 2;\n continue;\n }\n if (ch !== OPEN_BRACKET) {\n at += 1;\n continue;\n }\n const line = lineAt(at);\n // A definition's line holds its label, its destination and its title,\n // and none of them is a link.\n if (defined.has(line.line)) {\n at = line.end;\n continue;\n }\n const image = brackets.images.has(at);\n const start = image ? at - 1 : at;\n const link = wiki(at, start, image, line) ?? bracket(at, start, image, line);\n if (textEnd >= 0) {\n // An image that closes inside the text; its own text is alt text, and\n // holds nothing a reader follows.\n if (link !== null && link.image && link.form !== 'wiki' && link.end <= textEnd) {\n out.push(link);\n at = link.end;\n } else {\n at += 1;\n }\n } else if (link === null) {\n at += 1;\n } else {\n out.push(link);\n if (!link.image && link.form !== 'wiki') {\n textEnd = pairs.get(at) as number;\n resume = link.end;\n at += 1;\n } else {\n at = link.end;\n }\n }\n }\n first = last;\n }\n return out;\n}\n"]}
|
|
@@ -30,7 +30,7 @@ import { frontMatterCloses, frontMatterKind } from './frontmatter.js';
|
|
|
30
30
|
import { findAtxHeadings, findHeadings } from './headings.js';
|
|
31
31
|
import { findLinks } from './links.js';
|
|
32
32
|
import { findListItems } from './lists.js';
|
|
33
|
-
import { atxLevel, fenceCloses, fenceOpen, hasRawTextClose, isRawTextOpen, isThematicBreak, leadIndex, listMarker, measureIndent, opensComment, setextUnderline, stripQuotes, } from './syntax.js';
|
|
33
|
+
import { atxLevel, fenceCloses, fenceOpen, hasRawTextClose, isRawTextOpen, isThematicBreak, leadIndex, listMarker, measureIndent, opensComment, rawTextTag, setextUnderline, stripQuotes, } from './syntax.js';
|
|
34
34
|
import { findTables } from './tables.js';
|
|
35
35
|
const BACKTICK = 0x60;
|
|
36
36
|
const BACKSLASH = 0x5c;
|
|
@@ -38,7 +38,7 @@ const BACKSLASH = 0x5c;
|
|
|
38
38
|
export function scanMarkdown(source) {
|
|
39
39
|
const text = stripBom(source);
|
|
40
40
|
const index = createLineIndex(text);
|
|
41
|
-
const frontMatter = readFrontMatterBlock(text, index);
|
|
41
|
+
const { frontMatter, unclosedFrontMatter } = readFrontMatterBlock(text, index);
|
|
42
42
|
const bodyStart = frontMatter === null ? 0 : frontMatter.bodyStart;
|
|
43
43
|
const core = scanCore(text, index, frontMatter === null ? 0 : frontMatter.closeLine);
|
|
44
44
|
// Without front matter this range is empty, and merging drops it.
|
|
@@ -85,6 +85,7 @@ export function scanMarkdown(source) {
|
|
|
85
85
|
index,
|
|
86
86
|
lines: core.lines,
|
|
87
87
|
frontMatter,
|
|
88
|
+
unclosedFrontMatter,
|
|
88
89
|
bodyStart,
|
|
89
90
|
blocks: core.blocks,
|
|
90
91
|
codeSpans: core.spans,
|
|
@@ -109,24 +110,26 @@ export function scanMarkdown(source) {
|
|
|
109
110
|
export function linesOf(scan, view = 'text') {
|
|
110
111
|
return splitLines(view === 'text' ? scan.text : scan.masks[view]);
|
|
111
112
|
}
|
|
113
|
+
const NO_FRONT = { frontMatter: null, unclosedFrontMatter: null };
|
|
112
114
|
/**
|
|
113
115
|
* YAML between `---` lines, closed by `---` or `...`, or TOML between `+++`
|
|
114
116
|
* lines. The opening line is the document's first, exactly. An opening line
|
|
115
|
-
* that is never closed opens nothing: it is a thematic break
|
|
117
|
+
* that is never closed opens nothing: it is a thematic break, and is reported
|
|
118
|
+
* as unclosed front matter.
|
|
116
119
|
*/
|
|
117
120
|
function readFrontMatterBlock(text, index) {
|
|
118
121
|
const kind = frontMatterKind(index.lineText(1));
|
|
119
122
|
if (kind === null)
|
|
120
|
-
return
|
|
123
|
+
return NO_FRONT;
|
|
121
124
|
for (let line = 2; line <= index.lineCount; line += 1) {
|
|
122
125
|
if (!frontMatterCloses(index.lineText(line), kind))
|
|
123
126
|
continue;
|
|
124
127
|
const start = index.lineStart(2);
|
|
125
128
|
const end = index.lineStart(line);
|
|
126
129
|
const bodyStart = line < index.lineCount ? index.lineStart(line + 1) : text.length;
|
|
127
|
-
return { kind, raw: text.slice(start, end), start, end, bodyStart, closeLine: line };
|
|
130
|
+
return { frontMatter: { kind, raw: text.slice(start, end), start, end, bodyStart, closeLine: line }, unclosedFrontMatter: null };
|
|
128
131
|
}
|
|
129
|
-
return null;
|
|
132
|
+
return { frontMatter: null, unclosedFrontMatter: { kind, line: 1, start: 0, end: index.lineEnd(1) } };
|
|
130
133
|
}
|
|
131
134
|
/** `make`, run the first time its value is asked for; the same value after. */
|
|
132
135
|
function once(make) {
|
|
@@ -208,6 +211,9 @@ function scanCore(text, index, frontLines) {
|
|
|
208
211
|
return undefined;
|
|
209
212
|
const stop = stops.get(line);
|
|
210
213
|
const last = new Map();
|
|
214
|
+
// A run ends at `from`, so `from` is past 0 and holds no backtick. A
|
|
215
|
+
// search that stopped at `from` itself would record a run of length
|
|
216
|
+
// zero, which no opener asks for, and `at > 0` tests what `at >= 0` does.
|
|
211
217
|
let at = text.indexOf('`', from);
|
|
212
218
|
while (at >= 0 && at < stop) {
|
|
213
219
|
const run = at;
|
|
@@ -301,10 +307,12 @@ function scanCore(text, index, frontLines) {
|
|
|
301
307
|
let indented = null;
|
|
302
308
|
let previousBlank = true;
|
|
303
309
|
// The content column of each list item open around the line, innermost last.
|
|
310
|
+
// Each loop that pops it tests its length first, which says what is meant;
|
|
311
|
+
// without the test it stops all the same, `undefined > indent` being false.
|
|
304
312
|
const items = [];
|
|
305
313
|
let pos = 0;
|
|
306
|
-
const openBlock = (kind, i, info) => {
|
|
307
|
-
const block = { kind, start: index.lineStart(i + 1), end: index.lineEnd(i + 1), line: i + 1, endLine: i + 1, info, closed: kind === 'indented' };
|
|
314
|
+
const openBlock = (kind, i, info, tag) => {
|
|
315
|
+
const block = { kind, start: index.lineStart(i + 1), end: index.lineEnd(i + 1), line: i + 1, endLine: i + 1, info, tag, closed: kind === 'indented' };
|
|
308
316
|
blocks.push(block);
|
|
309
317
|
return block;
|
|
310
318
|
};
|
|
@@ -364,7 +372,7 @@ function scanCore(text, index, frontLines) {
|
|
|
364
372
|
const deep = shape.indent >= margin + 4;
|
|
365
373
|
if (!shape.blank && deep && (previousBlank || indented !== null)) {
|
|
366
374
|
if (indented === null)
|
|
367
|
-
indented = openBlock('indented', i, '');
|
|
375
|
+
indented = openBlock('indented', i, '', null);
|
|
368
376
|
else
|
|
369
377
|
extend(indented, i);
|
|
370
378
|
push(CODE);
|
|
@@ -381,12 +389,13 @@ function scanCore(text, index, frontLines) {
|
|
|
381
389
|
// A fence as deep as indented code continues a paragraph instead.
|
|
382
390
|
const open = deep ? null : fenceOpen(content);
|
|
383
391
|
if (open !== null) {
|
|
384
|
-
fence = { block: openBlock('fenced', i, open.info), depth: shape.depth, open };
|
|
392
|
+
fence = { block: openBlock('fenced', i, open.info, null), depth: shape.depth, open };
|
|
385
393
|
push(CODE);
|
|
386
394
|
return;
|
|
387
395
|
}
|
|
388
|
-
|
|
389
|
-
|
|
396
|
+
const tag = rawTextTag(content);
|
|
397
|
+
if (tag !== null) {
|
|
398
|
+
const block = openBlock('html', i, '', tag);
|
|
390
399
|
push(HTML);
|
|
391
400
|
if (hasRawTextClose(content))
|
|
392
401
|
block.closed = true;
|
|
@@ -422,7 +431,8 @@ function scanCore(text, index, frontLines) {
|
|
|
422
431
|
/**
|
|
423
432
|
* The column an item's text starts at: past its marker and the one to four
|
|
424
433
|
* spaces after it. With none, or five or more, the text starts one column
|
|
425
|
-
* past the marker, and anything further is indented code.
|
|
434
|
+
* past the marker, and anything further is indented code. At one space both
|
|
435
|
+
* arms give one, so `spaces > 1` would read the same as `spaces >= 1`.
|
|
426
436
|
*/
|
|
427
437
|
function itemColumn(indent, marker) {
|
|
428
438
|
const spaces = marker.width - marker.marker.length;
|