@tanstack/markdown 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/extensions/callouts.d.ts.map +1 -1
- package/dist/extensions/callouts.js +0 -5
- package/dist/extensions/comment-components.d.ts.map +1 -1
- package/dist/extensions/comment-components.js +16 -34
- package/dist/extensions/headings.js +8 -7
- package/dist/extensions/shared.d.ts.map +1 -1
- package/dist/extensions/shared.js +2 -9
- package/dist/extensions/tabs.d.ts.map +1 -1
- package/dist/extensions/tabs.js +11 -18
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +33 -34
- package/dist/inline.d.ts.map +1 -1
- package/dist/inline.js +106 -212
- package/dist/octane.d.ts.map +1 -1
- package/dist/octane.js +28 -23
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +166 -194
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +45 -37
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +6 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +37 -25
- package/package.json +11 -1
- package/skills/custom-extensions/SKILL.md +11 -4
- package/skills/docs-features/SKILL.md +1 -1
- package/skills/docs-features/references/docs-metadata.md +1 -1
- package/skills/octane-rendering/SKILL.md +1 -1
- package/skills/production-pipelines/SKILL.md +10 -2
- package/skills/react-rendering/SKILL.md +1 -1
- package/skills/render-markdown/SKILL.md +1 -1
- package/skills/render-markdown/references/ast-and-options.md +8 -3
package/dist/parser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseInline } from './inline.js';
|
|
2
|
-
import { createSlugger, footnoteId, isBlank, normalizeInput, normalizeReferenceLabel, plainText, stripIndent } from './utils.js';
|
|
2
|
+
import { createSlugger, footnoteId, isBlank, normalizeInput, normalizeReferenceLabel, parseDestination, plainText, stripIndent } from './utils.js';
|
|
3
3
|
const maxBlockDepth = 64;
|
|
4
4
|
export function parseMarkdown(markdown, options = {}) {
|
|
5
5
|
const normalized = normalizeInput(markdown);
|
|
@@ -22,14 +22,15 @@ export function parseMarkdown(markdown, options = {}) {
|
|
|
22
22
|
const parseOptions = hasReferences || hasFootnotes
|
|
23
23
|
? {
|
|
24
24
|
...options,
|
|
25
|
-
...(hasReferences
|
|
26
|
-
...(hasFootnotes
|
|
25
|
+
...(hasReferences && { references: definitions.references }),
|
|
26
|
+
...(hasFootnotes && { footnotes: definitions.footnotes, footnoteOrder, footnoteCounts }),
|
|
27
27
|
}
|
|
28
28
|
: options;
|
|
29
|
-
const
|
|
29
|
+
const slugger = createSlugger();
|
|
30
|
+
const parser = createBlockParser(lines, parseOptions, slugger);
|
|
30
31
|
const children = parser.parse();
|
|
31
32
|
if (hasFootnotes && footnoteOrder.length > 0) {
|
|
32
|
-
children.push(createFootnotesBlock(definitions.footnotes, footnoteOrder, parseOptions));
|
|
33
|
+
children.push(createFootnotesBlock(definitions.footnotes, footnoteOrder, parseOptions, slugger));
|
|
33
34
|
}
|
|
34
35
|
let document = frontmatter === undefined ? { type: 'root', children } : { type: 'root', frontmatter, children };
|
|
35
36
|
for (const extension of parseOptions.extensions ?? []) {
|
|
@@ -37,88 +38,86 @@ export function parseMarkdown(markdown, options = {}) {
|
|
|
37
38
|
}
|
|
38
39
|
return document;
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const value = this.lines.slice(this.index).join('\n');
|
|
55
|
-
this.index = this.lines.length;
|
|
56
|
-
return value ? [{ type: 'paragraph', children: parseInline(value, this.options) }] : [];
|
|
41
|
+
function createBlockParser(inputLines, options, slugger, budget = { depth: 0 }) {
|
|
42
|
+
let cursor = 0;
|
|
43
|
+
let looseBlocks = false;
|
|
44
|
+
return {
|
|
45
|
+
parse,
|
|
46
|
+
get loose() {
|
|
47
|
+
return looseBlocks;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
function parse() {
|
|
51
|
+
if (budget.depth >= maxBlockDepth) {
|
|
52
|
+
const value = inputLines.slice(cursor).join('\n');
|
|
53
|
+
cursor = inputLines.length;
|
|
54
|
+
return value ? [{ type: 'paragraph', children: parseInline(value, options) }] : [];
|
|
57
55
|
}
|
|
58
|
-
|
|
56
|
+
budget.depth++;
|
|
59
57
|
const nodes = [];
|
|
60
|
-
while (
|
|
61
|
-
if (isBlank(
|
|
62
|
-
|
|
58
|
+
while (cursor < inputLines.length) {
|
|
59
|
+
if (isBlank(current())) {
|
|
60
|
+
if (nodes.length)
|
|
61
|
+
looseBlocks = true;
|
|
62
|
+
cursor++;
|
|
63
63
|
continue;
|
|
64
64
|
}
|
|
65
|
-
const extensionNode =
|
|
65
|
+
const extensionNode = parseExtensionBlock();
|
|
66
66
|
if (extensionNode) {
|
|
67
67
|
nodes.push(extensionNode);
|
|
68
68
|
continue;
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
// Letter-led text cannot open a fence, heading, rule, quote, or list.
|
|
71
|
+
// It can still be a table header, so table detection remains below.
|
|
72
|
+
const node = (/^[a-z]/i.test(current()) ? undefined : (parseFence() ??
|
|
73
|
+
parseHeading() ??
|
|
74
|
+
parseThematicBreak() ??
|
|
75
|
+
parseBlockquote() ??
|
|
76
|
+
parseList())) ??
|
|
77
|
+
parseTable() ??
|
|
78
|
+
parseHtmlBlock() ??
|
|
79
|
+
parseParagraph();
|
|
78
80
|
nodes.push(node);
|
|
79
81
|
}
|
|
80
|
-
|
|
82
|
+
budget.depth--;
|
|
81
83
|
return nodes;
|
|
82
84
|
}
|
|
83
|
-
parseExtensionBlock() {
|
|
84
|
-
for (const extension of
|
|
85
|
+
function parseExtensionBlock() {
|
|
86
|
+
for (const extension of options.extensions ?? []) {
|
|
85
87
|
let consumed = 0;
|
|
86
88
|
const node = extension.parseBlock?.({
|
|
87
|
-
lines:
|
|
88
|
-
index:
|
|
89
|
-
options:
|
|
90
|
-
parseInline: value => parseInline(value,
|
|
91
|
-
parseBlocks: value =>
|
|
89
|
+
lines: inputLines,
|
|
90
|
+
index: cursor,
|
|
91
|
+
options: options,
|
|
92
|
+
parseInline: value => parseInline(value, options),
|
|
93
|
+
parseBlocks: value => createBlockParser(normalizeInput(value).split('\n'), options, slugger, budget).parse(),
|
|
92
94
|
consume: lines => {
|
|
93
95
|
consumed = lines;
|
|
94
96
|
},
|
|
95
97
|
});
|
|
96
98
|
if (node) {
|
|
97
|
-
|
|
99
|
+
cursor += Math.max(consumed, 1);
|
|
98
100
|
return node;
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
return undefined;
|
|
102
104
|
}
|
|
103
|
-
parseFence() {
|
|
104
|
-
const match =
|
|
105
|
+
function parseFence() {
|
|
106
|
+
const match = current().match(/^( {0,3})(`{3,}|~{3,})(.*)$/);
|
|
105
107
|
if (!match)
|
|
106
108
|
return undefined;
|
|
107
|
-
const fence = match[
|
|
108
|
-
const
|
|
109
|
-
const fenceSize = fence.length;
|
|
110
|
-
const info = match[2].trim();
|
|
109
|
+
const fence = match[2];
|
|
110
|
+
const info = match[3].trim();
|
|
111
111
|
const code = [];
|
|
112
|
-
|
|
113
|
-
while (
|
|
114
|
-
const line =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.index++;
|
|
112
|
+
cursor++;
|
|
113
|
+
while (cursor < inputLines.length) {
|
|
114
|
+
const line = current();
|
|
115
|
+
if (line.includes(fence) && /^ {0,3}(?:`+|~+)\s*$/.test(line)) {
|
|
116
|
+
cursor++;
|
|
118
117
|
break;
|
|
119
118
|
}
|
|
120
|
-
code.push(line);
|
|
121
|
-
|
|
119
|
+
code.push(stripIndent(line, match[1].length));
|
|
120
|
+
cursor++;
|
|
122
121
|
}
|
|
123
122
|
return {
|
|
124
123
|
type: 'code',
|
|
@@ -126,58 +125,55 @@ class BlockParser {
|
|
|
126
125
|
...parseCodeInfo(info),
|
|
127
126
|
};
|
|
128
127
|
}
|
|
129
|
-
parseHeading() {
|
|
130
|
-
const match =
|
|
128
|
+
function parseHeading() {
|
|
129
|
+
const match = current().match(/^ {0,3}(#{1,6})(?:[ \t]+(.*)|[ \t]*)$/);
|
|
131
130
|
if (!match)
|
|
132
131
|
return undefined;
|
|
133
132
|
const depth = match[1].length;
|
|
134
133
|
const rawValue = match[2] ?? '';
|
|
135
134
|
const value = (/^#+[ \t]*$/.test(rawValue) ? '' : rawValue.replace(/[ \t]+#+[ \t]*$/, '')).trim();
|
|
136
|
-
const children = parseInline(value,
|
|
137
|
-
const id =
|
|
138
|
-
|
|
135
|
+
const children = parseInline(value, options);
|
|
136
|
+
const id = createHeadingId(children);
|
|
137
|
+
cursor++;
|
|
139
138
|
return id ? { type: 'heading', depth, id, children } : { type: 'heading', depth, children };
|
|
140
139
|
}
|
|
141
|
-
parseThematicBreak() {
|
|
142
|
-
if (!/^ {0,3}([-*_])(?:\s*\1){2,}\s*$/.test(
|
|
140
|
+
function parseThematicBreak() {
|
|
141
|
+
if (!/^ {0,3}([-*_])(?:\s*\1){2,}\s*$/.test(current()))
|
|
143
142
|
return undefined;
|
|
144
|
-
|
|
143
|
+
cursor++;
|
|
145
144
|
return { type: 'thematicBreak' };
|
|
146
145
|
}
|
|
147
|
-
parseBlockquote() {
|
|
148
|
-
if (!/^ {0,3}>\s?/.test(
|
|
146
|
+
function parseBlockquote() {
|
|
147
|
+
if (!/^ {0,3}>\s?/.test(current()))
|
|
149
148
|
return undefined;
|
|
150
149
|
const quoted = [];
|
|
151
|
-
while (
|
|
152
|
-
const line =
|
|
153
|
-
if (isBlank(line)) {
|
|
154
|
-
quoted.push('');
|
|
155
|
-
this.index++;
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
150
|
+
while (cursor < inputLines.length) {
|
|
151
|
+
const line = current();
|
|
158
152
|
const match = line.match(/^ {0,3}>\s?(.*)$/);
|
|
159
|
-
if (!match)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
if (!match) {
|
|
154
|
+
if (!isBlank(line))
|
|
155
|
+
break;
|
|
156
|
+
looseBlocks = true;
|
|
157
|
+
}
|
|
158
|
+
quoted.push(match?.[1] ?? '');
|
|
159
|
+
cursor++;
|
|
163
160
|
}
|
|
164
161
|
return {
|
|
165
162
|
type: 'blockquote',
|
|
166
|
-
children:
|
|
163
|
+
children: createBlockParser(quoted, options, slugger, budget).parse(),
|
|
167
164
|
};
|
|
168
165
|
}
|
|
169
|
-
parseList() {
|
|
170
|
-
const first = listMarker(
|
|
166
|
+
function parseList() {
|
|
167
|
+
const first = listMarker(current());
|
|
171
168
|
if (!first)
|
|
172
169
|
return undefined;
|
|
173
170
|
const items = [];
|
|
174
171
|
const ordered = first.ordered;
|
|
175
172
|
const baseIndent = first.indent;
|
|
176
|
-
const start = ordered ? first.number : undefined;
|
|
177
173
|
let loose = false;
|
|
178
|
-
while (
|
|
179
|
-
const marker = listMarker(
|
|
180
|
-
if (!marker ||
|
|
174
|
+
while (cursor < inputLines.length) {
|
|
175
|
+
const marker = listMarker(current());
|
|
176
|
+
if (!marker || marker.marker !== first.marker || marker.indent !== baseIndent)
|
|
181
177
|
break;
|
|
182
178
|
let firstLine = marker.content;
|
|
183
179
|
const task = firstLine.match(/^\[([ xX])\]\s+(.*)$/);
|
|
@@ -185,45 +181,46 @@ class BlockParser {
|
|
|
185
181
|
if (task)
|
|
186
182
|
firstLine = task[2];
|
|
187
183
|
const itemLines = [firstLine];
|
|
188
|
-
|
|
189
|
-
while (
|
|
190
|
-
const line =
|
|
184
|
+
cursor++;
|
|
185
|
+
while (cursor < inputLines.length) {
|
|
186
|
+
const line = current();
|
|
191
187
|
const nextMarker = listMarker(line);
|
|
192
188
|
if (nextMarker && nextMarker.indent === baseIndent)
|
|
193
189
|
break;
|
|
194
190
|
if (isBlank(line)) {
|
|
195
|
-
let nextIndex =
|
|
196
|
-
while (nextIndex <
|
|
191
|
+
let nextIndex = cursor;
|
|
192
|
+
while (nextIndex < inputLines.length && isBlank(inputLines[nextIndex]))
|
|
197
193
|
nextIndex++;
|
|
198
|
-
const following =
|
|
194
|
+
const following = inputLines[nextIndex];
|
|
199
195
|
if (following === undefined)
|
|
200
196
|
break;
|
|
201
197
|
const followingMarker = listMarker(following);
|
|
202
198
|
if (followingMarker?.indent === baseIndent) {
|
|
203
|
-
if (
|
|
199
|
+
if (followingMarker.marker !== first.marker)
|
|
204
200
|
break;
|
|
205
201
|
loose = true;
|
|
206
|
-
|
|
202
|
+
cursor = nextIndex;
|
|
207
203
|
break;
|
|
208
204
|
}
|
|
209
205
|
if (leadingSpaces(following) < marker.contentIndent)
|
|
210
206
|
break;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.index = nextIndex;
|
|
207
|
+
while (cursor < nextIndex)
|
|
208
|
+
itemLines.push(stripIndent(inputLines[cursor++], marker.contentIndent));
|
|
214
209
|
continue;
|
|
215
210
|
}
|
|
216
211
|
if (leadingSpaces(line) >= marker.contentIndent) {
|
|
217
212
|
itemLines.push(stripIndent(line, marker.contentIndent));
|
|
218
|
-
|
|
213
|
+
cursor++;
|
|
219
214
|
continue;
|
|
220
215
|
}
|
|
221
|
-
if (isBlockStart(line,
|
|
216
|
+
if (isBlockStart(line, next()))
|
|
222
217
|
break;
|
|
223
218
|
itemLines.push(line.trimStart());
|
|
224
|
-
|
|
219
|
+
cursor++;
|
|
225
220
|
}
|
|
226
|
-
const
|
|
221
|
+
const parser = createBlockParser(itemLines, options, slugger, budget);
|
|
222
|
+
const children = parser.parse();
|
|
223
|
+
loose ||= parser.loose;
|
|
227
224
|
const item = { type: 'listItem', children };
|
|
228
225
|
if (checked !== undefined)
|
|
229
226
|
item.checked = checked;
|
|
@@ -232,133 +229,120 @@ class BlockParser {
|
|
|
232
229
|
return {
|
|
233
230
|
type: 'list',
|
|
234
231
|
ordered,
|
|
235
|
-
...(ordered &&
|
|
232
|
+
...(ordered && { start: first.number }),
|
|
236
233
|
...(loose && { loose: true }),
|
|
237
234
|
items,
|
|
238
235
|
};
|
|
239
236
|
}
|
|
240
|
-
parseTable() {
|
|
241
|
-
const header =
|
|
242
|
-
const delimiter =
|
|
237
|
+
function parseTable() {
|
|
238
|
+
const header = current();
|
|
239
|
+
const delimiter = next();
|
|
243
240
|
if (!delimiter || !looksLikeTableHeader(header, delimiter))
|
|
244
241
|
return undefined;
|
|
245
242
|
const headerCells = splitTableRow(header);
|
|
246
243
|
const align = splitTableRow(delimiter).map(parseAlign);
|
|
247
244
|
const columns = headerCells.length;
|
|
248
245
|
const rows = [];
|
|
249
|
-
|
|
250
|
-
while (
|
|
251
|
-
const line =
|
|
252
|
-
if (isBlank(line) || isBlockStart(line,
|
|
246
|
+
cursor += 2;
|
|
247
|
+
while (cursor < inputLines.length) {
|
|
248
|
+
const line = current();
|
|
249
|
+
if (isBlank(line) || isBlockStart(line, next()))
|
|
253
250
|
break;
|
|
254
251
|
const values = splitTableRow(line);
|
|
255
|
-
rows.push(Array.from({ length: columns }, (_, index) => cell(values[index] ?? '',
|
|
256
|
-
|
|
252
|
+
rows.push(Array.from({ length: columns }, (_, index) => cell(values[index] ?? '', options)));
|
|
253
|
+
cursor++;
|
|
257
254
|
}
|
|
258
255
|
return {
|
|
259
256
|
type: 'table',
|
|
260
257
|
align,
|
|
261
|
-
header: headerCells.map(value => cell(value,
|
|
258
|
+
header: headerCells.map(value => cell(value, options)),
|
|
262
259
|
rows,
|
|
263
260
|
};
|
|
264
261
|
}
|
|
265
|
-
parseHtmlBlock() {
|
|
266
|
-
if (!
|
|
262
|
+
function parseHtmlBlock() {
|
|
263
|
+
if (!options.allowHtml || !/^ {0,3}<([A-Za-z][\w:-]*|!--|\/[A-Za-z])/.test(current()))
|
|
267
264
|
return undefined;
|
|
268
265
|
const html = [];
|
|
269
|
-
if (/^ {0,3}<!--/.test(
|
|
270
|
-
while (
|
|
271
|
-
const line =
|
|
266
|
+
if (/^ {0,3}<!--/.test(current())) {
|
|
267
|
+
while (cursor < inputLines.length) {
|
|
268
|
+
const line = current();
|
|
272
269
|
html.push(line);
|
|
273
|
-
|
|
270
|
+
cursor++;
|
|
274
271
|
if (line.includes('-->'))
|
|
275
272
|
break;
|
|
276
273
|
}
|
|
277
274
|
return { type: 'html', value: html.join('\n') };
|
|
278
275
|
}
|
|
279
|
-
while (
|
|
280
|
-
html.push(
|
|
281
|
-
|
|
276
|
+
while (cursor < inputLines.length && !isBlank(current())) {
|
|
277
|
+
html.push(current());
|
|
278
|
+
cursor++;
|
|
282
279
|
}
|
|
283
280
|
return { type: 'html', value: html.join('\n') };
|
|
284
281
|
}
|
|
285
|
-
parseParagraph() {
|
|
282
|
+
function parseParagraph() {
|
|
286
283
|
const lines = [];
|
|
287
|
-
while (
|
|
288
|
-
const line =
|
|
284
|
+
while (cursor < inputLines.length) {
|
|
285
|
+
const line = current();
|
|
289
286
|
if (isBlank(line))
|
|
290
287
|
break;
|
|
291
|
-
if (lines.length > 0 && isBlockStart(line,
|
|
288
|
+
if (lines.length > 0 && isBlockStart(line, next()))
|
|
292
289
|
break;
|
|
293
290
|
lines.push(line.trim());
|
|
294
|
-
|
|
291
|
+
cursor++;
|
|
295
292
|
}
|
|
296
293
|
return {
|
|
297
294
|
type: 'paragraph',
|
|
298
|
-
children: parseInline(lines.join('\n'),
|
|
295
|
+
children: parseInline(lines.join('\n'), options),
|
|
299
296
|
};
|
|
300
297
|
}
|
|
301
|
-
createHeadingId(children) {
|
|
302
|
-
if (
|
|
298
|
+
function createHeadingId(children) {
|
|
299
|
+
if (options.headingIds === false)
|
|
303
300
|
return undefined;
|
|
304
301
|
const text = plainText(children);
|
|
305
|
-
if (typeof
|
|
306
|
-
return
|
|
307
|
-
return
|
|
302
|
+
if (typeof options.headingIds === 'function')
|
|
303
|
+
return options.headingIds(text, cursor);
|
|
304
|
+
return slugger(text);
|
|
308
305
|
}
|
|
309
|
-
current() {
|
|
310
|
-
return
|
|
306
|
+
function current() {
|
|
307
|
+
return inputLines[cursor] ?? '';
|
|
311
308
|
}
|
|
312
|
-
next() {
|
|
313
|
-
return
|
|
309
|
+
function next() {
|
|
310
|
+
return inputLines[cursor + 1];
|
|
314
311
|
}
|
|
315
312
|
}
|
|
316
313
|
function parseCodeInfo(info) {
|
|
317
|
-
if (!info)
|
|
318
|
-
return {};
|
|
319
314
|
const langMatch = info.match(/^([A-Za-z0-9_+.#-]+)/);
|
|
320
315
|
const lang = langMatch?.[1];
|
|
321
316
|
const meta = lang ? info.slice(lang.length).trim() : info;
|
|
322
|
-
const
|
|
323
|
-
const
|
|
317
|
+
const title = meta.match(/(?:^|\s)(?:title|file)=(?:"([^"]+)"|'([^']+)'|([^\s}]+))/)?.slice(1).find(Boolean);
|
|
318
|
+
const framework = meta.match(/(?:^|\s)framework=(?:"([^"]+)"|'([^']+)'|([^\s}]+))/)?.slice(1).find(Boolean);
|
|
324
319
|
const rangeMatch = meta.match(/\{([^}]+)\}|(?:^|\s)lines=([^\s]+)/);
|
|
325
|
-
const highlightLines = parseLineRanges(rangeMatch
|
|
326
|
-
const title = titleMatch ? titleMatch[1] ?? titleMatch[2] ?? titleMatch[3] : undefined;
|
|
327
|
-
const framework = frameworkMatch ? frameworkMatch[1] ?? frameworkMatch[2] ?? frameworkMatch[3] : undefined;
|
|
320
|
+
const highlightLines = rangeMatch ? parseLineRanges(rangeMatch[1] ?? rangeMatch[2]) : [];
|
|
328
321
|
return {
|
|
329
|
-
...(lang
|
|
330
|
-
...(meta
|
|
331
|
-
...(title
|
|
332
|
-
...(framework
|
|
333
|
-
...(highlightLines.length
|
|
322
|
+
...(lang && { lang }),
|
|
323
|
+
...(meta && { meta }),
|
|
324
|
+
...(title && { title, file: title }),
|
|
325
|
+
...(framework && { framework: framework.toLowerCase() }),
|
|
326
|
+
...(highlightLines.length && { highlightLines }),
|
|
334
327
|
};
|
|
335
328
|
}
|
|
336
329
|
function extractDefinitions(lines) {
|
|
337
330
|
const references = Object.create(null);
|
|
338
331
|
const footnotes = Object.create(null);
|
|
339
|
-
const footnoteIds =
|
|
332
|
+
const footnoteIds = createSlugger(footnoteId);
|
|
340
333
|
const remaining = [];
|
|
341
|
-
let
|
|
342
|
-
let fenceSize = 0;
|
|
334
|
+
let activeFence = '';
|
|
343
335
|
let index = 0;
|
|
344
336
|
while (index < lines.length) {
|
|
345
337
|
const line = lines[index];
|
|
346
|
-
const fence = line.match(/^ {0,3}(`{3,}|~{3,})
|
|
338
|
+
const fence = (!activeFence || line.includes(activeFence)) && line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
347
339
|
if (fence) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
else if (marker === fenceMarker && fence[1].length >= fenceSize) {
|
|
354
|
-
fenceMarker = undefined;
|
|
355
|
-
fenceSize = 0;
|
|
356
|
-
}
|
|
357
|
-
remaining.push(line);
|
|
358
|
-
index++;
|
|
359
|
-
continue;
|
|
340
|
+
if (!activeFence)
|
|
341
|
+
activeFence = fence[1];
|
|
342
|
+
else if (fence[1].startsWith(activeFence) && isBlank(fence[2]))
|
|
343
|
+
activeFence = '';
|
|
360
344
|
}
|
|
361
|
-
if (!
|
|
345
|
+
else if (!activeFence) {
|
|
362
346
|
const footnote = line.match(/^ {0,3}\[\^([^\]\n]+)\]:[ \t]*(.*)$/);
|
|
363
347
|
if (footnote) {
|
|
364
348
|
const label = footnote[1];
|
|
@@ -373,20 +357,14 @@ function extractDefinitions(lines) {
|
|
|
373
357
|
}
|
|
374
358
|
const key = normalizeReferenceLabel(label);
|
|
375
359
|
if (!footnotes[key]) {
|
|
376
|
-
|
|
377
|
-
const count = (footnoteIds.get(baseId) ?? 0) + 1;
|
|
378
|
-
footnoteIds.set(baseId, count);
|
|
379
|
-
footnotes[key] = { label, content: content.join('\n'), id: count === 1 ? baseId : `${baseId}-${count}` };
|
|
360
|
+
footnotes[key] = { label, content: content.join('\n'), id: footnoteIds(label) };
|
|
380
361
|
}
|
|
381
362
|
continue;
|
|
382
363
|
}
|
|
383
|
-
const definition = line.match(/^ {0,3}\[([^\]\n]+)\]:[ \t]*(\S
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
references[normalizeReferenceLabel(definition[1])]
|
|
387
|
-
href: definition[2].replace(/^<|>$/g, ''),
|
|
388
|
-
...(title !== undefined ? { title } : {}),
|
|
389
|
-
};
|
|
364
|
+
const definition = line.match(/^ {0,3}\[([^\]\n]+)\]:[ \t]*(\S.*)$/);
|
|
365
|
+
const destination = definition && parseDestination(definition[2].trimEnd());
|
|
366
|
+
if (destination) {
|
|
367
|
+
references[normalizeReferenceLabel(definition[1])] ??= destination;
|
|
390
368
|
index++;
|
|
391
369
|
continue;
|
|
392
370
|
}
|
|
@@ -396,7 +374,7 @@ function extractDefinitions(lines) {
|
|
|
396
374
|
}
|
|
397
375
|
return { lines: remaining, references, footnotes };
|
|
398
376
|
}
|
|
399
|
-
function createFootnotesBlock(footnotes, footnoteOrder, options) {
|
|
377
|
+
function createFootnotesBlock(footnotes, footnoteOrder, options, slugger) {
|
|
400
378
|
const items = [];
|
|
401
379
|
for (let index = 0; index < footnoteOrder.length; index++) {
|
|
402
380
|
const key = footnoteOrder[index];
|
|
@@ -404,9 +382,9 @@ function createFootnotesBlock(footnotes, footnoteOrder, options) {
|
|
|
404
382
|
if (!definition)
|
|
405
383
|
continue;
|
|
406
384
|
items.push({
|
|
407
|
-
id: definition.id ??
|
|
385
|
+
id: definition.id ?? footnoteId(definition.label),
|
|
408
386
|
number: index + 1,
|
|
409
|
-
children:
|
|
387
|
+
children: createBlockParser(normalizeInput(definition.content).split('\n'), options, slugger).parse(),
|
|
410
388
|
});
|
|
411
389
|
}
|
|
412
390
|
for (const item of items) {
|
|
@@ -424,6 +402,9 @@ function parseLineRanges(value) {
|
|
|
424
402
|
continue;
|
|
425
403
|
const start = Number(match[1]);
|
|
426
404
|
const end = Number(match[2] ?? match[1]);
|
|
405
|
+
// Larger integers can stop line++ from making progress.
|
|
406
|
+
if (end > Number.MAX_SAFE_INTEGER)
|
|
407
|
+
continue;
|
|
427
408
|
for (let line = start; line <= end && line < start + 1000; line++)
|
|
428
409
|
lines.add(line);
|
|
429
410
|
}
|
|
@@ -437,25 +418,19 @@ function listMarker(line) {
|
|
|
437
418
|
const ordered = /\d/.test(marker[0]);
|
|
438
419
|
return {
|
|
439
420
|
ordered,
|
|
440
|
-
...(ordered
|
|
421
|
+
...(ordered && { number: Number.parseInt(marker, 10) }),
|
|
441
422
|
indent: match[1].length,
|
|
442
423
|
marker: ordered ? marker.at(-1) : marker,
|
|
443
424
|
contentIndent: match[1].length + marker.length + (match[3]?.length ?? 1),
|
|
444
425
|
content: match[4] ?? '',
|
|
445
426
|
};
|
|
446
427
|
}
|
|
447
|
-
function sameListType(left, right) {
|
|
448
|
-
return left.ordered === right.ordered && left.marker === right.marker;
|
|
449
|
-
}
|
|
450
428
|
function leadingSpaces(line) {
|
|
451
429
|
return line.match(/^ */)?.[0].length ?? 0;
|
|
452
430
|
}
|
|
453
431
|
function isBlockStart(line, next) {
|
|
454
432
|
const marker = listMarker(line);
|
|
455
|
-
return (/^ {0,3}(
|
|
456
|
-
/^ {0,3}#{1,6}(?:\s+|$)/.test(line) ||
|
|
457
|
-
/^ {0,3}([-*_])(?:\s*\1){2,}\s*$/.test(line) ||
|
|
458
|
-
/^ {0,3}>\s?/.test(line) ||
|
|
433
|
+
return (/^ {0,3}(?:`{3,}|~{3,}|#{1,6}(?:\s|$)|([-*_])(?:\s*\1){2,}\s*$|>)/.test(line) ||
|
|
459
434
|
(marker !== undefined && (!marker.ordered || marker.number === 1)) ||
|
|
460
435
|
(!!next && looksLikeTableHeader(line, next)));
|
|
461
436
|
}
|
|
@@ -466,14 +441,10 @@ function looksLikeTableHeader(header, delimiter) {
|
|
|
466
441
|
return cells.length === splitTableRow(header).length && cells.every(cell => /^:?-+:?$/.test(cell.trim()));
|
|
467
442
|
}
|
|
468
443
|
function splitTableRow(value) {
|
|
469
|
-
|
|
470
|
-
if (row.startsWith('|'))
|
|
471
|
-
row = row.slice(1);
|
|
472
|
-
if (row.endsWith('|'))
|
|
473
|
-
row = row.slice(0, -1);
|
|
444
|
+
const row = value.trim();
|
|
474
445
|
const cells = [];
|
|
475
446
|
let current = '';
|
|
476
|
-
for (let index = 0; index < row.length; index++) {
|
|
447
|
+
for (let index = row.startsWith('|') ? 1 : 0; index < row.length; index++) {
|
|
477
448
|
const char = row[index];
|
|
478
449
|
if (char === '\\' && row[index + 1] === '|') {
|
|
479
450
|
current += '|';
|
|
@@ -487,7 +458,8 @@ function splitTableRow(value) {
|
|
|
487
458
|
}
|
|
488
459
|
current += char;
|
|
489
460
|
}
|
|
490
|
-
|
|
461
|
+
if (current || !row.endsWith('|') || !cells.length)
|
|
462
|
+
cells.push(current.trim());
|
|
491
463
|
return cells;
|
|
492
464
|
}
|
|
493
465
|
function parseAlign(value) {
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGlG,OAAO,KAAK,EAAE,SAAS,EAAwD,UAAU,EAAE,aAAa,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAE1J,KAAK,oBAAoB,GAAG,MAAM,GAAG,CAAC,iBAAiB,CAAA;AACvD,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAExE,MAAM,MAAM,sBAAsB,CAAC,OAAO,SAAS,oBAAoB,IAAI,wBAAwB,CAAC,OAAO,CAAC,CAAA;AAE5G,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC;KACtC,OAAO,IAAI,oBAAoB,GAAG,oBAAoB,GAAG,aAAa,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;CACzG,CAAC,GACA,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAA;AAEzD,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,UAAU,CAAC,EAAE,YAAY,CAAA;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,QAAQ,EAAE,aAAa,CAAA;CACxB;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,aAAa,GAAG,YAAY,CAE9E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAGvG;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,oBAAyB,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,CA+DhH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,oBAAyB,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CA0C/G"}
|