@agentshouse/mdmodel 0.1.0-alpha.9 → 0.1.0-c83456e1cebfb
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/API.md +298 -0
- package/README.md +29 -186
- package/dist/blocks.d.ts +11 -0
- package/dist/blocks.d.ts.map +1 -0
- package/dist/blocks.js +62 -0
- package/dist/definition.d.ts +7 -3
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +143 -134
- package/dist/divide.d.ts +3 -0
- package/dist/divide.d.ts.map +1 -0
- package/dist/divide.js +310 -0
- package/dist/document.d.ts +2 -0
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +89 -120
- package/dist/fields.d.ts +4 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +3 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/links.d.ts +1 -0
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +618 -224
- package/dist/paths.d.ts +2 -3
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +27 -37
- package/dist/profile.js +1 -3
- package/dist/project.d.ts +19 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +75 -91
- package/dist/refuse.d.ts.map +1 -1
- package/dist/refuse.js +2 -10
- package/dist/schema.d.ts +2 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +22 -33
- package/dist/sections.d.ts +2 -1
- package/dist/sections.d.ts.map +1 -1
- package/dist/sections.js +44 -66
- package/dist/types.d.ts +30 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -3
- package/dist/validate.d.ts +3 -2
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +145 -127
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -3
- package/dist/yaml.d.ts +1 -0
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +195 -186
- package/fixtures/README.md +77 -53
- package/fixtures/cases/binary-any-reference/expected.json +0 -1
- package/fixtures/cases/binary-any-reference/schema.yaml +4 -0
- package/fixtures/cases/binary-document-collision/expected.json +1 -2
- package/fixtures/cases/binary-document-collision/schema.yaml +2 -0
- package/fixtures/cases/binary-link-outside-collection/expected.json +1 -2
- package/fixtures/cases/binary-link-outside-collection/schema.yaml +2 -0
- package/fixtures/cases/binary-prototype-reference/expected.json +0 -1
- package/fixtures/cases/binary-prototype-reference/schema.yaml +4 -0
- package/fixtures/cases/binary-typed-reference/expected.json +0 -1
- package/fixtures/cases/binary-typed-reference/schema.yaml +5 -0
- package/fixtures/cases/bracketed-link-definition/schema.yaml +6 -0
- package/fixtures/cases/declared-binary-links/schema.yaml +2 -0
- package/fixtures/cases/duplicate-link-definition/schema.yaml +6 -0
- package/fixtures/cases/fenced-link-definition/schema.yaml +6 -0
- package/fixtures/cases/field-enum/expected.json +1 -2
- package/fixtures/cases/field-enum/schema.yaml +7 -0
- package/fixtures/cases/frontmatter-schema/expected.json +5 -0
- package/fixtures/cases/frontmatter-schema/schema.yaml +6 -0
- package/fixtures/cases/interrupted-link-definition/schema.yaml +2 -0
- package/fixtures/cases/long-fence-link-definition/schema.yaml +2 -0
- package/fixtures/cases/malformed-definition/expected.json +2 -4
- package/fixtures/cases/malformed-definition/schema.yaml +4 -0
- package/fixtures/cases/member-document/context.json +1 -0
- package/fixtures/cases/member-document/library/people/ana.md +5 -0
- package/fixtures/cases/member-document/schema.yaml +5 -0
- package/fixtures/cases/missing-binary-image/expected.json +1 -2
- package/fixtures/cases/missing-binary-image/schema.yaml +2 -0
- package/fixtures/cases/missing-binary-link/expected.json +1 -2
- package/fixtures/cases/missing-binary-link/schema.yaml +2 -0
- package/fixtures/cases/missing-required-field/expected.json +1 -2
- package/fixtures/cases/missing-required-field/schema.yaml +7 -0
- package/fixtures/cases/missing-section-item-kind/expected.json +2 -4
- package/fixtures/cases/missing-section-item-kind/schema.yaml +6 -0
- package/fixtures/cases/paragraph-link-definition/schema.yaml +2 -0
- package/fixtures/cases/prototype-field/expected.json +1 -2
- package/fixtures/cases/prototype-field/schema.yaml +6 -0
- package/fixtures/cases/quoted-link-definition/expected.json +1 -2
- package/fixtures/cases/quoted-link-definition/schema.yaml +2 -0
- package/fixtures/cases/referenced-missing-file/expected.json +0 -1
- package/fixtures/cases/referenced-missing-file/schema.yaml +10 -0
- package/fixtures/cases/second-member-document/context.json +1 -0
- package/fixtures/cases/second-member-document/expected.json +5 -0
- package/fixtures/cases/second-member-document/schema.yaml +5 -0
- package/fixtures/cases/section-item-enum/context.json +1 -0
- package/fixtures/cases/section-item-enum/expected.json +6 -0
- package/fixtures/cases/section-item-enum/library/task.md +8 -0
- package/fixtures/cases/section-item-enum/schema.yaml +4 -0
- package/fixtures/cases/section-item-kind/context.json +1 -0
- package/fixtures/cases/section-item-kind/expected.json +6 -0
- package/fixtures/cases/section-item-kind/library/task.md +8 -0
- package/fixtures/cases/section-item-kind/schema.yaml +4 -0
- package/fixtures/cases/section-items/context.json +1 -0
- package/fixtures/cases/section-items/expected.json +1 -0
- package/fixtures/cases/section-items/library/other.md +3 -0
- package/fixtures/cases/section-items/library/page.md +28 -0
- package/fixtures/cases/section-items/schema.yaml +8 -0
- package/fixtures/cases/section-reference-path/context.json +1 -0
- package/fixtures/cases/section-reference-path/expected.json +6 -0
- package/fixtures/cases/section-reference-path/library/other.md +3 -0
- package/fixtures/cases/section-reference-path/library/page.md +7 -0
- package/fixtures/cases/section-reference-path/schema.yaml +4 -0
- package/fixtures/cases/section-reference-type/context.json +1 -0
- package/fixtures/cases/section-reference-type/expected.json +6 -0
- package/fixtures/cases/section-reference-type/library/note.md +1 -0
- package/fixtures/cases/section-reference-type/library/page.md +7 -0
- package/fixtures/cases/section-reference-type/schema.yaml +4 -0
- package/fixtures/cases/shortcut-reference-link/context.json +1 -0
- package/fixtures/cases/shortcut-reference-link/expected.json +5 -0
- package/fixtures/cases/shortcut-reference-link/library/item.md +10 -0
- package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -0
- package/fixtures/cases/structured-section/expected.json +1 -2
- package/fixtures/cases/structured-section/schema.yaml +7 -0
- package/fixtures/cases/submission-keys/context.json +1 -0
- package/fixtures/cases/submission-keys/expected.json +1 -0
- package/fixtures/cases/submission-keys/library/notes/visitor.md +8 -0
- package/fixtures/cases/submission-keys/schema.yaml +4 -0
- package/fixtures/cases/text-field-kind/context.json +1 -0
- package/fixtures/cases/text-field-kind/expected.json +6 -0
- package/fixtures/cases/text-field-kind/library/page.md +4 -0
- package/fixtures/cases/text-field-kind/schema.yaml +4 -0
- package/fixtures/cases/truncated-link-definition/expected.json +1 -2
- package/fixtures/cases/truncated-link-definition/schema.yaml +2 -0
- package/fixtures/cases/types-folder-content/context.json +1 -0
- package/fixtures/cases/types-folder-content/expected.json +1 -0
- package/fixtures/cases/types-folder-content/library/types/task.md +4 -0
- package/fixtures/cases/types-folder-content/schema.yaml +4 -0
- package/fixtures/cases/unclosed-frontmatter/expected.json +1 -2
- package/fixtures/cases/undeclared-field/expected.json +1 -2
- package/fixtures/cases/undeclared-field/schema.yaml +6 -0
- package/fixtures/cases/unknown-type/context.json +1 -0
- package/fixtures/cases/unknown-type/expected.json +6 -0
- package/fixtures/cases/unknown-type/library/item.md +3 -0
- package/fixtures/cases/unknown-type/schema.yaml +4 -0
- package/fixtures/cases/unlisted-reference-type/context.json +1 -0
- package/fixtures/cases/unlisted-reference-type/expected.json +5 -0
- package/fixtures/cases/unlisted-reference-type/schema.yaml +4 -0
- package/fixtures/cases/unresolved-link/expected.json +1 -2
- package/fixtures/cases/unresolved-link/schema.yaml +6 -0
- package/fixtures/cases/valid-typed-document/schema.yaml +15 -0
- package/fixtures/cases/wide-item-fence-link/schema.yaml +2 -0
- package/fixtures/division.json +409 -0
- package/fixtures/projection.json +58 -21
- package/package.json +3 -12
- package/dist/definition.js.map +0 -1
- package/dist/document.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/links.js.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/profile.js.map +0 -1
- package/dist/project.js.map +0 -1
- package/dist/refuse.js.map +0 -1
- package/dist/schema.js.map +0 -1
- package/dist/sections.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/validate.js.map +0 -1
- package/dist/version.js.map +0 -1
- package/dist/yaml.js.map +0 -1
- package/fixtures/cases/binary-any-reference/library/types/note.md +0 -5
- package/fixtures/cases/binary-document-collision/library/types/note.md +0 -3
- package/fixtures/cases/binary-link-outside-collection/library/types/note.md +0 -3
- package/fixtures/cases/binary-prototype-reference/library/types/note.md +0 -5
- package/fixtures/cases/binary-typed-reference/library/types/note.md +0 -5
- package/fixtures/cases/binary-typed-reference/library/types/person.md +0 -3
- package/fixtures/cases/bracketed-link-definition/library/types/task.md +0 -7
- package/fixtures/cases/declared-binary-links/library/types/note.md +0 -3
- package/fixtures/cases/duplicate-link-definition/library/types/task.md +0 -7
- package/fixtures/cases/fenced-link-definition/library/types/task.md +0 -7
- package/fixtures/cases/field-enum/library/types/task.md +0 -8
- package/fixtures/cases/interrupted-link-definition/library/types/note.md +0 -3
- package/fixtures/cases/long-fence-link-definition/library/types/note.md +0 -3
- package/fixtures/cases/malformed-definition/library/types/task.md +0 -5
- package/fixtures/cases/missing-binary-image/library/types/note.md +0 -3
- package/fixtures/cases/missing-binary-link/library/types/note.md +0 -3
- package/fixtures/cases/missing-required-field/library/types/task.md +0 -8
- package/fixtures/cases/missing-section-item-kind/library/types/task.md +0 -7
- package/fixtures/cases/paragraph-link-definition/library/types/note.md +0 -3
- package/fixtures/cases/prd-definition/library/types/task.md +0 -16
- package/fixtures/cases/prototype-field/library/types/task.md +0 -7
- package/fixtures/cases/quoted-link-definition/library/types/note.md +0 -3
- package/fixtures/cases/referenced-missing-file/library/types/person.md +0 -5
- package/fixtures/cases/referenced-missing-file/library/types/task.md +0 -8
- package/fixtures/cases/structured-section/library/types/task.md +0 -8
- package/fixtures/cases/truncated-link-definition/library/types/note.md +0 -3
- package/fixtures/cases/undeclared-field/library/types/task.md +0 -7
- package/fixtures/cases/unresolved-link/library/types/task.md +0 -7
- package/fixtures/cases/valid-typed-document/library/types/person.md +0 -5
- package/fixtures/cases/valid-typed-document/library/types/task.md +0 -13
- package/fixtures/cases/wide-item-fence-link/library/types/note.md +0 -3
- package/markdown-syntax-profile.md +0 -9
- /package/fixtures/cases/{prd-definition → frontmatter-schema}/context.json +0 -0
- /package/fixtures/cases/{prd-definition → member-document}/expected.json +0 -0
package/dist/links.js
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
const TAB_STOP = 4;
|
|
2
2
|
const CLOSING_FENCE_INDENT = 3;
|
|
3
|
+
const CODE_INDENT = 4;
|
|
3
4
|
const HEADING = /^#{1,6}(?:[ \t]|$)/;
|
|
4
5
|
const BREAK = /^(?:(?:\*[ \t]*){3,}|(?:-[ \t]*){3,}|(?:_[ \t]*){3,})$/;
|
|
5
6
|
const SETEXT = /^(?:=+|-+)[ \t]*$/;
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const BLANK = /^[ \t\v\f]*\r?$/;
|
|
8
|
+
const HTML_CLOSED = [
|
|
9
|
+
[/^<(?:script|pre|style)(?:[ \t\v\f>]|$)/i, /<\/(?:script|pre|style)>/i],
|
|
10
|
+
[/^<!--/, /-->/],
|
|
11
|
+
[/^<\?/, /\?>/],
|
|
12
|
+
[/^<![A-Z]/, />/],
|
|
13
|
+
[/^<!\[CDATA\[/, /\]\]>/],
|
|
14
|
+
];
|
|
15
|
+
const HTML_BLOCK_TAG = /^<\/?(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)(?:[ \t\v\f>]|\/>|$)/i;
|
|
16
|
+
const HTML_TAG_LINE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\v\f]+[A-Za-z_:][A-Za-z0-9_.:-]*(?:[ \t\v\f]*=[ \t\v\f]*(?:[^ \t\v\f\r\n"'=<>`]+|'[^']*'|"[^"]*"))?)*[ \t\v\f]*\/?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\v\f]*>)[ \t\v\f]*$/;
|
|
17
|
+
const ORDERED = /^(\d{1,9})[.)]/;
|
|
18
|
+
const LABEL_LENGTH = 999;
|
|
19
|
+
const PUNCTUATION = /^[!-/:-@[-`{-~]$/;
|
|
20
|
+
const INLINE_RAW = new RegExp([
|
|
21
|
+
'<[A-Za-z][A-Za-z0-9-]*(?:[ \\t\\n\\v\\f\\r]+[A-Za-z_:][A-Za-z0-9_.:-]*(?:[ \\t\\n\\v\\f\\r]*=[ \\t\\n\\v\\f\\r]*(?:[^ \\t\\n\\v\\f\\r"\'=<>`]+|\'[^\']*\'|"[^"]*"))?)*[ \\t\\n\\v\\f\\r]*\\/?>',
|
|
22
|
+
'<\\/[A-Za-z][A-Za-z0-9-]*[ \\t\\n\\v\\f\\r]*>',
|
|
23
|
+
'<!--(?!-?>)(?:-?[^-])*-->',
|
|
24
|
+
'<\\?[\\s\\S]*?\\?>',
|
|
25
|
+
'<![A-Z]+[ \\t\\n\\v\\f\\r]+[^>]*>',
|
|
26
|
+
'<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
|
|
27
|
+
'<[A-Za-z][A-Za-z0-9+.-]{1,31}:[^\\x00-\\x20<>]*>',
|
|
28
|
+
"<[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*>",
|
|
29
|
+
].join('|'), 'y');
|
|
30
|
+
const DELIMITER_ROW = /^\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
|
|
31
|
+
const GAP = /^[ \t\v\f]+/;
|
|
9
32
|
function endOfLine(text, from) {
|
|
10
33
|
const nl = text.indexOf('\n', from);
|
|
11
34
|
return nl === -1 ? text.length : nl;
|
|
@@ -16,16 +39,21 @@ function afterLine(text, end) {
|
|
|
16
39
|
function itemMarker(text, index, end) {
|
|
17
40
|
let i = index;
|
|
18
41
|
const bullet = text[i];
|
|
19
|
-
if (bullet === '-' || bullet === '*' || bullet === '+')
|
|
42
|
+
if (bullet === '-' || bullet === '*' || bullet === '+')
|
|
43
|
+
i += 1;
|
|
20
44
|
else {
|
|
21
45
|
let digits = 0;
|
|
22
|
-
while(digits < 9 && i + digits < end && text[i + digits] >= '0' && text[i + digits] <= '9')
|
|
46
|
+
while (digits < 9 && i + digits < end && text[i + digits] >= '0' && text[i + digits] <= '9')
|
|
47
|
+
digits += 1;
|
|
23
48
|
const delimiter = text[i + digits];
|
|
24
|
-
if (digits === 0 || delimiter !== '.' && delimiter !== ')')
|
|
49
|
+
if (digits === 0 || (delimiter !== '.' && delimiter !== ')'))
|
|
50
|
+
return null;
|
|
25
51
|
i += digits + 1;
|
|
26
52
|
}
|
|
27
|
-
if (i >= end)
|
|
28
|
-
|
|
53
|
+
if (i >= end)
|
|
54
|
+
return i;
|
|
55
|
+
if (text[i] !== ' ' && text[i] !== '\t')
|
|
56
|
+
return null;
|
|
29
57
|
return i + 1;
|
|
30
58
|
}
|
|
31
59
|
function readLine(text, start, end) {
|
|
@@ -33,41 +61,38 @@ function readLine(text, start, end) {
|
|
|
33
61
|
let depth = 0;
|
|
34
62
|
let item = false;
|
|
35
63
|
let inner = start;
|
|
36
|
-
for(;;){
|
|
64
|
+
for (;;) {
|
|
37
65
|
let spaces = 0;
|
|
38
|
-
while(spaces < 3 && i < end && text[i] === ' '){
|
|
66
|
+
while (spaces < 3 && i < end && text[i] === ' ') {
|
|
39
67
|
i += 1;
|
|
40
68
|
spaces += 1;
|
|
41
69
|
}
|
|
42
70
|
if (i < end && text[i] === '>') {
|
|
43
71
|
depth += 1;
|
|
44
72
|
i += 1;
|
|
45
|
-
if (i < end && text[i] === ' ')
|
|
73
|
+
if (i < end && text[i] === ' ')
|
|
74
|
+
i += 1;
|
|
46
75
|
inner = i;
|
|
47
76
|
continue;
|
|
48
77
|
}
|
|
49
78
|
const after = i < end ? itemMarker(text, i, end) : null;
|
|
50
|
-
if (after === null)
|
|
79
|
+
if (after === null)
|
|
80
|
+
break;
|
|
51
81
|
item = true;
|
|
52
82
|
i = after;
|
|
53
83
|
}
|
|
54
|
-
return {
|
|
55
|
-
start,
|
|
56
|
-
end,
|
|
57
|
-
content: i,
|
|
58
|
-
depth,
|
|
59
|
-
item,
|
|
60
|
-
inner
|
|
61
|
-
};
|
|
84
|
+
return { start, end, content: i, depth, item, inner };
|
|
62
85
|
}
|
|
63
86
|
function widthOf(text, from, to) {
|
|
64
87
|
let width = 0;
|
|
65
|
-
for(let i = from; i < to; i += 1)
|
|
88
|
+
for (let i = from; i < to; i += 1)
|
|
89
|
+
width += text[i] === '\t' ? TAB_STOP - (width % TAB_STOP) : 1;
|
|
66
90
|
return width;
|
|
67
91
|
}
|
|
68
92
|
function afterIndent(text, line) {
|
|
69
93
|
let i = line.inner;
|
|
70
|
-
while(i < line.end && (text[i] === ' ' || text[i] === '\t'))
|
|
94
|
+
while (i < line.end && (text[i] === ' ' || text[i] === '\t'))
|
|
95
|
+
i += 1;
|
|
71
96
|
return i;
|
|
72
97
|
}
|
|
73
98
|
function indentWidth(text, line) {
|
|
@@ -79,302 +104,671 @@ function lineText(text, line) {
|
|
|
79
104
|
}
|
|
80
105
|
function fenceRun(text, at, end) {
|
|
81
106
|
const char = text[at];
|
|
82
|
-
if (char !== '`' && char !== '~')
|
|
107
|
+
if (char !== '`' && char !== '~')
|
|
108
|
+
return null;
|
|
83
109
|
let length = 0;
|
|
84
|
-
while(at + length < end && text[at + length] === char)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
length
|
|
88
|
-
};
|
|
110
|
+
while (at + length < end && text[at + length] === char)
|
|
111
|
+
length += 1;
|
|
112
|
+
return length < 3 ? null : { char, length };
|
|
89
113
|
}
|
|
90
114
|
function fenceAt(text, line) {
|
|
91
115
|
const run = fenceRun(text, line.content, line.end);
|
|
92
|
-
if (run === null)
|
|
116
|
+
if (run === null)
|
|
117
|
+
return null;
|
|
93
118
|
return {
|
|
94
119
|
char: run.char,
|
|
95
120
|
length: run.length,
|
|
96
121
|
depth: line.depth,
|
|
97
122
|
column: line.item ? widthOf(text, line.inner, line.content) : 0,
|
|
98
|
-
item: line.item
|
|
123
|
+
item: line.item,
|
|
99
124
|
};
|
|
100
125
|
}
|
|
101
126
|
function closesFence(text, line, open) {
|
|
102
|
-
if (line.depth !== open.depth || line.item)
|
|
127
|
+
if (line.depth !== open.depth || line.item)
|
|
128
|
+
return false;
|
|
103
129
|
const indent = indentWidth(text, line);
|
|
104
|
-
if (indent < open.column || indent > open.column + CLOSING_FENCE_INDENT)
|
|
130
|
+
if (indent < open.column || indent > open.column + CLOSING_FENCE_INDENT)
|
|
131
|
+
return false;
|
|
105
132
|
const at = afterIndent(text, line);
|
|
106
133
|
const run = fenceRun(text, at, line.end);
|
|
107
|
-
if (run === null || run.char !== open.char || run.length < open.length)
|
|
134
|
+
if (run === null || run.char !== open.char || run.length < open.length)
|
|
135
|
+
return false;
|
|
108
136
|
return text.slice(at + run.length, line.end).trim() === '';
|
|
109
137
|
}
|
|
110
138
|
function leavesContainer(text, line, open) {
|
|
111
|
-
if (line.depth < open.depth)
|
|
112
|
-
|
|
139
|
+
if (line.depth < open.depth)
|
|
140
|
+
return true;
|
|
141
|
+
if (!open.item || lineText(text, line).trim() === '')
|
|
142
|
+
return false;
|
|
113
143
|
return indentWidth(text, line) < open.column;
|
|
114
144
|
}
|
|
115
145
|
function fenceSpan(text, line, open) {
|
|
116
146
|
let cursor = afterLine(text, line.end);
|
|
117
|
-
while(cursor < text.length){
|
|
147
|
+
while (cursor < text.length) {
|
|
118
148
|
const end = endOfLine(text, cursor);
|
|
119
149
|
const next = readLine(text, cursor, end);
|
|
120
|
-
if (leavesContainer(text, next, open))
|
|
121
|
-
|
|
150
|
+
if (leavesContainer(text, next, open))
|
|
151
|
+
return cursor;
|
|
152
|
+
if (closesFence(text, next, open))
|
|
153
|
+
return afterLine(text, end);
|
|
122
154
|
cursor = afterLine(text, end);
|
|
123
155
|
}
|
|
124
156
|
return text.length;
|
|
125
157
|
}
|
|
126
|
-
function skipInlineCode(text, index) {
|
|
158
|
+
function skipInlineCode(text, index, joins) {
|
|
127
159
|
let ticks = 0;
|
|
128
|
-
while(text[index + ticks] === '`')
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
160
|
+
while (text[index + ticks] === '`')
|
|
161
|
+
ticks += 1;
|
|
162
|
+
let i = index + ticks;
|
|
163
|
+
while (i < text.length) {
|
|
164
|
+
const ch = text[i];
|
|
165
|
+
if (ch === '`') {
|
|
166
|
+
let run = 0;
|
|
167
|
+
while (text[i + run] === '`')
|
|
168
|
+
run += 1;
|
|
169
|
+
if (run === ticks)
|
|
170
|
+
return i + run;
|
|
171
|
+
i += run;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (ch === '\r' && text[i + 1] !== '\n')
|
|
175
|
+
break;
|
|
176
|
+
if (ch === '\n' && !joins.has(i))
|
|
177
|
+
break;
|
|
178
|
+
i += 1;
|
|
179
|
+
}
|
|
180
|
+
return index + ticks;
|
|
132
181
|
}
|
|
133
182
|
function skipLinkSpace(text, start) {
|
|
134
183
|
let i = start;
|
|
135
|
-
while(text[i] === ' ' || text[i] === '\t')
|
|
184
|
+
while (text[i] === ' ' || text[i] === '\t')
|
|
185
|
+
i += 1;
|
|
136
186
|
return i;
|
|
137
187
|
}
|
|
138
|
-
function
|
|
139
|
-
|
|
140
|
-
if (
|
|
188
|
+
function skipInlineSpace(text, start, joins) {
|
|
189
|
+
let i = skipLinkSpace(text, start);
|
|
190
|
+
if (text[i] === '\r' && text[i + 1] === '\n')
|
|
191
|
+
i += 1;
|
|
192
|
+
if (text[i] !== '\n' || !joins.has(i))
|
|
193
|
+
return i;
|
|
194
|
+
return afterIndent(text, readLine(text, i + 1, endOfLine(text, i + 1)));
|
|
195
|
+
}
|
|
196
|
+
function closeEnd(text, start, open, joins) {
|
|
141
197
|
const close = open === '(' ? ')' : open;
|
|
142
|
-
let i = start
|
|
143
|
-
while(i < text.length){
|
|
198
|
+
let i = start;
|
|
199
|
+
while (i < text.length) {
|
|
144
200
|
const ch = text[i];
|
|
145
|
-
if (
|
|
146
|
-
|
|
201
|
+
if (escapes(text, i)) {
|
|
202
|
+
i += 2;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (ch === close)
|
|
206
|
+
return i + 1;
|
|
207
|
+
if (open === '(' && ch === '(')
|
|
208
|
+
return null;
|
|
209
|
+
if (ch === '\r' && text[i + 1] !== '\n')
|
|
210
|
+
return null;
|
|
211
|
+
if (ch === '\n' && !joins.has(i))
|
|
212
|
+
return null;
|
|
147
213
|
i += 1;
|
|
148
214
|
}
|
|
149
215
|
return null;
|
|
150
216
|
}
|
|
151
|
-
function
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
217
|
+
function skipTitle(text, start, joins) {
|
|
218
|
+
const open = text[start];
|
|
219
|
+
if (open !== '"' && open !== "'" && open !== '(')
|
|
220
|
+
return start;
|
|
221
|
+
return closeEnd(text, start + 1, open, joins);
|
|
222
|
+
}
|
|
223
|
+
function destinationAt(text, at, end) {
|
|
224
|
+
if (text[at] === '<') {
|
|
225
|
+
let close = at + 1;
|
|
226
|
+
while (close < end && text[close] !== '>') {
|
|
227
|
+
if (text[close] === '<')
|
|
228
|
+
return null;
|
|
229
|
+
close += escapes(text, close) ? 2 : 1;
|
|
230
|
+
}
|
|
231
|
+
if (close >= end)
|
|
232
|
+
return null;
|
|
233
|
+
return { href: text.slice(at + 1, close), start: at, end: close + 1, bracketed: true };
|
|
234
|
+
}
|
|
235
|
+
let i = at;
|
|
236
|
+
let depth = 0;
|
|
237
|
+
while (i < end) {
|
|
238
|
+
if (escapes(text, i)) {
|
|
239
|
+
i += 2;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const ch = text[i];
|
|
243
|
+
if (ch <= ' ' || ch === '\x7f')
|
|
244
|
+
break;
|
|
245
|
+
if (ch === '(')
|
|
246
|
+
depth += 1;
|
|
247
|
+
else if (ch === ')') {
|
|
248
|
+
if (depth === 0)
|
|
249
|
+
break;
|
|
250
|
+
depth -= 1;
|
|
251
|
+
}
|
|
252
|
+
i += 1;
|
|
253
|
+
}
|
|
254
|
+
if (depth !== 0)
|
|
255
|
+
return null;
|
|
256
|
+
return { href: text.slice(at, i), start: at, end: i, bracketed: false };
|
|
257
|
+
}
|
|
258
|
+
function destination(text, start, joins) {
|
|
259
|
+
let i = skipInlineSpace(text, start + 1, joins);
|
|
260
|
+
const occurrence = destinationAt(text, i, endOfLine(text, i));
|
|
261
|
+
if (occurrence === null)
|
|
262
|
+
return null;
|
|
263
|
+
i = occurrence.end;
|
|
264
|
+
const spaced = skipInlineSpace(text, i, joins);
|
|
265
|
+
if (spaced === i && text[i] !== ')')
|
|
266
|
+
return null;
|
|
267
|
+
i = spaced;
|
|
268
|
+
const afterTitle = skipTitle(text, i, joins);
|
|
269
|
+
if (afterTitle === null)
|
|
270
|
+
return null;
|
|
271
|
+
i = skipInlineSpace(text, afterTitle, joins);
|
|
272
|
+
if (text[i] !== ')')
|
|
273
|
+
return null;
|
|
274
|
+
return { occurrence, end: i + 1 };
|
|
275
|
+
}
|
|
276
|
+
function cellCount(row) {
|
|
277
|
+
return row
|
|
278
|
+
.trim()
|
|
279
|
+
.replace(/^\|/, '')
|
|
280
|
+
.replace(/(?<!\\)\|$/, '')
|
|
281
|
+
.split(/(?<!\\)\|/).length;
|
|
282
|
+
}
|
|
283
|
+
function headsTable(text, header, end) {
|
|
284
|
+
if (end >= text.length)
|
|
285
|
+
return false;
|
|
286
|
+
const row = lineText(text, readLine(text, end + 1, endOfLine(text, end + 1)));
|
|
287
|
+
return row.includes('|') && DELIMITER_ROW.test(row) && cellCount(row) === cellCount(header);
|
|
288
|
+
}
|
|
289
|
+
function blockText(text, line) {
|
|
290
|
+
if (!line.item)
|
|
291
|
+
return lineText(text, line);
|
|
292
|
+
const raw = text.slice(afterIndent(text, line), line.end);
|
|
293
|
+
return raw.endsWith('\r') ? raw.slice(0, -1) : raw;
|
|
294
|
+
}
|
|
295
|
+
function interruptsWithHtml(head) {
|
|
296
|
+
return HTML_CLOSED.some(([open]) => open.test(head)) || HTML_BLOCK_TAG.test(head);
|
|
297
|
+
}
|
|
298
|
+
function markerColumn(text, line) {
|
|
299
|
+
return widthOf(text, line.inner, afterIndent(text, line));
|
|
300
|
+
}
|
|
301
|
+
function markerEnd(text, at, end) {
|
|
302
|
+
const after = itemMarker(text, at, end);
|
|
303
|
+
if (after === null)
|
|
304
|
+
return null;
|
|
305
|
+
return after > at && (text[after - 1] === ' ' || text[after - 1] === '\t') ? after - 1 : after;
|
|
306
|
+
}
|
|
307
|
+
function itemContent(text, line) {
|
|
308
|
+
let marker = markerEnd(text, afterIndent(text, line), line.end);
|
|
309
|
+
for (;;) {
|
|
310
|
+
let next = marker + 1;
|
|
311
|
+
let spaces = 0;
|
|
312
|
+
while (spaces < 3 && text[next] === ' ') {
|
|
313
|
+
next += 1;
|
|
314
|
+
spaces += 1;
|
|
315
|
+
}
|
|
316
|
+
const nested = next < line.end ? markerEnd(text, next, line.end) : null;
|
|
317
|
+
if (nested === null)
|
|
318
|
+
break;
|
|
319
|
+
marker = nested;
|
|
320
|
+
}
|
|
321
|
+
const at = skipLinkSpace(text, marker);
|
|
322
|
+
const rest = text.slice(at, line.end).trim();
|
|
323
|
+
const column = widthOf(text, line.inner, at);
|
|
324
|
+
const start = widthOf(text, line.inner, marker);
|
|
325
|
+
if (rest !== '' && column - start <= CODE_INDENT)
|
|
326
|
+
return { column, code: null };
|
|
327
|
+
return { column: start + 1, code: rest === '' ? null : marker + 1 };
|
|
328
|
+
}
|
|
329
|
+
function joinsParagraph(text, line, depth, item) {
|
|
330
|
+
if (line.depth > depth)
|
|
331
|
+
return false;
|
|
332
|
+
const head = blockText(text, line);
|
|
333
|
+
if (head.trim() === '' || endsBlock(head) || interruptsWithHtml(head))
|
|
334
|
+
return false;
|
|
335
|
+
if (fenceAt(text, line) !== null)
|
|
336
|
+
return false;
|
|
337
|
+
if (!line.item)
|
|
338
|
+
return true;
|
|
339
|
+
if (item !== undefined && markerColumn(text, line) < item)
|
|
340
|
+
return false;
|
|
341
|
+
if (lineText(text, line).trim() === '')
|
|
342
|
+
return true;
|
|
343
|
+
const ordered = ORDERED.exec(head);
|
|
344
|
+
return ordered !== null && Number(ordered[1]) !== 1;
|
|
345
|
+
}
|
|
346
|
+
function startsParagraph(text, line) {
|
|
347
|
+
return lineText(text, line).trim() !== '' && !endsBlock(blockText(text, line));
|
|
348
|
+
}
|
|
349
|
+
function lineColumn(text, line) {
|
|
350
|
+
return line.item ? markerColumn(text, line) : indentWidth(text, line);
|
|
351
|
+
}
|
|
352
|
+
function endsTable(text, line, depth) {
|
|
353
|
+
const head = blockText(text, line);
|
|
354
|
+
return (head.trim() === '' ||
|
|
355
|
+
line.depth !== depth ||
|
|
356
|
+
line.item ||
|
|
357
|
+
endsBlock(head) ||
|
|
358
|
+
interruptsWithHtml(head) ||
|
|
359
|
+
fenceAt(text, line) !== null);
|
|
360
|
+
}
|
|
361
|
+
function quoteInner(text, start, end, depth) {
|
|
362
|
+
let i = start;
|
|
363
|
+
for (let level = 0; level < depth; level += 1) {
|
|
364
|
+
let spaces = 0;
|
|
365
|
+
while (spaces < 3 && i < end && text[i] === ' ') {
|
|
175
366
|
i += 1;
|
|
367
|
+
spaces += 1;
|
|
176
368
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
};
|
|
369
|
+
if (text[i] !== '>')
|
|
370
|
+
return null;
|
|
371
|
+
i += 1;
|
|
372
|
+
if (text[i] === ' ')
|
|
373
|
+
i += 1;
|
|
183
374
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
375
|
+
return i;
|
|
376
|
+
}
|
|
377
|
+
function htmlEnd(text, line, item) {
|
|
378
|
+
const head = lineText(text, line);
|
|
379
|
+
const closed = HTML_CLOSED.find(([open]) => open.test(head));
|
|
380
|
+
if (closed === undefined && !HTML_BLOCK_TAG.test(head) && !HTML_TAG_LINE.test(head))
|
|
381
|
+
return null;
|
|
382
|
+
if (closed !== undefined && closed[1].test(head))
|
|
383
|
+
return afterLine(text, line.end);
|
|
384
|
+
let cursor = afterLine(text, line.end);
|
|
385
|
+
while (cursor < text.length) {
|
|
386
|
+
const end = endOfLine(text, cursor);
|
|
387
|
+
const inner = quoteInner(text, cursor, end, line.depth);
|
|
388
|
+
if (inner === null)
|
|
389
|
+
return cursor;
|
|
390
|
+
const at = skipLinkSpace(text, inner);
|
|
391
|
+
const body = text.slice(inner, end);
|
|
392
|
+
const blank = BLANK.test(text.slice(at, end));
|
|
393
|
+
if (item !== undefined && !blank && widthOf(text, inner, at) < item)
|
|
394
|
+
return cursor;
|
|
395
|
+
if (closed === undefined && blank)
|
|
396
|
+
return cursor;
|
|
397
|
+
if (closed !== undefined && closed[1].test(body))
|
|
398
|
+
return afterLine(text, end);
|
|
399
|
+
cursor = afterLine(text, end);
|
|
400
|
+
if (cursor === end)
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
return text.length;
|
|
404
|
+
}
|
|
405
|
+
function codeEnd(text, line, base) {
|
|
406
|
+
let stop = afterLine(text, line.end);
|
|
407
|
+
let cursor = stop;
|
|
408
|
+
while (cursor < text.length) {
|
|
409
|
+
const end = endOfLine(text, cursor);
|
|
410
|
+
const current = readLine(text, cursor, end);
|
|
411
|
+
if (current.depth !== line.depth)
|
|
412
|
+
break;
|
|
413
|
+
const blank = lineText(text, current).trim() === '' && !current.item;
|
|
414
|
+
if (!blank && (current.item || indentWidth(text, current) < base + CODE_INDENT))
|
|
415
|
+
break;
|
|
416
|
+
cursor = afterLine(text, end);
|
|
417
|
+
if (!blank)
|
|
418
|
+
stop = cursor;
|
|
419
|
+
if (cursor === end)
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
return stop;
|
|
193
423
|
}
|
|
194
|
-
function
|
|
424
|
+
function structure(text) {
|
|
425
|
+
const joins = new Set();
|
|
426
|
+
const raw = [];
|
|
427
|
+
const items = [];
|
|
428
|
+
let paragraph = null;
|
|
429
|
+
let table = null;
|
|
430
|
+
let depth = 0;
|
|
431
|
+
let cursor = 0;
|
|
432
|
+
while (cursor < text.length) {
|
|
433
|
+
const end = endOfLine(text, cursor);
|
|
434
|
+
const line = readLine(text, cursor, end);
|
|
435
|
+
const content = lineText(text, line);
|
|
436
|
+
const blank = content.trim() === '' && !line.item;
|
|
437
|
+
if (table !== null && endsTable(text, line, table))
|
|
438
|
+
table = null;
|
|
439
|
+
if (table !== null) {
|
|
440
|
+
cursor = afterLine(text, end);
|
|
441
|
+
if (cursor === end)
|
|
442
|
+
break;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (paragraph !== null && joinsParagraph(text, line, paragraph, items.at(-1))) {
|
|
446
|
+
if (headsTable(text, content, end)) {
|
|
447
|
+
table = line.depth;
|
|
448
|
+
paragraph = null;
|
|
449
|
+
}
|
|
450
|
+
else
|
|
451
|
+
joins.add(cursor - 1);
|
|
452
|
+
cursor = afterLine(text, end);
|
|
453
|
+
if (cursor === end)
|
|
454
|
+
break;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
paragraph = null;
|
|
458
|
+
if (line.depth !== depth)
|
|
459
|
+
items.length = 0;
|
|
460
|
+
depth = line.depth;
|
|
461
|
+
if (!blank) {
|
|
462
|
+
while (items.length > 0 && items.at(-1) > lineColumn(text, line))
|
|
463
|
+
items.pop();
|
|
464
|
+
}
|
|
465
|
+
if (line.item && !BREAK.test(blockText(text, line))) {
|
|
466
|
+
const opened = itemContent(text, line);
|
|
467
|
+
items.push(opened.column);
|
|
468
|
+
if (opened.code !== null) {
|
|
469
|
+
const stop = codeEnd(text, line, opened.column);
|
|
470
|
+
raw.push([opened.code, stop]);
|
|
471
|
+
cursor = stop;
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const open = fenceAt(text, line);
|
|
476
|
+
if (open !== null) {
|
|
477
|
+
const stop = fenceSpan(text, line, open);
|
|
478
|
+
raw.push([cursor, stop]);
|
|
479
|
+
cursor = stop;
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
const base = items.at(-1) ?? 0;
|
|
483
|
+
if (!blank && !line.item && indentWidth(text, line) >= base + CODE_INDENT) {
|
|
484
|
+
const stop = codeEnd(text, line, base);
|
|
485
|
+
raw.push([cursor, stop]);
|
|
486
|
+
cursor = stop;
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
const html = htmlEnd(text, line, items.at(-1));
|
|
490
|
+
if (html !== null) {
|
|
491
|
+
raw.push([cursor, html]);
|
|
492
|
+
cursor = html;
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
if (startsParagraph(text, line)) {
|
|
496
|
+
if (headsTable(text, content, end))
|
|
497
|
+
table = line.depth;
|
|
498
|
+
else
|
|
499
|
+
paragraph = line.depth;
|
|
500
|
+
}
|
|
501
|
+
cursor = afterLine(text, end);
|
|
502
|
+
if (cursor === end)
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
return { joins, raw };
|
|
506
|
+
}
|
|
507
|
+
function escapes(text, index) {
|
|
508
|
+
return text[index] === '\\' && PUNCTUATION.test(text[index + 1] ?? '');
|
|
509
|
+
}
|
|
510
|
+
function referenceEnd(text, start, joins) {
|
|
195
511
|
let i = start;
|
|
196
|
-
|
|
197
|
-
while(i < text.length && depth > 0){
|
|
512
|
+
while (i < text.length) {
|
|
198
513
|
const ch = text[i];
|
|
199
|
-
if (
|
|
514
|
+
if (escapes(text, i)) {
|
|
200
515
|
i += 2;
|
|
201
516
|
continue;
|
|
202
517
|
}
|
|
203
|
-
if (ch === '
|
|
204
|
-
|
|
205
|
-
|
|
518
|
+
if (ch === ']')
|
|
519
|
+
return i + 1;
|
|
520
|
+
if (ch === '[')
|
|
521
|
+
return -1;
|
|
522
|
+
if (ch === '\r' && text[i + 1] !== '\n')
|
|
523
|
+
return -1;
|
|
524
|
+
if (ch === '\n' && !joins.has(i))
|
|
525
|
+
return -1;
|
|
206
526
|
i += 1;
|
|
207
527
|
}
|
|
208
|
-
return
|
|
209
|
-
}
|
|
210
|
-
function
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
528
|
+
return -1;
|
|
529
|
+
}
|
|
530
|
+
function labelText(text, from, to) {
|
|
531
|
+
let label = '';
|
|
532
|
+
let cursor = from;
|
|
533
|
+
let newline = text.indexOf('\n', cursor);
|
|
534
|
+
while (newline !== -1 && newline < to) {
|
|
535
|
+
label += `${text.slice(cursor, newline)}\n`;
|
|
536
|
+
cursor = afterIndent(text, readLine(text, newline + 1, endOfLine(text, newline + 1)));
|
|
537
|
+
newline = text.indexOf('\n', cursor);
|
|
538
|
+
}
|
|
539
|
+
return label + text.slice(cursor, to);
|
|
540
|
+
}
|
|
541
|
+
function labelKey(label) {
|
|
542
|
+
return label
|
|
543
|
+
.replace(/[ \t\n\v\f\r]+/g, ' ')
|
|
544
|
+
.replace(/^ | $/g, '')
|
|
545
|
+
.toLowerCase()
|
|
546
|
+
.split('\u0131')
|
|
547
|
+
.map((part) => part.toUpperCase())
|
|
548
|
+
.join('\u0131');
|
|
549
|
+
}
|
|
550
|
+
function labelKeyAt(text, from, to) {
|
|
551
|
+
const label = labelText(text, from, to);
|
|
552
|
+
if (label.length > LABEL_LENGTH && [...label].length > LABEL_LENGTH)
|
|
553
|
+
return '';
|
|
554
|
+
return labelKey(label);
|
|
555
|
+
}
|
|
556
|
+
function closeLink(text, opener, close, defs, joins) {
|
|
557
|
+
const end = close + 1;
|
|
558
|
+
const use = (destination, to) => ({
|
|
559
|
+
start: opener.start,
|
|
560
|
+
end: to,
|
|
561
|
+
labelStart: opener.at + 1,
|
|
562
|
+
labelEnd: close,
|
|
563
|
+
destination,
|
|
564
|
+
});
|
|
565
|
+
if (text[end] === '(') {
|
|
566
|
+
const dest = destination(text, end, joins);
|
|
567
|
+
if (dest !== null)
|
|
568
|
+
return use(dest.occurrence, dest.end);
|
|
226
569
|
}
|
|
227
|
-
if (text[
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
destination: defined
|
|
239
|
-
});
|
|
570
|
+
if (text[end] === '[') {
|
|
571
|
+
const second = referenceEnd(text, end + 1, joins);
|
|
572
|
+
const collapsed = second === end + 2;
|
|
573
|
+
const named = collapsed
|
|
574
|
+
? opener.bracketAfter
|
|
575
|
+
? ''
|
|
576
|
+
: labelKeyAt(text, opener.at + 1, close)
|
|
577
|
+
: labelKeyAt(text, end + 1, second - 1);
|
|
578
|
+
if (second !== -1 && (named !== '' || collapsed)) {
|
|
579
|
+
const defined = defs.get(named);
|
|
580
|
+
return defined === undefined ? null : use(defined, second);
|
|
240
581
|
}
|
|
241
|
-
return close;
|
|
242
582
|
}
|
|
243
|
-
|
|
583
|
+
if (opener.bracketAfter)
|
|
584
|
+
return null;
|
|
585
|
+
const shortcut = defs.get(labelKeyAt(text, opener.at + 1, close));
|
|
586
|
+
return shortcut === undefined ? null : use(shortcut, end);
|
|
244
587
|
}
|
|
245
588
|
function definitionDestination(text, from, to) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
589
|
+
const occurrence = destinationAt(text, skipLinkSpace(text, from), to);
|
|
590
|
+
return occurrence === null || (occurrence.href === '' && !occurrence.bracketed)
|
|
591
|
+
? null
|
|
592
|
+
: occurrence;
|
|
593
|
+
}
|
|
594
|
+
function titleEnd(text, at, joins) {
|
|
595
|
+
const open = text[at];
|
|
596
|
+
if (open !== '"' && open !== "'" && open !== '(')
|
|
597
|
+
return null;
|
|
598
|
+
const closed = closeEnd(text, at + 1, open, joins);
|
|
599
|
+
if (closed === null)
|
|
600
|
+
return null;
|
|
601
|
+
const end = endOfLine(text, closed);
|
|
602
|
+
return BLANK.test(text.slice(closed, end)) ? afterLine(text, end) : null;
|
|
260
603
|
}
|
|
261
|
-
function definitionAt(text, line) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
if (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
604
|
+
function definitionAt(text, line, joins) {
|
|
605
|
+
if (text[line.content] !== '[')
|
|
606
|
+
return null;
|
|
607
|
+
const close = referenceEnd(text, line.content + 1, joins);
|
|
608
|
+
if (close === -1 || text[close] !== ':')
|
|
609
|
+
return null;
|
|
610
|
+
const id = labelKeyAt(text, line.content + 1, close - 1);
|
|
611
|
+
if (id === '')
|
|
612
|
+
return null;
|
|
613
|
+
const from = close + 1;
|
|
614
|
+
let end = endOfLine(text, from);
|
|
615
|
+
let occurrence = definitionDestination(text, from, end);
|
|
269
616
|
if (occurrence === null) {
|
|
270
|
-
if (text.slice(from,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
617
|
+
if (text.slice(from, end).trim() !== '' || !joins.has(end))
|
|
618
|
+
return null;
|
|
619
|
+
const start = end + 1;
|
|
620
|
+
end = endOfLine(text, start);
|
|
621
|
+
occurrence = definitionDestination(text, afterIndent(text, readLine(text, start, end)), end);
|
|
622
|
+
if (occurrence === null)
|
|
623
|
+
return null;
|
|
275
624
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
625
|
+
const rest = text.slice(occurrence.end, end);
|
|
626
|
+
if (!BLANK.test(rest)) {
|
|
627
|
+
const gap = GAP.exec(rest);
|
|
628
|
+
const titled = gap === null ? null : titleEnd(text, occurrence.end + gap[0].length, joins);
|
|
629
|
+
return titled === null ? null : { id, occurrence, next: titled };
|
|
279
630
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
631
|
+
const next = afterLine(text, end);
|
|
632
|
+
if (joins.has(end)) {
|
|
633
|
+
const titled = titleEnd(text, afterIndent(text, readLine(text, next, endOfLine(text, next))), joins);
|
|
634
|
+
if (titled !== null)
|
|
635
|
+
return { id, occurrence, next: titled };
|
|
636
|
+
}
|
|
637
|
+
return { id, occurrence, next };
|
|
285
638
|
}
|
|
286
639
|
function endsBlock(content) {
|
|
287
640
|
return HEADING.test(content) || BREAK.test(content) || SETEXT.test(content);
|
|
288
641
|
}
|
|
289
642
|
function scanBlocks(text) {
|
|
290
|
-
const
|
|
643
|
+
const { joins, raw } = structure(text);
|
|
291
644
|
const definitions = new Map();
|
|
292
645
|
const blocks = [];
|
|
293
|
-
let
|
|
294
|
-
let depth = 0;
|
|
646
|
+
let fresh = 0;
|
|
295
647
|
let i = 0;
|
|
296
|
-
while(i < text.length){
|
|
297
|
-
const
|
|
298
|
-
if (
|
|
299
|
-
|
|
300
|
-
const open = fenceAt(text, line);
|
|
301
|
-
if (open !== null) {
|
|
302
|
-
const stop = fenceSpan(text, line, open);
|
|
303
|
-
fences.push([
|
|
304
|
-
i,
|
|
305
|
-
stop
|
|
306
|
-
]);
|
|
307
|
-
paragraph = false;
|
|
308
|
-
i = stop;
|
|
309
|
-
continue;
|
|
310
|
-
}
|
|
311
|
-
const content = lineText(text, line);
|
|
312
|
-
if (content.trim() === '') {
|
|
313
|
-
paragraph = false;
|
|
314
|
-
i = afterLine(text, line.end);
|
|
648
|
+
while (i < text.length) {
|
|
649
|
+
const skip = spanEndAt(raw, i);
|
|
650
|
+
if (skip !== undefined) {
|
|
651
|
+
i = skip;
|
|
315
652
|
continue;
|
|
316
653
|
}
|
|
317
|
-
const
|
|
654
|
+
const line = readLine(text, i, endOfLine(text, i));
|
|
655
|
+
const definition = lineText(text, line).trim() === '' || (i !== fresh && joins.has(i - 1))
|
|
656
|
+
? null
|
|
657
|
+
: definitionAt(text, line, joins);
|
|
318
658
|
if (definition !== null) {
|
|
319
|
-
if (!definitions.has(definition.id))
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
end: definition.next,
|
|
323
|
-
destination: definition.occurrence
|
|
324
|
-
});
|
|
659
|
+
if (!definitions.has(definition.id))
|
|
660
|
+
definitions.set(definition.id, definition.occurrence);
|
|
661
|
+
blocks.push({ start: line.start, end: definition.next, destination: definition.occurrence });
|
|
325
662
|
i = definition.next;
|
|
663
|
+
fresh = i;
|
|
326
664
|
continue;
|
|
327
665
|
}
|
|
328
|
-
paragraph = !endsBlock(content);
|
|
329
666
|
i = afterLine(text, line.end);
|
|
330
667
|
}
|
|
331
|
-
return {
|
|
332
|
-
fences,
|
|
333
|
-
definitions,
|
|
334
|
-
blocks
|
|
335
|
-
};
|
|
668
|
+
return { raw, definitions, blocks, joins };
|
|
336
669
|
}
|
|
337
|
-
function
|
|
338
|
-
for (const [start, end] of spans){
|
|
339
|
-
if (index >= start && index < end)
|
|
670
|
+
function spanEndAt(spans, index) {
|
|
671
|
+
for (const [start, end] of spans) {
|
|
672
|
+
if (index >= start && index < end)
|
|
673
|
+
return end;
|
|
340
674
|
}
|
|
341
675
|
return undefined;
|
|
342
676
|
}
|
|
677
|
+
export function fenceSpans(text) {
|
|
678
|
+
const fences = [];
|
|
679
|
+
let i = 0;
|
|
680
|
+
while (i < text.length) {
|
|
681
|
+
const line = readLine(text, i, endOfLine(text, i));
|
|
682
|
+
const open = fenceAt(text, line);
|
|
683
|
+
if (open === null) {
|
|
684
|
+
i = afterLine(text, line.end);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
const stop = fenceSpan(text, line, open);
|
|
688
|
+
fences.push([i, stop]);
|
|
689
|
+
i = stop;
|
|
690
|
+
}
|
|
691
|
+
return fences;
|
|
692
|
+
}
|
|
693
|
+
function paragraphEnd(text, from, joins) {
|
|
694
|
+
let i = from;
|
|
695
|
+
while (i < text.length) {
|
|
696
|
+
if (text[i] === '\n' && !joins.has(i))
|
|
697
|
+
return i;
|
|
698
|
+
if (text[i] === '\r' && text[i + 1] !== '\n')
|
|
699
|
+
return i;
|
|
700
|
+
i += 1;
|
|
701
|
+
}
|
|
702
|
+
return i;
|
|
703
|
+
}
|
|
343
704
|
export function linkInventory(body) {
|
|
344
|
-
const {
|
|
705
|
+
const { raw, definitions, blocks, joins } = scanBlocks(body);
|
|
706
|
+
const skipped = [...raw, ...blocks.map((block) => [block.start, block.end])];
|
|
345
707
|
const uses = [];
|
|
708
|
+
const openers = [];
|
|
709
|
+
let paragraph = { start: 0, end: -1, text: '' };
|
|
346
710
|
let i = 0;
|
|
347
|
-
while(i < body.length){
|
|
348
|
-
const
|
|
349
|
-
if (
|
|
350
|
-
|
|
711
|
+
while (i < body.length) {
|
|
712
|
+
const skipEnd = spanEndAt(skipped, i);
|
|
713
|
+
if (skipEnd !== undefined) {
|
|
714
|
+
openers.length = 0;
|
|
715
|
+
i = skipEnd;
|
|
351
716
|
continue;
|
|
352
717
|
}
|
|
353
|
-
|
|
354
|
-
|
|
718
|
+
const ch = body[i];
|
|
719
|
+
if (escapes(body, i)) {
|
|
720
|
+
i += 2;
|
|
355
721
|
continue;
|
|
356
722
|
}
|
|
357
|
-
if (
|
|
358
|
-
i =
|
|
723
|
+
if (ch === '`') {
|
|
724
|
+
i = skipInlineCode(body, i, joins);
|
|
359
725
|
continue;
|
|
360
726
|
}
|
|
361
|
-
if (
|
|
362
|
-
|
|
727
|
+
if (ch === '<') {
|
|
728
|
+
if (i >= paragraph.end) {
|
|
729
|
+
const end = paragraphEnd(body, i, joins);
|
|
730
|
+
paragraph = { start: i, end, text: body.slice(i, end) };
|
|
731
|
+
}
|
|
732
|
+
INLINE_RAW.lastIndex = i - paragraph.start;
|
|
733
|
+
const raw = INLINE_RAW.exec(paragraph.text);
|
|
734
|
+
if (raw !== null) {
|
|
735
|
+
i += raw[0].length;
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if ((ch === '\n' && !joins.has(i)) || (ch === '\r' && body[i + 1] !== '\n'))
|
|
740
|
+
openers.length = 0;
|
|
741
|
+
if (ch === '[' || (ch === '!' && body[i + 1] === '[')) {
|
|
742
|
+
const previous = openers.at(-1);
|
|
743
|
+
if (previous !== undefined)
|
|
744
|
+
previous.bracketAfter = true;
|
|
745
|
+
const image = ch === '!';
|
|
746
|
+
openers.push({ at: image ? i + 1 : i, start: i, image, active: true, bracketAfter: false });
|
|
747
|
+
i += image ? 2 : 1;
|
|
748
|
+
continue;
|
|
749
|
+
}
|
|
750
|
+
if (ch === ']') {
|
|
751
|
+
const opener = openers.pop();
|
|
752
|
+
const use = opener?.active ? closeLink(body, opener, i, definitions, joins) : null;
|
|
753
|
+
if (opener === undefined || use === null) {
|
|
754
|
+
i += 1;
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
uses.push(use);
|
|
758
|
+
if (!opener.image)
|
|
759
|
+
for (const earlier of openers)
|
|
760
|
+
if (!earlier.image)
|
|
761
|
+
earlier.active = false;
|
|
762
|
+
i = use.end;
|
|
363
763
|
continue;
|
|
364
764
|
}
|
|
365
765
|
i += 1;
|
|
366
766
|
}
|
|
367
|
-
return {
|
|
368
|
-
uses,
|
|
369
|
-
blocks
|
|
370
|
-
};
|
|
767
|
+
return { uses, blocks };
|
|
371
768
|
}
|
|
372
769
|
export function hrefOccurrences(body) {
|
|
373
770
|
const byStart = new Map();
|
|
374
|
-
for (const use of linkInventory(body).uses)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
].sort((left, right)=>left.start - right.start);
|
|
771
|
+
for (const use of linkInventory(body).uses)
|
|
772
|
+
byStart.set(use.destination.start, use.destination);
|
|
773
|
+
return [...byStart.values()].sort((left, right) => left.start - right.start);
|
|
378
774
|
}
|
|
379
|
-
|
|
380
|
-
//# sourceMappingURL=links.js.map
|