@stacksjs/ts-md 0.1.0

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/dist/index.js ADDED
@@ -0,0 +1,1130 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true,
8
+ configurable: true,
9
+ set: (newValue) => all[name] = () => newValue
10
+ });
11
+ };
12
+
13
+ // src/frontmatter.ts
14
+ var exports_frontmatter = {};
15
+ __export(exports_frontmatter, {
16
+ stringify: () => stringify2,
17
+ parse: () => parse2,
18
+ hasFrontmatter: () => hasFrontmatter,
19
+ extractFrontmatter: () => extractFrontmatter
20
+ });
21
+
22
+ // src/yaml.ts
23
+ var exports_yaml = {};
24
+ __export(exports_yaml, {
25
+ stringify: () => stringify,
26
+ parse: () => parse
27
+ });
28
+ function convertYaml11Booleans(obj) {
29
+ if (obj === null || obj === undefined) {
30
+ return obj;
31
+ }
32
+ if (typeof obj === "string") {
33
+ const lower = obj.toLowerCase();
34
+ if (lower === "yes" || lower === "on")
35
+ return true;
36
+ if (lower === "no" || lower === "off")
37
+ return false;
38
+ return obj;
39
+ }
40
+ if (Array.isArray(obj)) {
41
+ return obj.map(convertYaml11Booleans);
42
+ }
43
+ if (typeof obj === "object") {
44
+ const result = {};
45
+ for (const [key, value] of Object.entries(obj)) {
46
+ result[key] = convertYaml11Booleans(value);
47
+ }
48
+ return result;
49
+ }
50
+ return obj;
51
+ }
52
+ function parse(input, options = {}) {
53
+ const strict = options.strict ?? false;
54
+ try {
55
+ const content = input.replace(/^\uFEFF/, "");
56
+ if (!content.trim()) {
57
+ return {};
58
+ }
59
+ let result = Bun.YAML.parse(content);
60
+ if (Array.isArray(result) && result.length === 1) {
61
+ result = result[0];
62
+ }
63
+ return convertYaml11Booleans(result);
64
+ } catch (error) {
65
+ if (strict) {
66
+ throw new Error(`YAML parsing failed: ${error}`);
67
+ }
68
+ return {};
69
+ }
70
+ }
71
+ function stringify(obj, _options = {}) {
72
+ try {
73
+ return Bun.YAML.stringify(obj, null, 2);
74
+ } catch {
75
+ return stringifyFallback(obj, 0);
76
+ }
77
+ }
78
+ function stringifyFallback(obj, indent) {
79
+ return stringifyValue(obj, indent);
80
+ }
81
+ function stringifyValue(value, indent) {
82
+ const spaces = " ".repeat(indent);
83
+ if (value === null || value === undefined) {
84
+ return "null";
85
+ }
86
+ if (typeof value === "boolean") {
87
+ return value.toString();
88
+ }
89
+ if (typeof value === "number") {
90
+ return value.toString();
91
+ }
92
+ if (typeof value === "string") {
93
+ if (value.includes(":") || value.includes("#") || value.includes(`
94
+ `)) {
95
+ return `"${value.replace(/"/g, "\\\"")}"`;
96
+ }
97
+ return value;
98
+ }
99
+ if (Array.isArray(value)) {
100
+ if (value.length === 0)
101
+ return "[]";
102
+ return value.map((item) => {
103
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
104
+ const itemStr = stringifyValue(item, indent + 2);
105
+ return `
106
+ ${spaces}- ${itemStr.trim()}`;
107
+ }
108
+ return `
109
+ ${spaces}- ${stringifyValue(item, indent + 2)}`;
110
+ }).join("");
111
+ }
112
+ if (typeof value === "object") {
113
+ const keys = Object.keys(value);
114
+ if (keys.length === 0)
115
+ return "{}";
116
+ return keys.map((key) => {
117
+ const val = value[key];
118
+ if (typeof val === "object" && val !== null) {
119
+ return `
120
+ ${spaces}${key}:${stringifyValue(val, indent + 2)}`;
121
+ }
122
+ return `
123
+ ${spaces}${key}: ${stringifyValue(val, indent + 2)}`;
124
+ }).join("");
125
+ }
126
+ return String(value);
127
+ }
128
+
129
+ // src/frontmatter.ts
130
+ var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n/;
131
+ var FRONTMATTER_REGEX_ALT = /^\+\+\+\r?\n([\s\S]*?)\r?\n\+\+\+\r?\n/;
132
+ function parse2(content) {
133
+ const original = content;
134
+ let match = content.match(FRONTMATTER_REGEX);
135
+ let data = {};
136
+ let matter;
137
+ let markdown = content;
138
+ if (match) {
139
+ matter = match[1];
140
+ markdown = content.substring(match[0].length);
141
+ data = parse(matter);
142
+ } else {
143
+ match = content.match(FRONTMATTER_REGEX_ALT);
144
+ if (match) {
145
+ matter = match[1];
146
+ markdown = content.substring(match[0].length);
147
+ data = parseToml(matter);
148
+ }
149
+ }
150
+ return {
151
+ data,
152
+ content: markdown,
153
+ original,
154
+ matter
155
+ };
156
+ }
157
+ function parseToml(content) {
158
+ const result = {};
159
+ const lines = content.split(`
160
+ `);
161
+ for (const line of lines) {
162
+ const trimmed = line.trim();
163
+ if (!trimmed || trimmed.startsWith("#")) {
164
+ continue;
165
+ }
166
+ const equalIndex = trimmed.indexOf("=");
167
+ if (equalIndex > 0) {
168
+ const key = trimmed.substring(0, equalIndex).trim();
169
+ const value = trimmed.substring(equalIndex + 1).trim();
170
+ result[key] = parseTomlValue(value);
171
+ }
172
+ }
173
+ return result;
174
+ }
175
+ function parseTomlValue(value) {
176
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
177
+ return value.substring(1, value.length - 1);
178
+ }
179
+ if (value === "true")
180
+ return true;
181
+ if (value === "false")
182
+ return false;
183
+ if (/^-?\d+$/.test(value)) {
184
+ return Number.parseInt(value, 10);
185
+ }
186
+ if (/^-?\d+\.\d+$/.test(value)) {
187
+ return Number.parseFloat(value);
188
+ }
189
+ if (value.startsWith("[") && value.endsWith("]")) {
190
+ const items = value.substring(1, value.length - 1).split(",");
191
+ return items.map((item) => parseTomlValue(item.trim()));
192
+ }
193
+ return value;
194
+ }
195
+ function stringify2(data, content, format = "yaml") {
196
+ if (!data || Object.keys(data).length === 0) {
197
+ return content;
198
+ }
199
+ const delimiter = format === "yaml" ? "---" : "+++";
200
+ const matter = format === "yaml" ? stringify(data).trim() : stringifyToml(data).trim();
201
+ return `${delimiter}
202
+ ${matter}
203
+ ${delimiter}
204
+ ${content}`;
205
+ }
206
+ function stringifyToml(obj) {
207
+ const lines = [];
208
+ for (const [key, value] of Object.entries(obj)) {
209
+ if (typeof value === "string") {
210
+ lines.push(`${key} = "${value}"`);
211
+ } else if (typeof value === "boolean" || typeof value === "number") {
212
+ lines.push(`${key} = ${value}`);
213
+ } else if (Array.isArray(value)) {
214
+ const items = value.map((item) => {
215
+ if (typeof item === "string")
216
+ return `"${item}"`;
217
+ return String(item);
218
+ });
219
+ lines.push(`${key} = [${items.join(", ")}]`);
220
+ }
221
+ }
222
+ return lines.join(`
223
+ `);
224
+ }
225
+ function hasFrontmatter(content) {
226
+ return FRONTMATTER_REGEX.test(content) || FRONTMATTER_REGEX_ALT.test(content);
227
+ }
228
+ function extractFrontmatter(content) {
229
+ let match = content.match(FRONTMATTER_REGEX);
230
+ if (match)
231
+ return match[1];
232
+ match = content.match(FRONTMATTER_REGEX_ALT);
233
+ if (match)
234
+ return match[1];
235
+ return null;
236
+ }
237
+
238
+ // src/parser.ts
239
+ var defaultOptions = {
240
+ gfm: true,
241
+ breaks: false,
242
+ headerIds: true,
243
+ headerPrefix: "",
244
+ pedantic: false,
245
+ smartLists: true,
246
+ smartypants: false,
247
+ sanitize: false
248
+ };
249
+ var CODE_NEWLINE = 10;
250
+ var CODE_HASH = 35;
251
+ var CODE_STAR = 42;
252
+ var CODE_UNDERSCORE = 95;
253
+ var CODE_BACKTICK = 96;
254
+ var CODE_LBRACKET = 91;
255
+ var CODE_BANG = 33;
256
+ var CODE_TILDE = 126;
257
+ var CODE_PIPE = 124;
258
+ var CODE_GT = 62;
259
+ var CODE_MINUS = 45;
260
+ var CODE_PLUS = 43;
261
+ var CODE_SPACE = 32;
262
+ function isAlphanumeric(code) {
263
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
264
+ }
265
+ function parse3(markdown, options = {}) {
266
+ const opts = { ...defaultOptions, ...options };
267
+ const state = {
268
+ src: markdown.replace(/\r\n/g, `
269
+ `).replace(/\r/g, `
270
+ `),
271
+ pos: 0,
272
+ posMax: markdown.length,
273
+ tokens: [],
274
+ pending: "",
275
+ level: 0,
276
+ options: opts,
277
+ cache: {},
278
+ delimiters: []
279
+ };
280
+ parseBlocks(state);
281
+ return renderTokens(state.tokens, opts);
282
+ }
283
+ function parseSync(markdown, options = {}) {
284
+ return parse3(markdown, options);
285
+ }
286
+ function parseBlocks(state) {
287
+ while (state.pos < state.posMax) {
288
+ const char = state.src.charCodeAt(state.pos);
289
+ if (char === CODE_NEWLINE) {
290
+ state.pos++;
291
+ continue;
292
+ }
293
+ if (char === CODE_HASH && isStartOfLine(state)) {
294
+ if (parseHeading(state))
295
+ continue;
296
+ }
297
+ if (char === CODE_BACKTICK && lookAhead(state, "```")) {
298
+ if (parseCodeBlock(state))
299
+ continue;
300
+ }
301
+ if ((char === CODE_STAR || char === CODE_MINUS || char === CODE_UNDERSCORE) && isStartOfLine(state)) {
302
+ if (parseHR(state))
303
+ continue;
304
+ }
305
+ if (char === CODE_GT && isStartOfLine(state)) {
306
+ if (parseBlockquote(state))
307
+ continue;
308
+ }
309
+ if (isListMarker(char) && isStartOfLine(state)) {
310
+ if (parseList(state))
311
+ continue;
312
+ }
313
+ if (state.options.gfm && char === CODE_PIPE && isStartOfLine(state)) {
314
+ if (parseTable(state))
315
+ continue;
316
+ }
317
+ if (parseParagraph(state))
318
+ continue;
319
+ state.pos++;
320
+ }
321
+ if (state.pending) {
322
+ pushPending(state);
323
+ }
324
+ }
325
+ function isStartOfLine(state) {
326
+ return state.pos === 0 || state.src.charCodeAt(state.pos - 1) === CODE_NEWLINE;
327
+ }
328
+ function lookAhead(state, str) {
329
+ return state.src.slice(state.pos, state.pos + str.length) === str;
330
+ }
331
+ function isListMarker(char) {
332
+ return char === CODE_STAR || char === CODE_MINUS || char === CODE_PLUS || char >= 48 && char <= 57;
333
+ }
334
+ function pushPending(state) {
335
+ if (!state.pending)
336
+ return;
337
+ state.tokens.push({
338
+ type: "text",
339
+ content: state.pending,
340
+ level: state.level
341
+ });
342
+ state.pending = "";
343
+ }
344
+ function pushToken(state, type, tag, nesting) {
345
+ pushPending(state);
346
+ if (nesting < 0)
347
+ state.level--;
348
+ const token = {
349
+ type,
350
+ tag,
351
+ nesting,
352
+ level: state.level
353
+ };
354
+ if (nesting > 0)
355
+ state.level++;
356
+ state.tokens.push(token);
357
+ return token;
358
+ }
359
+ function parseHeading(state) {
360
+ const start = state.pos;
361
+ let level = 0;
362
+ while (state.pos < state.posMax && state.src.charCodeAt(state.pos) === CODE_HASH && level < 6) {
363
+ level++;
364
+ state.pos++;
365
+ }
366
+ if (level === 0 || state.pos >= state.posMax || state.src.charCodeAt(state.pos) !== CODE_SPACE) {
367
+ state.pos = start;
368
+ return false;
369
+ }
370
+ state.pos++;
371
+ const textStart = state.pos;
372
+ let textEnd = state.pos;
373
+ while (textEnd < state.posMax && state.src.charCodeAt(textEnd) !== CODE_NEWLINE) {
374
+ textEnd++;
375
+ }
376
+ const content = state.src.slice(textStart, textEnd).trim();
377
+ const token = pushToken(state, "heading_open", `h${level}`, 1);
378
+ if (state.options.headerIds) {
379
+ token.markup = `${state.options.headerPrefix}${slugify(content)}`;
380
+ }
381
+ parseInline(state, content);
382
+ pushToken(state, "heading_close", `h${level}`, -1);
383
+ state.pos = textEnd + 1;
384
+ return true;
385
+ }
386
+ function slugify(text) {
387
+ return text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
388
+ }
389
+ function parseCodeBlock(state) {
390
+ const start = state.pos;
391
+ state.pos += 3;
392
+ const langStart = state.pos;
393
+ while (state.pos < state.posMax && state.src.charCodeAt(state.pos) !== CODE_NEWLINE) {
394
+ state.pos++;
395
+ }
396
+ const lang = state.src.slice(langStart, state.pos).trim();
397
+ state.pos++;
398
+ const codeStart = state.pos;
399
+ if (state.src.slice(state.pos, state.pos + 3) === "```") {
400
+ const token2 = pushToken(state, "fence", "code", 0);
401
+ token2.content = "";
402
+ token2.markup = lang;
403
+ state.pos += 3;
404
+ return true;
405
+ }
406
+ const closing = state.src.indexOf("\n```", state.pos);
407
+ if (closing === -1) {
408
+ state.pos = start;
409
+ return false;
410
+ }
411
+ const code = state.src.slice(codeStart, closing);
412
+ const token = pushToken(state, "fence", "code", 0);
413
+ token.content = code;
414
+ token.markup = lang;
415
+ state.pos = closing + 4;
416
+ return true;
417
+ }
418
+ function parseHR(state) {
419
+ const start = state.pos;
420
+ const marker = state.src.charCodeAt(state.pos);
421
+ let count = 0;
422
+ while (state.pos < state.posMax) {
423
+ const char = state.src.charCodeAt(state.pos);
424
+ if (char === marker)
425
+ count++;
426
+ else if (char !== CODE_SPACE && char !== CODE_NEWLINE)
427
+ break;
428
+ state.pos++;
429
+ if (char === CODE_NEWLINE)
430
+ break;
431
+ }
432
+ if (count >= 3) {
433
+ pushToken(state, "hr", "hr", 0);
434
+ return true;
435
+ }
436
+ state.pos = start;
437
+ return false;
438
+ }
439
+ function parseBlockquote(state) {
440
+ pushToken(state, "blockquote_open", "blockquote", 1);
441
+ while (state.pos < state.posMax && state.src.charCodeAt(state.pos) === CODE_GT) {
442
+ state.pos++;
443
+ if (state.src.charCodeAt(state.pos) === CODE_SPACE)
444
+ state.pos++;
445
+ const lineStart = state.pos;
446
+ let lineEnd = state.pos;
447
+ while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {
448
+ lineEnd++;
449
+ }
450
+ const content = state.src.slice(lineStart, lineEnd).trim();
451
+ if (content) {
452
+ pushToken(state, "paragraph_open", "p", 1);
453
+ parseInline(state, content);
454
+ pushToken(state, "paragraph_close", "p", -1);
455
+ }
456
+ state.pos = lineEnd + 1;
457
+ }
458
+ pushToken(state, "blockquote_close", "blockquote", -1);
459
+ return true;
460
+ }
461
+ function parseList(state) {
462
+ const firstChar = state.src.charCodeAt(state.pos);
463
+ const isOrdered = firstChar >= 48 && firstChar <= 57;
464
+ if (!isOrdered) {
465
+ const nextChar = state.src.charCodeAt(state.pos + 1);
466
+ if (nextChar === firstChar || nextChar !== CODE_SPACE) {
467
+ return false;
468
+ }
469
+ }
470
+ pushToken(state, isOrdered ? "ordered_list_open" : "bullet_list_open", isOrdered ? "ol" : "ul", 1);
471
+ while (state.pos < state.posMax) {
472
+ const char = state.src.charCodeAt(state.pos);
473
+ if (isOrdered) {
474
+ let num = 0;
475
+ while (state.src.charCodeAt(state.pos) >= 48 && state.src.charCodeAt(state.pos) <= 57) {
476
+ state.pos++;
477
+ num++;
478
+ }
479
+ if (num === 0 || state.src.charCodeAt(state.pos) !== 46)
480
+ break;
481
+ state.pos++;
482
+ } else {
483
+ if (char !== CODE_STAR && char !== CODE_MINUS && char !== CODE_PLUS)
484
+ break;
485
+ if (state.src.charCodeAt(state.pos + 1) === char)
486
+ break;
487
+ state.pos++;
488
+ }
489
+ if (state.src.charCodeAt(state.pos) !== CODE_SPACE)
490
+ break;
491
+ state.pos++;
492
+ const itemStart = state.pos;
493
+ let itemEnd = state.pos;
494
+ while (itemEnd < state.posMax && state.src.charCodeAt(itemEnd) !== CODE_NEWLINE) {
495
+ itemEnd++;
496
+ }
497
+ let content = state.src.slice(itemStart, itemEnd).trim();
498
+ const taskMatch = content.match(/^\[([ x])\]\s+(.+)/i);
499
+ if (taskMatch) {
500
+ const checked = taskMatch[1].toLowerCase() === "x";
501
+ content = taskMatch[2];
502
+ const token = pushToken(state, "list_item_open", "li", 1);
503
+ token.markup = checked ? "checked" : "unchecked";
504
+ parseInline(state, content);
505
+ pushToken(state, "list_item_close", "li", -1);
506
+ } else {
507
+ pushToken(state, "list_item_open", "li", 1);
508
+ parseInline(state, content);
509
+ pushToken(state, "list_item_close", "li", -1);
510
+ }
511
+ state.pos = itemEnd + 1;
512
+ const nextChar = state.src.charCodeAt(state.pos);
513
+ if (!isListMarker(nextChar))
514
+ break;
515
+ }
516
+ pushToken(state, isOrdered ? "ordered_list_close" : "bullet_list_close", isOrdered ? "ol" : "ul", -1);
517
+ return true;
518
+ }
519
+ function splitTableCells(line) {
520
+ const cells = [];
521
+ let current = "";
522
+ let inCode = false;
523
+ let escaped = false;
524
+ for (let i = 0;i < line.length; i++) {
525
+ const char = line[i];
526
+ if (escaped) {
527
+ current += char;
528
+ escaped = false;
529
+ continue;
530
+ }
531
+ if (char === "\\") {
532
+ current += char;
533
+ escaped = true;
534
+ continue;
535
+ }
536
+ if (char === "`") {
537
+ inCode = !inCode;
538
+ current += char;
539
+ continue;
540
+ }
541
+ if (char === "|" && !inCode) {
542
+ cells.push(current.trim());
543
+ current = "";
544
+ continue;
545
+ }
546
+ current += char;
547
+ }
548
+ if (current || cells.length > 0) {
549
+ cells.push(current.trim());
550
+ }
551
+ return cells.slice(1, -1);
552
+ }
553
+ function parseTable(state) {
554
+ const start = state.pos;
555
+ let lineEnd = state.pos;
556
+ while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {
557
+ lineEnd++;
558
+ }
559
+ const headerLine = state.src.slice(state.pos, lineEnd);
560
+ if (!headerLine.startsWith("|") || !headerLine.trim().endsWith("|")) {
561
+ return false;
562
+ }
563
+ state.pos = lineEnd + 1;
564
+ lineEnd = state.pos;
565
+ while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {
566
+ lineEnd++;
567
+ }
568
+ const alignLine = state.src.slice(state.pos, lineEnd);
569
+ if (!/^\|(?:\s*:?-+:?\s*\|)+$/.test(alignLine.trim())) {
570
+ state.pos = start;
571
+ return false;
572
+ }
573
+ const alignCells = alignLine.split("|").slice(1, -1);
574
+ const align = alignCells.map((cell) => {
575
+ const trimmed = cell.trim();
576
+ if (trimmed.startsWith(":") && trimmed.endsWith(":"))
577
+ return "center";
578
+ if (trimmed.endsWith(":"))
579
+ return "right";
580
+ if (trimmed.startsWith(":"))
581
+ return "left";
582
+ return null;
583
+ });
584
+ state.pos = lineEnd + 1;
585
+ const headerCells = splitTableCells(headerLine);
586
+ pushToken(state, "table_open", "table", 1);
587
+ pushToken(state, "thead_open", "thead", 1);
588
+ pushToken(state, "tr_open", "tr", 1);
589
+ for (let i = 0;i < headerCells.length; i++) {
590
+ const token = pushToken(state, "th_open", "th", 1);
591
+ if (align[i]) {
592
+ token.markup = align[i] ?? undefined;
593
+ }
594
+ parseInline(state, headerCells[i]);
595
+ pushToken(state, "th_close", "th", -1);
596
+ }
597
+ pushToken(state, "tr_close", "tr", -1);
598
+ pushToken(state, "thead_close", "thead", -1);
599
+ pushToken(state, "tbody_open", "tbody", 1);
600
+ while (state.pos < state.posMax) {
601
+ lineEnd = state.pos;
602
+ while (lineEnd < state.posMax && state.src.charCodeAt(lineEnd) !== CODE_NEWLINE) {
603
+ lineEnd++;
604
+ }
605
+ const rowLine = state.src.slice(state.pos, lineEnd).trim();
606
+ if (!rowLine.startsWith("|") || !rowLine.endsWith("|")) {
607
+ break;
608
+ }
609
+ const cells = splitTableCells(rowLine);
610
+ pushToken(state, "tr_open", "tr", 1);
611
+ for (let i = 0;i < cells.length; i++) {
612
+ const token = pushToken(state, "td_open", "td", 1);
613
+ if (align[i]) {
614
+ token.markup = align[i] ?? undefined;
615
+ }
616
+ parseInline(state, cells[i]);
617
+ pushToken(state, "td_close", "td", -1);
618
+ }
619
+ pushToken(state, "tr_close", "tr", -1);
620
+ state.pos = lineEnd + 1;
621
+ }
622
+ pushToken(state, "tbody_close", "tbody", -1);
623
+ pushToken(state, "table_close", "table", -1);
624
+ return true;
625
+ }
626
+ function parseParagraph(state) {
627
+ const start = state.pos;
628
+ let end = state.pos;
629
+ while (end < state.posMax) {
630
+ if (state.src.charCodeAt(end) === CODE_NEWLINE) {
631
+ if (end + 1 < state.posMax && state.src.charCodeAt(end + 1) === CODE_NEWLINE) {
632
+ break;
633
+ }
634
+ }
635
+ end++;
636
+ }
637
+ const content = state.src.slice(start, end).trim();
638
+ if (!content) {
639
+ state.pos = end + 1;
640
+ return false;
641
+ }
642
+ pushToken(state, "paragraph_open", "p", 1);
643
+ parseInline(state, content);
644
+ pushToken(state, "paragraph_close", "p", -1);
645
+ state.pos = end + 1;
646
+ return true;
647
+ }
648
+ function parseInline(state, content) {
649
+ const savedSrc = state.src;
650
+ const savedPos = state.pos;
651
+ const savedPosMax = state.posMax;
652
+ state.src = content;
653
+ state.pos = 0;
654
+ state.posMax = content.length;
655
+ while (state.pos < state.posMax) {
656
+ const char = state.src.charCodeAt(state.pos);
657
+ if ((char === CODE_STAR || char === CODE_UNDERSCORE) && state.src.charCodeAt(state.pos + 1) === char) {
658
+ if (scanStrong(state, char))
659
+ continue;
660
+ }
661
+ if (char === CODE_STAR || char === CODE_UNDERSCORE) {
662
+ if (scanEmphasisDirect(state, char))
663
+ continue;
664
+ }
665
+ if (char === CODE_BACKTICK) {
666
+ if (scanCode(state))
667
+ continue;
668
+ }
669
+ if (char === CODE_LBRACKET) {
670
+ if (scanLink(state))
671
+ continue;
672
+ }
673
+ if (char === CODE_BANG && state.src.charCodeAt(state.pos + 1) === CODE_LBRACKET) {
674
+ if (scanImage(state))
675
+ continue;
676
+ }
677
+ if (state.options.gfm && char === CODE_TILDE && state.src.charCodeAt(state.pos + 1) === CODE_TILDE) {
678
+ if (scanStrikethrough(state))
679
+ continue;
680
+ }
681
+ if (state.options.breaks && char === CODE_NEWLINE) {
682
+ pushPending(state);
683
+ pushToken(state, "br", "br", 0);
684
+ state.pos++;
685
+ continue;
686
+ }
687
+ state.pending += state.src[state.pos];
688
+ state.pos++;
689
+ }
690
+ if (state.pending)
691
+ pushPending(state);
692
+ state.src = savedSrc;
693
+ state.pos = savedPos;
694
+ state.posMax = savedPosMax;
695
+ }
696
+ function scanStrong(state, marker) {
697
+ const start = state.pos;
698
+ const markerStr = String.fromCharCode(marker);
699
+ const searchStart = start + 2;
700
+ if (marker === 95) {
701
+ const prevChar = start > 0 ? state.src.charCodeAt(start - 1) : 0;
702
+ if (isAlphanumeric(prevChar) || prevChar === 95) {
703
+ return false;
704
+ }
705
+ }
706
+ const closePos = state.src.indexOf(markerStr + markerStr, searchStart);
707
+ if (closePos === -1) {
708
+ return false;
709
+ }
710
+ if (marker === 95) {
711
+ const nextChar = closePos + 2 < state.posMax ? state.src.charCodeAt(closePos + 2) : 0;
712
+ if (isAlphanumeric(nextChar) || nextChar === 95) {
713
+ return false;
714
+ }
715
+ }
716
+ pushPending(state);
717
+ const text = state.src.substring(searchStart, closePos);
718
+ pushToken(state, "strong_open", "strong", 1);
719
+ parseInline(state, text);
720
+ pushToken(state, "strong_close", "strong", -1);
721
+ state.pos = closePos + 2;
722
+ return true;
723
+ }
724
+ function scanEmphasisDirect(state, marker) {
725
+ const start = state.pos;
726
+ const markerStr = String.fromCharCode(marker);
727
+ const searchStart = start + 1;
728
+ if (marker === 95) {
729
+ const prevChar = start > 0 ? state.src.charCodeAt(start - 1) : 0;
730
+ if (isAlphanumeric(prevChar) || prevChar === 95) {
731
+ return false;
732
+ }
733
+ }
734
+ let closePos = state.src.indexOf(markerStr, searchStart);
735
+ while (closePos !== -1) {
736
+ if (state.src.charCodeAt(closePos + 1) === marker) {
737
+ closePos = state.src.indexOf(markerStr, closePos + 2);
738
+ continue;
739
+ }
740
+ if (marker === 95) {
741
+ const nextChar = closePos + 1 < state.posMax ? state.src.charCodeAt(closePos + 1) : 0;
742
+ if (isAlphanumeric(nextChar) || nextChar === 95) {
743
+ closePos = state.src.indexOf(markerStr, closePos + 1);
744
+ continue;
745
+ }
746
+ }
747
+ break;
748
+ }
749
+ if (closePos === -1 || closePos === searchStart) {
750
+ return false;
751
+ }
752
+ pushPending(state);
753
+ const text = state.src.substring(searchStart, closePos);
754
+ pushToken(state, "em_open", "em", 1);
755
+ parseInline(state, text);
756
+ pushToken(state, "em_close", "em", -1);
757
+ state.pos = closePos + 1;
758
+ return true;
759
+ }
760
+ function scanCode(state) {
761
+ const start = state.pos;
762
+ state.pos++;
763
+ const codeStart = state.pos;
764
+ const closeIdx = state.src.indexOf("`", state.pos);
765
+ if (closeIdx === -1) {
766
+ state.pos = start;
767
+ return false;
768
+ }
769
+ const code = state.src.slice(codeStart, closeIdx);
770
+ pushToken(state, "code_inline", "code", 0).content = code;
771
+ state.pos = closeIdx + 1;
772
+ return true;
773
+ }
774
+ function scanLink(state) {
775
+ const start = state.pos;
776
+ state.pos++;
777
+ const textStart = state.pos;
778
+ const textEnd = state.src.indexOf("]", state.pos);
779
+ if (textEnd === -1) {
780
+ state.pos = start;
781
+ return false;
782
+ }
783
+ if (state.src.charCodeAt(textEnd + 1) !== 40) {
784
+ state.pos = start;
785
+ return false;
786
+ }
787
+ const urlStart = textEnd + 2;
788
+ const urlEnd = state.src.indexOf(")", urlStart);
789
+ if (urlEnd === -1) {
790
+ state.pos = start;
791
+ return false;
792
+ }
793
+ pushPending(state);
794
+ const text = state.src.slice(textStart, textEnd);
795
+ const urlPart = state.src.slice(urlStart, urlEnd);
796
+ let url = urlPart;
797
+ let title = "";
798
+ const titleMatch = urlPart.match(/^(.*?)\s+["'](.*)["']$/);
799
+ if (titleMatch) {
800
+ url = titleMatch[1];
801
+ title = titleMatch[2];
802
+ }
803
+ const token = pushToken(state, "link_open", "a", 1);
804
+ token.markup = url;
805
+ if (title) {
806
+ token.content = title;
807
+ }
808
+ parseInline(state, text);
809
+ pushToken(state, "link_close", "a", -1);
810
+ state.pos = urlEnd + 1;
811
+ return true;
812
+ }
813
+ function scanImage(state) {
814
+ const start = state.pos;
815
+ state.pos += 2;
816
+ const altStart = state.pos;
817
+ const altEnd = state.src.indexOf("]", state.pos);
818
+ if (altEnd === -1) {
819
+ state.pos = start;
820
+ return false;
821
+ }
822
+ if (state.src.charCodeAt(altEnd + 1) !== 40) {
823
+ state.pos = start;
824
+ return false;
825
+ }
826
+ const urlStart = altEnd + 2;
827
+ const urlEnd = state.src.indexOf(")", urlStart);
828
+ if (urlEnd === -1) {
829
+ state.pos = start;
830
+ return false;
831
+ }
832
+ const alt = state.src.slice(altStart, altEnd);
833
+ const urlPart = state.src.slice(urlStart, urlEnd);
834
+ let url = urlPart;
835
+ let title = "";
836
+ const titleMatch = urlPart.match(/^(.*?)\s+["'](.*)["']$/);
837
+ if (titleMatch) {
838
+ url = titleMatch[1];
839
+ title = titleMatch[2];
840
+ }
841
+ pushToken(state, "image", "img", 0).markup = `${alt}|${url}|${title}`;
842
+ state.pos = urlEnd + 1;
843
+ return true;
844
+ }
845
+ function scanStrikethrough(state) {
846
+ const start = state.pos;
847
+ state.pos += 2;
848
+ const textStart = state.pos;
849
+ const closeIdx = state.src.indexOf("~~", state.pos);
850
+ if (closeIdx === -1) {
851
+ state.pos = start;
852
+ return false;
853
+ }
854
+ pushPending(state);
855
+ const text = state.src.slice(textStart, closeIdx);
856
+ pushToken(state, "del_open", "del", 1);
857
+ parseInline(state, text);
858
+ pushToken(state, "del_close", "del", -1);
859
+ state.pos = closeIdx + 2;
860
+ return true;
861
+ }
862
+ function renderTokens(tokens, options) {
863
+ let html = "";
864
+ for (const token of tokens) {
865
+ switch (token.type) {
866
+ case "heading_open":
867
+ if (token.markup) {
868
+ html += `<${token.tag} id="${token.markup}">`;
869
+ } else {
870
+ html += `<${token.tag}>`;
871
+ }
872
+ break;
873
+ case "heading_close":
874
+ html += `</${token.tag}>
875
+ `;
876
+ break;
877
+ case "paragraph_open":
878
+ html += "<p>";
879
+ break;
880
+ case "paragraph_close":
881
+ html += `</p>
882
+ `;
883
+ break;
884
+ case "fence":
885
+ case "code_block": {
886
+ let code = token.content || "";
887
+ const lang = token.markup || "";
888
+ if (options.highlight && lang) {
889
+ code = options.highlight(code, lang);
890
+ } else {
891
+ code = escapeHtml(code);
892
+ }
893
+ if (lang) {
894
+ html += `<pre><code class="language-${lang}">${code}</code></pre>
895
+ `;
896
+ } else {
897
+ html += `<pre><code>${code}</code></pre>
898
+ `;
899
+ }
900
+ break;
901
+ }
902
+ case "code_inline":
903
+ html += `<code>${escapeHtml(token.content || "")}</code>`;
904
+ break;
905
+ case "hr":
906
+ html += `<hr>
907
+ `;
908
+ break;
909
+ case "blockquote_open":
910
+ html += `<blockquote>
911
+ `;
912
+ break;
913
+ case "blockquote_close":
914
+ html += `</blockquote>
915
+ `;
916
+ break;
917
+ case "bullet_list_open":
918
+ html += `<ul>
919
+ `;
920
+ break;
921
+ case "bullet_list_close":
922
+ html += `</ul>
923
+ `;
924
+ break;
925
+ case "ordered_list_open":
926
+ html += `<ol>
927
+ `;
928
+ break;
929
+ case "ordered_list_close":
930
+ html += `</ol>
931
+ `;
932
+ break;
933
+ case "list_item_open":
934
+ html += "<li>";
935
+ if (token.markup === "checked") {
936
+ html += '<input type="checkbox" checked disabled> ';
937
+ } else if (token.markup === "unchecked") {
938
+ html += '<input type="checkbox" disabled> ';
939
+ }
940
+ break;
941
+ case "list_item_close":
942
+ html += `</li>
943
+ `;
944
+ break;
945
+ case "table_open":
946
+ html += `<table>
947
+ `;
948
+ break;
949
+ case "table_close":
950
+ html += `</table>
951
+ `;
952
+ break;
953
+ case "thead_open":
954
+ html += `<thead>
955
+ `;
956
+ break;
957
+ case "thead_close":
958
+ html += `</thead>
959
+ `;
960
+ break;
961
+ case "tbody_open":
962
+ html += `<tbody>
963
+ `;
964
+ break;
965
+ case "tbody_close":
966
+ html += `</tbody>
967
+ `;
968
+ break;
969
+ case "tr_open":
970
+ html += `<tr>
971
+ `;
972
+ break;
973
+ case "tr_close":
974
+ html += `</tr>
975
+ `;
976
+ break;
977
+ case "th_open":
978
+ if (token.markup) {
979
+ html += `<th align="${token.markup}">`;
980
+ } else {
981
+ html += "<th>";
982
+ }
983
+ break;
984
+ case "th_close":
985
+ html += `</th>
986
+ `;
987
+ break;
988
+ case "td_open":
989
+ if (token.markup) {
990
+ html += `<td align="${token.markup}">`;
991
+ } else {
992
+ html += "<td>";
993
+ }
994
+ break;
995
+ case "td_close":
996
+ html += `</td>
997
+ `;
998
+ break;
999
+ case "strong_open":
1000
+ html += "<strong>";
1001
+ break;
1002
+ case "strong_close":
1003
+ html += "</strong>";
1004
+ break;
1005
+ case "em_open":
1006
+ html += "<em>";
1007
+ break;
1008
+ case "em_close":
1009
+ html += "</em>";
1010
+ break;
1011
+ case "del_open":
1012
+ html += "<del>";
1013
+ break;
1014
+ case "del_close":
1015
+ html += "</del>";
1016
+ break;
1017
+ case "br":
1018
+ html += "<br>";
1019
+ break;
1020
+ case "link_open":
1021
+ if (token.content) {
1022
+ html += `<a href="${escapeHtml(token.markup || "")}" title="${escapeHtml(token.content)}">`;
1023
+ } else {
1024
+ html += `<a href="${escapeHtml(token.markup || "")}">`;
1025
+ }
1026
+ break;
1027
+ case "link_close":
1028
+ html += "</a>";
1029
+ break;
1030
+ case "image": {
1031
+ const [alt, url, imageTitle] = (token.markup || "||").split("|");
1032
+ if (imageTitle) {
1033
+ html += `<img src="${escapeHtml(url)}" alt="${escapeHtml(alt)}" title="${escapeHtml(imageTitle)}">`;
1034
+ } else {
1035
+ html += `<img src="${escapeHtml(url)}" alt="${escapeHtml(alt)}">`;
1036
+ }
1037
+ break;
1038
+ }
1039
+ case "text":
1040
+ html += escapeHtml(token.content || "");
1041
+ break;
1042
+ }
1043
+ }
1044
+ return html;
1045
+ }
1046
+ var CHAR_AMP = 38;
1047
+ var CHAR_LT = 60;
1048
+ var CHAR_GT = 62;
1049
+ var CHAR_QUOT = 34;
1050
+ var CHAR_APOS = 39;
1051
+ function escapeHtml(text) {
1052
+ const len = text.length;
1053
+ let lastPos = 0;
1054
+ let needsEscape = false;
1055
+ for (let i = 0;i < len; i++) {
1056
+ const code = text.charCodeAt(i);
1057
+ if (code === CHAR_AMP || code === CHAR_LT || code === CHAR_GT || code === CHAR_QUOT || code === CHAR_APOS) {
1058
+ needsEscape = true;
1059
+ break;
1060
+ }
1061
+ }
1062
+ if (!needsEscape)
1063
+ return text;
1064
+ const parts = [];
1065
+ for (let i = 0;i < len; i++) {
1066
+ const code = text.charCodeAt(i);
1067
+ let replacement = null;
1068
+ switch (code) {
1069
+ case CHAR_AMP:
1070
+ replacement = "&amp;";
1071
+ break;
1072
+ case CHAR_LT:
1073
+ replacement = "&lt;";
1074
+ break;
1075
+ case CHAR_GT:
1076
+ replacement = "&gt;";
1077
+ break;
1078
+ case CHAR_QUOT:
1079
+ replacement = "&quot;";
1080
+ break;
1081
+ case CHAR_APOS:
1082
+ replacement = "&#39;";
1083
+ break;
1084
+ }
1085
+ if (replacement) {
1086
+ if (i > lastPos) {
1087
+ parts.push(text.substring(lastPos, i));
1088
+ }
1089
+ parts.push(replacement);
1090
+ lastPos = i + 1;
1091
+ }
1092
+ }
1093
+ if (lastPos < len) {
1094
+ parts.push(text.substring(lastPos));
1095
+ }
1096
+ return parts.join("");
1097
+ }
1098
+
1099
+ // src/index.ts
1100
+ function parseMarkdownWithFrontmatter(content, options) {
1101
+ const { data, content: markdown } = parse2(content);
1102
+ const html = parse3(markdown, options);
1103
+ return {
1104
+ data,
1105
+ content: markdown,
1106
+ html
1107
+ };
1108
+ }
1109
+ var markdownParser = {
1110
+ parseFrontmatter: parse2,
1111
+ parseMarkdown: parse3,
1112
+ parseMarkdownWithFrontmatter
1113
+ };
1114
+ var src_default = markdownParser;
1115
+ export {
1116
+ exports_yaml as yaml,
1117
+ stringify as stringifyYaml,
1118
+ stringify2 as stringifyFrontmatter,
1119
+ parse as parseYaml,
1120
+ parseSync,
1121
+ parseMarkdownWithFrontmatter,
1122
+ parseSync as parseMarkdownSync,
1123
+ parse3 as parseMarkdown,
1124
+ parse2 as parseFrontmatter,
1125
+ parse3 as parse,
1126
+ exports_frontmatter as frontmatter,
1127
+ src_default as default
1128
+ };
1129
+
1130
+ //# debugId=4EC4EE35429AE4D764756E2164756E21