@changerawr/markdown 1.0.4 → 1.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/LICENSE +21 -0
- package/README.md +129 -11
- package/dist/index.d.mts +63 -47
- package/dist/index.d.ts +63 -47
- package/dist/index.js +677 -448
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +661 -449
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +2 -37
- package/dist/react/index.d.ts +2 -37
- package/dist/react/index.js +604 -432
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +604 -433
- package/dist/react/index.mjs.map +1 -1
- package/dist/standalone.browser.js +2722 -0
- package/dist/standalone.d.mts +2 -37
- package/dist/standalone.d.ts +2 -37
- package/dist/standalone.js +604 -431
- package/dist/standalone.js.map +1 -1
- package/dist/standalone.mjs +604 -431
- package/dist/standalone.mjs.map +1 -1
- package/dist/tailwind/index.d.mts +6 -2
- package/dist/tailwind/index.d.ts +6 -2
- package/dist/tailwind/index.js +204 -95
- package/dist/tailwind/index.js.map +1 -1
- package/dist/tailwind/index.mjs +204 -95
- package/dist/tailwind/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use client";
|
|
2
1
|
"use strict";
|
|
3
2
|
var __create = Object.create;
|
|
4
3
|
var __defProp = Object.defineProperty;
|
|
@@ -32,17 +31,33 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
31
|
var index_exports = {};
|
|
33
32
|
__export(index_exports, {
|
|
34
33
|
AlertExtension: () => AlertExtension,
|
|
34
|
+
BlockquoteExtension: () => BlockquoteExtension,
|
|
35
|
+
BoldExtension: () => BoldExtension,
|
|
35
36
|
ButtonExtension: () => ButtonExtension,
|
|
36
37
|
ChangerawrMarkdown: () => ChangerawrMarkdown,
|
|
38
|
+
CodeBlockExtension: () => CodeBlockExtension,
|
|
39
|
+
CoreExtensions: () => CoreExtensions,
|
|
37
40
|
EmbedExtension: () => EmbedExtension,
|
|
41
|
+
HeadingExtension: () => HeadingExtension,
|
|
42
|
+
HorizontalRuleExtension: () => HorizontalRuleExtension,
|
|
43
|
+
ImageExtension: () => ImageExtension,
|
|
44
|
+
InlineCodeExtension: () => InlineCodeExtension,
|
|
45
|
+
ItalicExtension: () => ItalicExtension,
|
|
46
|
+
LineBreakExtension: () => LineBreakExtension,
|
|
47
|
+
LinkExtension: () => LinkExtension,
|
|
48
|
+
ListExtension: () => ListExtension,
|
|
38
49
|
Logger: () => Logger,
|
|
39
50
|
MarkdownParser: () => MarkdownParser,
|
|
40
51
|
MarkdownRenderer: () => MarkdownRenderer,
|
|
52
|
+
ParagraphExtension: () => ParagraphExtension,
|
|
41
53
|
PerformanceTimer: () => PerformanceTimer,
|
|
54
|
+
TaskListExtension: () => TaskListExtension,
|
|
55
|
+
TextExtension: () => TextExtension,
|
|
42
56
|
astToJSONString: () => astToJSONString,
|
|
43
57
|
astToTokens: () => astToTokens,
|
|
44
58
|
basicSanitize: () => basicSanitize,
|
|
45
59
|
compareTokens: () => compareTokens,
|
|
60
|
+
createCoreOnlyEngine: () => createCoreOnlyEngine,
|
|
46
61
|
createCumEngine: () => createCumEngine,
|
|
47
62
|
createCustomEngine: () => createCustomEngine,
|
|
48
63
|
createDebugEngine: () => createDebugEngine,
|
|
@@ -96,39 +111,56 @@ var MarkdownParser = class {
|
|
|
96
111
|
constructor(config) {
|
|
97
112
|
this.rules = [];
|
|
98
113
|
this.warnings = [];
|
|
99
|
-
this.config =
|
|
114
|
+
this.config = {
|
|
115
|
+
debugMode: false,
|
|
116
|
+
maxIterations: 1e4,
|
|
117
|
+
validateMarkdown: false,
|
|
118
|
+
...config
|
|
119
|
+
};
|
|
100
120
|
}
|
|
101
121
|
addRule(rule) {
|
|
102
122
|
this.rules.push(rule);
|
|
103
123
|
this.rules.sort((a, b) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
124
|
+
const aFeatureExtension = ["alert", "button", "embed"].includes(a.name);
|
|
125
|
+
const bFeatureExtension = ["alert", "button", "embed"].includes(b.name);
|
|
126
|
+
if (aFeatureExtension && !bFeatureExtension) return -1;
|
|
127
|
+
if (!aFeatureExtension && bFeatureExtension) return 1;
|
|
128
|
+
const aCoreExtension = ["text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(a.name);
|
|
129
|
+
const bCoreExtension = ["text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(b.name);
|
|
130
|
+
if (aCoreExtension && !bCoreExtension) return -1;
|
|
131
|
+
if (!aCoreExtension && bCoreExtension) return 1;
|
|
132
|
+
if (a.name === "image" && b.name === "link") return -1;
|
|
133
|
+
if (a.name === "link" && b.name === "image") return 1;
|
|
134
|
+
if (a.name === "task-item" && b.name === "list-item") return -1;
|
|
135
|
+
if (a.name === "list-item" && b.name === "task-item") return 1;
|
|
136
|
+
if (a.name === "codeblock" && b.name === "code") return -1;
|
|
137
|
+
if (a.name === "code" && b.name === "codeblock") return 1;
|
|
138
|
+
if (a.name === "bold" && b.name === "italic") return -1;
|
|
139
|
+
if (a.name === "italic" && b.name === "bold") return 1;
|
|
110
140
|
return a.name.localeCompare(b.name);
|
|
111
141
|
});
|
|
112
142
|
}
|
|
113
|
-
setupDefaultRulesIfEmpty() {
|
|
114
|
-
const hasDefaultRules = this.rules.some(
|
|
115
|
-
(rule) => !["alert", "button", "embed"].includes(rule.name)
|
|
116
|
-
);
|
|
117
|
-
if (!hasDefaultRules) {
|
|
118
|
-
this.setupDefaultRules();
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
143
|
hasRule(name) {
|
|
122
144
|
return this.rules.some((rule) => rule.name === name);
|
|
123
145
|
}
|
|
124
146
|
parse(markdown3) {
|
|
125
147
|
this.warnings = [];
|
|
126
|
-
|
|
148
|
+
if (!markdown3.trim()) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
if (this.rules.length === 0) {
|
|
152
|
+
this.warnings.push("No parse rules registered - consider using CoreExtensions");
|
|
153
|
+
return [{
|
|
154
|
+
type: "text",
|
|
155
|
+
content: markdown3,
|
|
156
|
+
raw: markdown3
|
|
157
|
+
}];
|
|
158
|
+
}
|
|
127
159
|
const processedMarkdown = this.preprocessMarkdown(markdown3);
|
|
128
160
|
const tokens = [];
|
|
129
161
|
let remaining = processedMarkdown;
|
|
130
162
|
let iterationCount = 0;
|
|
131
|
-
const maxIterations = this.config.maxIterations ||
|
|
163
|
+
const maxIterations = this.config.maxIterations || 1e4;
|
|
132
164
|
while (remaining.length > 0 && iterationCount < maxIterations) {
|
|
133
165
|
iterationCount++;
|
|
134
166
|
let matched = false;
|
|
@@ -217,9 +249,6 @@ var MarkdownParser = class {
|
|
|
217
249
|
clearWarnings() {
|
|
218
250
|
this.warnings = [];
|
|
219
251
|
}
|
|
220
|
-
getIterationCount() {
|
|
221
|
-
return 0;
|
|
222
|
-
}
|
|
223
252
|
preprocessMarkdown(markdown3) {
|
|
224
253
|
if (this.config.validateMarkdown) {
|
|
225
254
|
this.validateMarkdown(markdown3);
|
|
@@ -274,161 +303,6 @@ var MarkdownParser = class {
|
|
|
274
303
|
}
|
|
275
304
|
return processed;
|
|
276
305
|
}
|
|
277
|
-
setupDefaultRules() {
|
|
278
|
-
this.addRule({
|
|
279
|
-
name: "heading",
|
|
280
|
-
pattern: /^(#{1,6})\s+(.+)$/m,
|
|
281
|
-
render: (match) => ({
|
|
282
|
-
type: "heading",
|
|
283
|
-
content: match[2]?.trim() || "",
|
|
284
|
-
raw: match[0] || "",
|
|
285
|
-
attributes: {
|
|
286
|
-
level: String(match[1]?.length || 1)
|
|
287
|
-
}
|
|
288
|
-
})
|
|
289
|
-
});
|
|
290
|
-
this.addRule({
|
|
291
|
-
name: "codeblock",
|
|
292
|
-
pattern: /```(\w+)?\s*\n([\s\S]*?)\n```/,
|
|
293
|
-
render: (match) => ({
|
|
294
|
-
type: "codeblock",
|
|
295
|
-
content: match[2] || "",
|
|
296
|
-
raw: match[0] || "",
|
|
297
|
-
attributes: {
|
|
298
|
-
language: match[1] || "text"
|
|
299
|
-
}
|
|
300
|
-
})
|
|
301
|
-
});
|
|
302
|
-
this.addRule({
|
|
303
|
-
name: "hard-break-backslash",
|
|
304
|
-
pattern: /\\\s*\n/,
|
|
305
|
-
render: (match) => ({
|
|
306
|
-
type: "line-break",
|
|
307
|
-
content: "",
|
|
308
|
-
raw: match[0] || ""
|
|
309
|
-
})
|
|
310
|
-
});
|
|
311
|
-
this.addRule({
|
|
312
|
-
name: "hard-break-spaces",
|
|
313
|
-
pattern: / +\n/,
|
|
314
|
-
render: (match) => ({
|
|
315
|
-
type: "line-break",
|
|
316
|
-
content: "",
|
|
317
|
-
raw: match[0] || ""
|
|
318
|
-
})
|
|
319
|
-
});
|
|
320
|
-
this.addRule({
|
|
321
|
-
name: "paragraph-break",
|
|
322
|
-
pattern: /\n\s*\n/,
|
|
323
|
-
render: (match) => ({
|
|
324
|
-
type: "paragraph-break",
|
|
325
|
-
content: "",
|
|
326
|
-
raw: match[0] || ""
|
|
327
|
-
})
|
|
328
|
-
});
|
|
329
|
-
this.addRule({
|
|
330
|
-
name: "bold",
|
|
331
|
-
pattern: /\*\*((?:(?!\*\*).)+)\*\*/,
|
|
332
|
-
render: (match) => ({
|
|
333
|
-
type: "bold",
|
|
334
|
-
content: match[1] || "",
|
|
335
|
-
raw: match[0] || ""
|
|
336
|
-
})
|
|
337
|
-
});
|
|
338
|
-
this.addRule({
|
|
339
|
-
name: "italic",
|
|
340
|
-
pattern: /\*((?:(?!\*).)+)\*/,
|
|
341
|
-
render: (match) => ({
|
|
342
|
-
type: "italic",
|
|
343
|
-
content: match[1] || "",
|
|
344
|
-
raw: match[0] || ""
|
|
345
|
-
})
|
|
346
|
-
});
|
|
347
|
-
this.addRule({
|
|
348
|
-
name: "code",
|
|
349
|
-
pattern: /`([^`]+)`/,
|
|
350
|
-
render: (match) => ({
|
|
351
|
-
type: "code",
|
|
352
|
-
content: match[1] || "",
|
|
353
|
-
raw: match[0] || ""
|
|
354
|
-
})
|
|
355
|
-
});
|
|
356
|
-
this.addRule({
|
|
357
|
-
name: "image",
|
|
358
|
-
pattern: /!\[([^\]]*)\]\(([^)]+?)(?:\s+"([^"]+)")?\)/,
|
|
359
|
-
render: (match) => ({
|
|
360
|
-
type: "image",
|
|
361
|
-
content: match[1] || "",
|
|
362
|
-
raw: match[0] || "",
|
|
363
|
-
attributes: {
|
|
364
|
-
alt: match[1] || "",
|
|
365
|
-
src: match[2] || "",
|
|
366
|
-
title: match[3] || ""
|
|
367
|
-
}
|
|
368
|
-
})
|
|
369
|
-
});
|
|
370
|
-
this.addRule({
|
|
371
|
-
name: "link",
|
|
372
|
-
pattern: /\[([^\]]+)\]\(([^)]+)\)/,
|
|
373
|
-
render: (match) => ({
|
|
374
|
-
type: "link",
|
|
375
|
-
content: match[1] || "",
|
|
376
|
-
raw: match[0] || "",
|
|
377
|
-
attributes: {
|
|
378
|
-
href: match[2] || ""
|
|
379
|
-
}
|
|
380
|
-
})
|
|
381
|
-
});
|
|
382
|
-
this.addRule({
|
|
383
|
-
name: "task-list",
|
|
384
|
-
pattern: /^(\s*)-\s*\[([ xX])\]\s*(.+)$/m,
|
|
385
|
-
render: (match) => ({
|
|
386
|
-
type: "task-item",
|
|
387
|
-
content: match[3] || "",
|
|
388
|
-
raw: match[0] || "",
|
|
389
|
-
attributes: {
|
|
390
|
-
checked: String((match[2] || "").toLowerCase() === "x")
|
|
391
|
-
}
|
|
392
|
-
})
|
|
393
|
-
});
|
|
394
|
-
this.addRule({
|
|
395
|
-
name: "list",
|
|
396
|
-
pattern: /^(\s*)[-*+]\s+(.+)$/m,
|
|
397
|
-
render: (match) => ({
|
|
398
|
-
type: "list-item",
|
|
399
|
-
content: match[2] || "",
|
|
400
|
-
raw: match[0] || ""
|
|
401
|
-
})
|
|
402
|
-
});
|
|
403
|
-
this.addRule({
|
|
404
|
-
name: "blockquote",
|
|
405
|
-
pattern: /^>\s+(.+)$/m,
|
|
406
|
-
render: (match) => ({
|
|
407
|
-
type: "blockquote",
|
|
408
|
-
content: match[1] || "",
|
|
409
|
-
raw: match[0] || ""
|
|
410
|
-
})
|
|
411
|
-
});
|
|
412
|
-
this.addRule({
|
|
413
|
-
name: "hr",
|
|
414
|
-
pattern: /^---$/m,
|
|
415
|
-
render: (match) => ({
|
|
416
|
-
type: "hr",
|
|
417
|
-
content: "",
|
|
418
|
-
raw: match[0] || ""
|
|
419
|
-
})
|
|
420
|
-
});
|
|
421
|
-
this.addRule({
|
|
422
|
-
name: "soft-break",
|
|
423
|
-
pattern: /\n/,
|
|
424
|
-
render: (match) => ({
|
|
425
|
-
type: "soft-break",
|
|
426
|
-
content: " ",
|
|
427
|
-
// Convert to space for inline text
|
|
428
|
-
raw: match[0] || ""
|
|
429
|
-
})
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
306
|
};
|
|
433
307
|
|
|
434
308
|
// src/utils.ts
|
|
@@ -747,7 +621,6 @@ var MarkdownRenderer = class {
|
|
|
747
621
|
debugMode: false,
|
|
748
622
|
...config
|
|
749
623
|
};
|
|
750
|
-
this.setupDefaultRules();
|
|
751
624
|
}
|
|
752
625
|
addRule(rule) {
|
|
753
626
|
this.rules.set(rule.type, rule);
|
|
@@ -757,28 +630,20 @@ var MarkdownRenderer = class {
|
|
|
757
630
|
}
|
|
758
631
|
render(tokens) {
|
|
759
632
|
this.warnings = [];
|
|
760
|
-
const
|
|
633
|
+
const tokensWithFormat = tokens.map((token) => ({
|
|
634
|
+
...token,
|
|
635
|
+
attributes: {
|
|
636
|
+
...token.attributes,
|
|
637
|
+
format: this.config.format
|
|
638
|
+
}
|
|
639
|
+
}));
|
|
640
|
+
const htmlParts = tokensWithFormat.map((token) => this.renderToken(token));
|
|
761
641
|
const combinedHtml = htmlParts.join("");
|
|
762
642
|
if (this.config.sanitize && !this.config.allowUnsafeHtml) {
|
|
763
643
|
return sanitizeHtml(combinedHtml);
|
|
764
644
|
}
|
|
765
645
|
return combinedHtml;
|
|
766
646
|
}
|
|
767
|
-
getWarnings() {
|
|
768
|
-
return [...this.warnings];
|
|
769
|
-
}
|
|
770
|
-
getConfig() {
|
|
771
|
-
return { ...this.config };
|
|
772
|
-
}
|
|
773
|
-
updateConfig(config) {
|
|
774
|
-
this.config = { ...this.config, ...config };
|
|
775
|
-
}
|
|
776
|
-
setDebugMode(enabled) {
|
|
777
|
-
this.config.debugMode = enabled;
|
|
778
|
-
}
|
|
779
|
-
clearWarnings() {
|
|
780
|
-
this.warnings = [];
|
|
781
|
-
}
|
|
782
647
|
renderToken(token) {
|
|
783
648
|
const rule = this.rules.get(token.type);
|
|
784
649
|
if (rule) {
|
|
@@ -790,9 +655,6 @@ var MarkdownRenderer = class {
|
|
|
790
655
|
return this.createErrorBlock(`Render error for ${token.type}: ${errorMessage}`);
|
|
791
656
|
}
|
|
792
657
|
}
|
|
793
|
-
if (token.type === "text") {
|
|
794
|
-
return escapeHtml(token.content || token.raw || "");
|
|
795
|
-
}
|
|
796
658
|
if (this.config.debugMode) {
|
|
797
659
|
return this.createDebugBlock(token);
|
|
798
660
|
}
|
|
@@ -820,15 +682,234 @@ var MarkdownRenderer = class {
|
|
|
820
682
|
<strong>Content:</strong> ${escapeHtml(token.content || token.raw || "")}
|
|
821
683
|
</div>`;
|
|
822
684
|
}
|
|
823
|
-
|
|
824
|
-
this.
|
|
685
|
+
getWarnings() {
|
|
686
|
+
return [...this.warnings];
|
|
687
|
+
}
|
|
688
|
+
getConfig() {
|
|
689
|
+
return { ...this.config };
|
|
690
|
+
}
|
|
691
|
+
updateConfig(config) {
|
|
692
|
+
this.config = { ...this.config, ...config };
|
|
693
|
+
}
|
|
694
|
+
setDebugMode(enabled) {
|
|
695
|
+
this.config.debugMode = enabled;
|
|
696
|
+
}
|
|
697
|
+
clearWarnings() {
|
|
698
|
+
this.warnings = [];
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// src/extensions/core/blockquote.ts
|
|
703
|
+
var BlockquoteExtension = {
|
|
704
|
+
name: "blockquote",
|
|
705
|
+
parseRules: [
|
|
706
|
+
{
|
|
707
|
+
name: "blockquote",
|
|
708
|
+
pattern: /^>\s+(.+)$/m,
|
|
709
|
+
render: (match) => ({
|
|
710
|
+
type: "blockquote",
|
|
711
|
+
content: match[1] || "",
|
|
712
|
+
raw: match[0] || ""
|
|
713
|
+
})
|
|
714
|
+
}
|
|
715
|
+
],
|
|
716
|
+
renderRules: [
|
|
717
|
+
{
|
|
718
|
+
type: "blockquote",
|
|
719
|
+
render: (token) => {
|
|
720
|
+
const content = escapeHtml(token.content);
|
|
721
|
+
const format = token.attributes?.format || "html";
|
|
722
|
+
if (format === "html") {
|
|
723
|
+
return `<blockquote style="border-left: 2px solid #d1d5db; padding: 8px 0 8px 16px; margin: 16px 0; font-style: italic; color: #6b7280;">${content}</blockquote>`;
|
|
724
|
+
}
|
|
725
|
+
return `<blockquote class="pl-4 py-2 border-l-2 border-border italic text-muted-foreground my-4">${content}</blockquote>`;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
]
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
// src/extensions/core/breaks.ts
|
|
732
|
+
var LineBreakExtension = {
|
|
733
|
+
name: "line-break",
|
|
734
|
+
parseRules: [
|
|
735
|
+
{
|
|
736
|
+
name: "hard-break-backslash",
|
|
737
|
+
pattern: /\\\s*\n/,
|
|
738
|
+
render: (match) => ({
|
|
739
|
+
type: "line-break",
|
|
740
|
+
content: "",
|
|
741
|
+
raw: match[0] || ""
|
|
742
|
+
})
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
name: "hard-break-spaces",
|
|
746
|
+
pattern: / +\n/,
|
|
747
|
+
render: (match) => ({
|
|
748
|
+
type: "line-break",
|
|
749
|
+
content: "",
|
|
750
|
+
raw: match[0] || ""
|
|
751
|
+
})
|
|
752
|
+
}
|
|
753
|
+
],
|
|
754
|
+
renderRules: [
|
|
755
|
+
{
|
|
756
|
+
type: "line-break",
|
|
757
|
+
render: () => "<br>"
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
type: "paragraph-break",
|
|
761
|
+
render: () => "</p><p>"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
type: "soft-break",
|
|
765
|
+
render: (token) => token.content || " "
|
|
766
|
+
}
|
|
767
|
+
]
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
// src/extensions/core/code.ts
|
|
771
|
+
var InlineCodeExtension = {
|
|
772
|
+
name: "inline-code",
|
|
773
|
+
parseRules: [
|
|
774
|
+
{
|
|
775
|
+
name: "code",
|
|
776
|
+
pattern: /`([^`]+)`/,
|
|
777
|
+
render: (match) => ({
|
|
778
|
+
type: "code",
|
|
779
|
+
content: match[1] || "",
|
|
780
|
+
raw: match[0] || ""
|
|
781
|
+
})
|
|
782
|
+
}
|
|
783
|
+
],
|
|
784
|
+
renderRules: [
|
|
785
|
+
{
|
|
786
|
+
type: "code",
|
|
787
|
+
render: (token) => {
|
|
788
|
+
const content = escapeHtml(token.content);
|
|
789
|
+
const format = token.attributes?.format;
|
|
790
|
+
if (format === "html") {
|
|
791
|
+
return `<code style="background-color: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.875rem;">${content}</code>`;
|
|
792
|
+
}
|
|
793
|
+
return `<code class="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">${content}</code>`;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
]
|
|
797
|
+
};
|
|
798
|
+
var CodeBlockExtension = {
|
|
799
|
+
name: "codeblock",
|
|
800
|
+
parseRules: [
|
|
801
|
+
{
|
|
802
|
+
name: "codeblock",
|
|
803
|
+
pattern: /```(\w+)?\s*\n([\s\S]*?)\n```/,
|
|
804
|
+
render: (match) => ({
|
|
805
|
+
type: "codeblock",
|
|
806
|
+
content: match[2] || "",
|
|
807
|
+
raw: match[0] || "",
|
|
808
|
+
attributes: {
|
|
809
|
+
language: match[1] || "text"
|
|
810
|
+
}
|
|
811
|
+
})
|
|
812
|
+
}
|
|
813
|
+
],
|
|
814
|
+
renderRules: [
|
|
815
|
+
{
|
|
816
|
+
type: "codeblock",
|
|
817
|
+
render: (token) => {
|
|
818
|
+
const language = token.attributes?.language || "text";
|
|
819
|
+
const escapedCode = escapeHtml(token.content);
|
|
820
|
+
const format = token.attributes?.format || "html";
|
|
821
|
+
if (format === "html") {
|
|
822
|
+
return `<pre style="background-color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; margin: 16px 0;"><code class="language-${escapeHtml(language)}">${escapedCode}</code></pre>`;
|
|
823
|
+
}
|
|
824
|
+
return `<pre class="bg-muted p-4 rounded-md overflow-x-auto my-4"><code class="language-${escapeHtml(language)}">${escapedCode}</code></pre>`;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
]
|
|
828
|
+
};
|
|
829
|
+
|
|
830
|
+
// src/extensions/core/emphasis.ts
|
|
831
|
+
var BoldExtension = {
|
|
832
|
+
name: "bold",
|
|
833
|
+
parseRules: [
|
|
834
|
+
{
|
|
835
|
+
name: "bold",
|
|
836
|
+
pattern: /\*\*((?:(?!\*\*).)+)\*\*/,
|
|
837
|
+
render: (match) => ({
|
|
838
|
+
type: "bold",
|
|
839
|
+
content: match[1] || "",
|
|
840
|
+
raw: match[0] || ""
|
|
841
|
+
})
|
|
842
|
+
}
|
|
843
|
+
],
|
|
844
|
+
renderRules: [
|
|
845
|
+
{
|
|
846
|
+
type: "bold",
|
|
847
|
+
render: (token) => {
|
|
848
|
+
const content = escapeHtml(token.content);
|
|
849
|
+
const format = token.attributes?.format;
|
|
850
|
+
if (format === "html") {
|
|
851
|
+
return `<strong>${content}</strong>`;
|
|
852
|
+
}
|
|
853
|
+
return `<strong class="font-bold">${content}</strong>`;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
]
|
|
857
|
+
};
|
|
858
|
+
var ItalicExtension = {
|
|
859
|
+
name: "italic",
|
|
860
|
+
parseRules: [
|
|
861
|
+
{
|
|
862
|
+
name: "italic",
|
|
863
|
+
pattern: /\*((?:(?!\*).)+)\*/,
|
|
864
|
+
render: (match) => ({
|
|
865
|
+
type: "italic",
|
|
866
|
+
content: match[1] || "",
|
|
867
|
+
raw: match[0] || ""
|
|
868
|
+
})
|
|
869
|
+
}
|
|
870
|
+
],
|
|
871
|
+
renderRules: [
|
|
872
|
+
{
|
|
873
|
+
type: "italic",
|
|
874
|
+
render: (token) => {
|
|
875
|
+
const content = escapeHtml(token.content);
|
|
876
|
+
const format = token.attributes?.format;
|
|
877
|
+
if (format === "html") {
|
|
878
|
+
return `<em>${content}</em>`;
|
|
879
|
+
}
|
|
880
|
+
return `<em class="italic">${content}</em>`;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
]
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
// src/extensions/core/heading.ts
|
|
887
|
+
var HeadingExtension = {
|
|
888
|
+
name: "heading",
|
|
889
|
+
parseRules: [
|
|
890
|
+
{
|
|
891
|
+
name: "heading",
|
|
892
|
+
pattern: /^(#{1,6})\s+(.+)$/m,
|
|
893
|
+
render: (match) => ({
|
|
894
|
+
type: "heading",
|
|
895
|
+
content: match[2]?.trim() || "",
|
|
896
|
+
raw: match[0] || "",
|
|
897
|
+
attributes: {
|
|
898
|
+
level: String(match[1]?.length || 1)
|
|
899
|
+
}
|
|
900
|
+
})
|
|
901
|
+
}
|
|
902
|
+
],
|
|
903
|
+
renderRules: [
|
|
904
|
+
{
|
|
825
905
|
type: "heading",
|
|
826
906
|
render: (token) => {
|
|
827
907
|
const level = parseInt(token.attributes?.level || "1");
|
|
828
908
|
const text = token.content;
|
|
829
909
|
const id = generateId(text);
|
|
830
910
|
const escapedContent = escapeHtml(text);
|
|
831
|
-
|
|
911
|
+
const format = token.attributes?.format || "html";
|
|
912
|
+
if (format === "html") {
|
|
832
913
|
return `<h${level} id="${id}">${escapedContent}</h${level}>`;
|
|
833
914
|
}
|
|
834
915
|
let headingClasses = "group relative flex items-center gap-2";
|
|
@@ -855,61 +936,108 @@ var MarkdownRenderer = class {
|
|
|
855
936
|
return `<h${level} id="${id}" class="${headingClasses}">
|
|
856
937
|
${escapedContent}
|
|
857
938
|
<a href="#${id}" class="opacity-0 group-hover:opacity-100 text-muted-foreground transition-opacity">
|
|
858
|
-
<svg width="16" height="16" viewBox="0 0
|
|
859
|
-
|
|
860
|
-
|
|
939
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
940
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
|
941
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
|
942
|
+
</svg>
|
|
861
943
|
</a>
|
|
862
944
|
</h${level}>`;
|
|
863
945
|
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
this.addRule({
|
|
886
|
-
type: "code",
|
|
946
|
+
}
|
|
947
|
+
]
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
// src/extensions/core/hr.ts
|
|
951
|
+
var HorizontalRuleExtension = {
|
|
952
|
+
name: "hr",
|
|
953
|
+
parseRules: [
|
|
954
|
+
{
|
|
955
|
+
name: "hr",
|
|
956
|
+
pattern: /^---$/m,
|
|
957
|
+
render: (match) => ({
|
|
958
|
+
type: "hr",
|
|
959
|
+
content: "",
|
|
960
|
+
raw: match[0] || ""
|
|
961
|
+
})
|
|
962
|
+
}
|
|
963
|
+
],
|
|
964
|
+
renderRules: [
|
|
965
|
+
{
|
|
966
|
+
type: "hr",
|
|
887
967
|
render: (token) => {
|
|
888
|
-
const
|
|
889
|
-
if (
|
|
890
|
-
return
|
|
968
|
+
const format = token.attributes?.format;
|
|
969
|
+
if (format === "html") {
|
|
970
|
+
return '<hr style="margin: 24px 0; border: none; border-top: 1px solid #d1d5db;">';
|
|
891
971
|
}
|
|
892
|
-
return
|
|
972
|
+
return '<hr class="my-6 border-t border-border">';
|
|
893
973
|
}
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
|
|
974
|
+
}
|
|
975
|
+
]
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
// src/extensions/core/image.ts
|
|
979
|
+
var ImageExtension = {
|
|
980
|
+
name: "image",
|
|
981
|
+
parseRules: [
|
|
982
|
+
{
|
|
983
|
+
name: "image",
|
|
984
|
+
pattern: /!\[([^\]]*)\]\(([^)]+?)(?:\s+"([^"]+)")?\)/,
|
|
985
|
+
render: (match) => ({
|
|
986
|
+
type: "image",
|
|
987
|
+
content: match[1] || "",
|
|
988
|
+
raw: match[0] || "",
|
|
989
|
+
attributes: {
|
|
990
|
+
alt: match[1] || "",
|
|
991
|
+
src: match[2] || "",
|
|
992
|
+
title: match[3] || ""
|
|
993
|
+
}
|
|
994
|
+
})
|
|
995
|
+
}
|
|
996
|
+
],
|
|
997
|
+
renderRules: [
|
|
998
|
+
{
|
|
999
|
+
type: "image",
|
|
897
1000
|
render: (token) => {
|
|
898
|
-
const
|
|
899
|
-
const
|
|
900
|
-
|
|
901
|
-
|
|
1001
|
+
const src = token.attributes?.src || "";
|
|
1002
|
+
const alt = token.attributes?.alt || "";
|
|
1003
|
+
const title = token.attributes?.title || "";
|
|
1004
|
+
const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
|
|
1005
|
+
const format = token.attributes?.format || "html";
|
|
1006
|
+
if (format === "html") {
|
|
1007
|
+
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
|
|
902
1008
|
}
|
|
903
|
-
return `<
|
|
1009
|
+
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
|
|
904
1010
|
}
|
|
905
|
-
}
|
|
906
|
-
|
|
1011
|
+
}
|
|
1012
|
+
]
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
// src/extensions/core/links.ts
|
|
1016
|
+
var LinkExtension = {
|
|
1017
|
+
name: "link",
|
|
1018
|
+
parseRules: [
|
|
1019
|
+
{
|
|
1020
|
+
name: "link",
|
|
1021
|
+
pattern: /\[(?!(?:button|embed):)([^\]]+)\]\(([^)]+)\)/,
|
|
1022
|
+
render: (match) => ({
|
|
1023
|
+
type: "link",
|
|
1024
|
+
content: match[1] || "",
|
|
1025
|
+
raw: match[0] || "",
|
|
1026
|
+
attributes: {
|
|
1027
|
+
href: match[2] || ""
|
|
1028
|
+
}
|
|
1029
|
+
})
|
|
1030
|
+
}
|
|
1031
|
+
],
|
|
1032
|
+
renderRules: [
|
|
1033
|
+
{
|
|
907
1034
|
type: "link",
|
|
908
1035
|
render: (token) => {
|
|
909
1036
|
const href = token.attributes?.href || "#";
|
|
910
1037
|
const escapedHref = escapeHtml(href);
|
|
911
1038
|
const escapedText = escapeHtml(token.content);
|
|
912
|
-
|
|
1039
|
+
const format = token.attributes?.format || "html";
|
|
1040
|
+
if (format === "html") {
|
|
913
1041
|
return `<a href="${escapedHref}" target="_blank" rel="noopener noreferrer">${escapedText}</a>`;
|
|
914
1042
|
}
|
|
915
1043
|
return `<a href="${escapedHref}" class="text-primary hover:underline inline-flex items-center gap-1" target="_blank" rel="noopener noreferrer">
|
|
@@ -921,47 +1049,55 @@ var MarkdownRenderer = class {
|
|
|
921
1049
|
</svg>
|
|
922
1050
|
</a>`;
|
|
923
1051
|
}
|
|
924
|
-
}
|
|
925
|
-
|
|
1052
|
+
}
|
|
1053
|
+
]
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
// src/extensions/core/lists.ts
|
|
1057
|
+
var ListExtension = {
|
|
1058
|
+
name: "list",
|
|
1059
|
+
parseRules: [
|
|
1060
|
+
{
|
|
1061
|
+
name: "list-item",
|
|
1062
|
+
pattern: /^(\s*)[-*+]\s+(.+)$/m,
|
|
1063
|
+
render: (match) => ({
|
|
1064
|
+
type: "list-item",
|
|
1065
|
+
content: match[2] || "",
|
|
1066
|
+
raw: match[0] || ""
|
|
1067
|
+
})
|
|
1068
|
+
}
|
|
1069
|
+
],
|
|
1070
|
+
renderRules: [
|
|
1071
|
+
{
|
|
926
1072
|
type: "list-item",
|
|
927
1073
|
render: (token) => `<li>${escapeHtml(token.content)}</li>`
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
return escapeHtml(token.content);
|
|
944
|
-
}
|
|
945
|
-
});
|
|
946
|
-
this.addRule({
|
|
947
|
-
type: "paragraph",
|
|
948
|
-
render: (token) => {
|
|
949
|
-
if (!token.content) return "";
|
|
950
|
-
const content = token.content.trim();
|
|
951
|
-
if (!content) return "";
|
|
952
|
-
const processedContent = content.includes("<br>") ? content : escapeHtml(content);
|
|
953
|
-
if (this.config.format === "html") {
|
|
954
|
-
return `<p style="line-height: 1.75; margin-bottom: 16px;">${processedContent}</p>`;
|
|
1074
|
+
}
|
|
1075
|
+
]
|
|
1076
|
+
};
|
|
1077
|
+
var TaskListExtension = {
|
|
1078
|
+
name: "task-list",
|
|
1079
|
+
parseRules: [
|
|
1080
|
+
{
|
|
1081
|
+
name: "task-item",
|
|
1082
|
+
pattern: /^(\s*)-\s*\[([ xX])\]\s*(.+)$/m,
|
|
1083
|
+
render: (match) => ({
|
|
1084
|
+
type: "task-item",
|
|
1085
|
+
content: match[3] || "",
|
|
1086
|
+
raw: match[0] || "",
|
|
1087
|
+
attributes: {
|
|
1088
|
+
checked: String((match[2] || "").toLowerCase() === "x")
|
|
955
1089
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1090
|
+
})
|
|
1091
|
+
}
|
|
1092
|
+
],
|
|
1093
|
+
renderRules: [
|
|
1094
|
+
{
|
|
960
1095
|
type: "task-item",
|
|
961
1096
|
render: (token) => {
|
|
962
1097
|
const isChecked = token.attributes?.checked === "true";
|
|
963
1098
|
const escapedContent = escapeHtml(token.content);
|
|
964
|
-
|
|
1099
|
+
const format = token.attributes?.format || "html";
|
|
1100
|
+
if (format === "html") {
|
|
965
1101
|
return `<div style="display: flex; align-items: center; gap: 8px; margin: 8px 0;">
|
|
966
1102
|
<input type="checkbox" ${isChecked ? "checked" : ""} disabled style="margin: 0;" />
|
|
967
1103
|
<span${isChecked ? ' style="text-decoration: line-through; color: #6b7280;"' : ""}>${escapedContent}</span>
|
|
@@ -973,44 +1109,65 @@ var MarkdownRenderer = class {
|
|
|
973
1109
|
<span${isChecked ? ' class="line-through text-muted-foreground"' : ""}>${escapedContent}</span>
|
|
974
1110
|
</div>`;
|
|
975
1111
|
}
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
|
|
1112
|
+
}
|
|
1113
|
+
]
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
// src/extensions/core/paragraph.ts
|
|
1117
|
+
var ParagraphExtension = {
|
|
1118
|
+
name: "paragraph",
|
|
1119
|
+
parseRules: [],
|
|
1120
|
+
renderRules: [
|
|
1121
|
+
{
|
|
1122
|
+
type: "paragraph",
|
|
979
1123
|
render: (token) => {
|
|
980
|
-
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
1124
|
+
if (!token.content) return "";
|
|
1125
|
+
const content = token.content.trim();
|
|
1126
|
+
if (!content) return "";
|
|
1127
|
+
const processedContent = content.includes("<br>") ? content : escapeHtml(content);
|
|
1128
|
+
const format = token.attributes?.format || "html";
|
|
1129
|
+
if (format === "html") {
|
|
1130
|
+
return `<p style="line-height: 1.75; margin-bottom: 16px;">${processedContent}</p>`;
|
|
986
1131
|
}
|
|
987
|
-
return `<
|
|
1132
|
+
return `<p class="leading-7 mb-4">${processedContent}</p>`;
|
|
988
1133
|
}
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1134
|
+
}
|
|
1135
|
+
]
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
// src/extensions/core/text.ts
|
|
1139
|
+
var TextExtension = {
|
|
1140
|
+
name: "text",
|
|
1141
|
+
parseRules: [],
|
|
1142
|
+
renderRules: [
|
|
1143
|
+
{
|
|
1144
|
+
type: "text",
|
|
1145
|
+
render: (token) => {
|
|
1146
|
+
if (!token.content) return "";
|
|
1147
|
+
return escapeHtml(token.content);
|
|
997
1148
|
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
type: "line-break",
|
|
1001
|
-
render: () => "<br>"
|
|
1002
|
-
});
|
|
1003
|
-
this.addRule({
|
|
1004
|
-
type: "paragraph-break",
|
|
1005
|
-
render: () => "</p><p>"
|
|
1006
|
-
});
|
|
1007
|
-
this.addRule({
|
|
1008
|
-
type: "soft-break",
|
|
1009
|
-
render: (token) => token.content || " "
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1149
|
+
}
|
|
1150
|
+
]
|
|
1012
1151
|
};
|
|
1013
1152
|
|
|
1153
|
+
// src/extensions/core/index.ts
|
|
1154
|
+
var CoreExtensions = [
|
|
1155
|
+
TextExtension,
|
|
1156
|
+
HeadingExtension,
|
|
1157
|
+
BoldExtension,
|
|
1158
|
+
ItalicExtension,
|
|
1159
|
+
InlineCodeExtension,
|
|
1160
|
+
CodeBlockExtension,
|
|
1161
|
+
LinkExtension,
|
|
1162
|
+
ImageExtension,
|
|
1163
|
+
ListExtension,
|
|
1164
|
+
TaskListExtension,
|
|
1165
|
+
BlockquoteExtension,
|
|
1166
|
+
HorizontalRuleExtension,
|
|
1167
|
+
ParagraphExtension,
|
|
1168
|
+
LineBreakExtension
|
|
1169
|
+
];
|
|
1170
|
+
|
|
1014
1171
|
// src/extensions/alert.ts
|
|
1015
1172
|
var AlertExtension = {
|
|
1016
1173
|
name: "alert",
|
|
@@ -1090,26 +1247,19 @@ var ButtonExtension = {
|
|
|
1090
1247
|
name: "button",
|
|
1091
1248
|
pattern: /\[button:([^\]]+)\]\(([^)]+)\)(?:\{([^}]+)\})?/,
|
|
1092
1249
|
render: (match) => {
|
|
1093
|
-
const
|
|
1094
|
-
const href = match[2] || "";
|
|
1095
|
-
const optionsString = match[3] || "";
|
|
1096
|
-
const options = optionsString.split(",").map((opt) => opt.trim()).filter(Boolean);
|
|
1097
|
-
const styleOptions = ["default", "primary", "secondary", "success", "danger", "outline", "ghost"];
|
|
1098
|
-
const style = options.find((opt) => styleOptions.includes(opt)) || "primary";
|
|
1099
|
-
const sizeOptions = ["sm", "md", "lg"];
|
|
1100
|
-
const size = options.find((opt) => sizeOptions.includes(opt)) || "md";
|
|
1101
|
-
const disabled = options.includes("disabled");
|
|
1102
|
-
const target = options.includes("self") ? "_self" : "_blank";
|
|
1250
|
+
const options = match[3] ? match[3].split(",").map((opt) => opt.trim()) : [];
|
|
1103
1251
|
return {
|
|
1104
1252
|
type: "button",
|
|
1105
|
-
content:
|
|
1253
|
+
content: match[1] || "",
|
|
1106
1254
|
raw: match[0] || "",
|
|
1107
1255
|
attributes: {
|
|
1108
|
-
href,
|
|
1109
|
-
style
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1256
|
+
href: match[2] || "",
|
|
1257
|
+
style: options.find(
|
|
1258
|
+
(opt) => ["default", "primary", "secondary", "success", "danger", "outline", "ghost"].includes(opt)
|
|
1259
|
+
) || "primary",
|
|
1260
|
+
size: options.find((opt) => ["sm", "md", "lg"].includes(opt)) || "md",
|
|
1261
|
+
disabled: String(options.includes("disabled")),
|
|
1262
|
+
target: options.includes("self") ? "_self" : "_blank"
|
|
1113
1263
|
}
|
|
1114
1264
|
};
|
|
1115
1265
|
}
|
|
@@ -1124,53 +1274,92 @@ var ButtonExtension = {
|
|
|
1124
1274
|
const size = token.attributes?.size || "md";
|
|
1125
1275
|
const disabled = token.attributes?.disabled === "true";
|
|
1126
1276
|
const target = token.attributes?.target || "_blank";
|
|
1127
|
-
const
|
|
1128
|
-
|
|
1277
|
+
const baseClasses = `
|
|
1278
|
+
inline-flex items-center justify-center font-medium rounded-lg
|
|
1279
|
+
transition-all duration-200 ease-out
|
|
1280
|
+
focus:outline-none focus:ring-2 focus:ring-offset-2
|
|
1281
|
+
disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none
|
|
1282
|
+
transform hover:scale-[1.02] active:scale-[0.98]
|
|
1283
|
+
shadow-sm hover:shadow-md active:shadow-sm
|
|
1284
|
+
border border-transparent
|
|
1285
|
+
relative overflow-hidden
|
|
1286
|
+
before:absolute before:inset-0 before:rounded-lg
|
|
1287
|
+
before:bg-gradient-to-br before:from-white/20 before:to-transparent
|
|
1288
|
+
before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-200
|
|
1289
|
+
`.replace(/\s+/g, " ").trim();
|
|
1290
|
+
const sizeClasses = {
|
|
1291
|
+
sm: "px-3 py-1.5 text-sm gap-1.5",
|
|
1292
|
+
md: "px-4 py-2 text-base gap-2",
|
|
1293
|
+
lg: "px-6 py-3 text-lg gap-2.5"
|
|
1294
|
+
};
|
|
1295
|
+
const styleClasses = {
|
|
1296
|
+
default: `
|
|
1297
|
+
bg-slate-600 text-white border-slate-500
|
|
1298
|
+
hover:bg-slate-700 hover:border-slate-400
|
|
1299
|
+
focus:ring-slate-500
|
|
1300
|
+
shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
|
|
1301
|
+
hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
|
|
1302
|
+
`,
|
|
1303
|
+
primary: `
|
|
1304
|
+
bg-blue-600 text-white border-blue-500
|
|
1305
|
+
hover:bg-blue-700 hover:border-blue-400
|
|
1306
|
+
focus:ring-blue-500
|
|
1307
|
+
shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
|
|
1308
|
+
hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
|
|
1309
|
+
`,
|
|
1310
|
+
secondary: `
|
|
1311
|
+
bg-gray-600 text-white border-gray-500
|
|
1312
|
+
hover:bg-gray-700 hover:border-gray-400
|
|
1313
|
+
focus:ring-gray-500
|
|
1314
|
+
shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
|
|
1315
|
+
hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
|
|
1316
|
+
`,
|
|
1317
|
+
success: `
|
|
1318
|
+
bg-green-600 text-white border-green-500
|
|
1319
|
+
hover:bg-green-700 hover:border-green-400
|
|
1320
|
+
focus:ring-green-500
|
|
1321
|
+
shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
|
|
1322
|
+
hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
|
|
1323
|
+
`,
|
|
1324
|
+
danger: `
|
|
1325
|
+
bg-red-600 text-white border-red-500
|
|
1326
|
+
hover:bg-red-700 hover:border-red-400
|
|
1327
|
+
focus:ring-red-500
|
|
1328
|
+
shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
|
|
1329
|
+
hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
|
|
1330
|
+
`,
|
|
1331
|
+
outline: `
|
|
1332
|
+
bg-transparent text-blue-600 border-blue-600
|
|
1333
|
+
hover:bg-blue-50 hover:border-blue-700 hover:text-blue-700
|
|
1334
|
+
focus:ring-blue-500
|
|
1335
|
+
shadow-[0_0_0_1px_rgba(59,130,246,0.5)_inset]
|
|
1336
|
+
hover:shadow-[0_0_0_1px_rgba(29,78,216,0.6)_inset,0_1px_2px_0_rgba(0,0,0,0.05)]
|
|
1337
|
+
`,
|
|
1338
|
+
ghost: `
|
|
1339
|
+
bg-transparent text-gray-700 border-transparent
|
|
1340
|
+
hover:bg-gray-100 hover:text-gray-900
|
|
1341
|
+
focus:ring-gray-500
|
|
1342
|
+
shadow-none
|
|
1343
|
+
hover:shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]
|
|
1344
|
+
`
|
|
1345
|
+
};
|
|
1346
|
+
const classes = `
|
|
1347
|
+
${baseClasses}
|
|
1348
|
+
${sizeClasses[size] || sizeClasses.md}
|
|
1349
|
+
${styleClasses[style] || styleClasses.primary}
|
|
1350
|
+
`.replace(/\s+/g, " ").trim();
|
|
1129
1351
|
const targetAttr = target === "_blank" ? ' target="_blank" rel="noopener noreferrer"' : target === "_self" ? ' target="_self"' : "";
|
|
1130
1352
|
const disabledAttr = disabled ? ' aria-disabled="true" tabindex="-1"' : "";
|
|
1131
|
-
const externalIcon = target === "_blank" && !disabled ?
|
|
1353
|
+
const externalIcon = target === "_blank" && !disabled ? `<svg class="w-4 h-4 ml-1 opacity-75" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1354
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
|
1355
|
+
</svg>` : "";
|
|
1132
1356
|
return `<a href="${href}" class="${classes}"${targetAttr}${disabledAttr}>
|
|
1133
|
-
|
|
1134
|
-
|
|
1357
|
+
<span class="relative z-10">${token.content}</span>${externalIcon}
|
|
1358
|
+
</a>`;
|
|
1135
1359
|
}
|
|
1136
1360
|
}
|
|
1137
1361
|
]
|
|
1138
1362
|
};
|
|
1139
|
-
function buildButtonClasses(style, size) {
|
|
1140
|
-
const base = [
|
|
1141
|
-
"inline-flex",
|
|
1142
|
-
"items-center",
|
|
1143
|
-
"justify-center",
|
|
1144
|
-
"font-medium",
|
|
1145
|
-
"rounded-lg",
|
|
1146
|
-
"transition-colors",
|
|
1147
|
-
"focus:outline-none",
|
|
1148
|
-
"focus:ring-2",
|
|
1149
|
-
"focus:ring-offset-2",
|
|
1150
|
-
"disabled:opacity-50",
|
|
1151
|
-
"disabled:cursor-not-allowed"
|
|
1152
|
-
];
|
|
1153
|
-
const sizes = {
|
|
1154
|
-
sm: ["px-3", "py-1.5", "text-sm"],
|
|
1155
|
-
md: ["px-4", "py-2", "text-base"],
|
|
1156
|
-
lg: ["px-6", "py-3", "text-lg"]
|
|
1157
|
-
};
|
|
1158
|
-
const styles = {
|
|
1159
|
-
default: ["bg-slate-600", "text-white", "hover:bg-slate-700", "focus:ring-slate-500"],
|
|
1160
|
-
primary: ["bg-blue-600", "text-white", "hover:bg-blue-700", "focus:ring-blue-500"],
|
|
1161
|
-
secondary: ["bg-gray-600", "text-white", "hover:bg-gray-700", "focus:ring-gray-500"],
|
|
1162
|
-
success: ["bg-green-600", "text-white", "hover:bg-green-700", "focus:ring-green-500"],
|
|
1163
|
-
danger: ["bg-red-600", "text-white", "hover:bg-red-700", "focus:ring-red-500"],
|
|
1164
|
-
outline: ["border", "border-blue-600", "text-blue-600", "hover:bg-blue-50", "focus:ring-blue-500"],
|
|
1165
|
-
ghost: ["text-gray-700", "hover:bg-gray-100", "focus:ring-gray-500"]
|
|
1166
|
-
};
|
|
1167
|
-
const allClasses = [
|
|
1168
|
-
...base,
|
|
1169
|
-
...sizes[size] ?? sizes.md ?? [],
|
|
1170
|
-
...styles[style] ?? styles.primary ?? []
|
|
1171
|
-
];
|
|
1172
|
-
return allClasses.join(" ");
|
|
1173
|
-
}
|
|
1174
1363
|
|
|
1175
1364
|
// src/extensions/embed.ts
|
|
1176
1365
|
var EmbedExtension = {
|
|
@@ -1248,8 +1437,7 @@ function renderYouTubeEmbed(url, options, classes) {
|
|
|
1248
1437
|
params.set("rel", "0");
|
|
1249
1438
|
params.set("modestbranding", "1");
|
|
1250
1439
|
const embedUrl = `https://www.youtube.com/embed/${videoId}?${params.toString()}`;
|
|
1251
|
-
return
|
|
1252
|
-
<div class="${classes}">
|
|
1440
|
+
return `<div class="${classes}">
|
|
1253
1441
|
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
|
|
1254
1442
|
<iframe
|
|
1255
1443
|
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;"
|
|
@@ -1277,8 +1465,7 @@ function renderCodePenEmbed(url, options, classes) {
|
|
|
1277
1465
|
"editable": "true"
|
|
1278
1466
|
});
|
|
1279
1467
|
const embedUrl = `https://codepen.io/${user}/embed/${penId}?${embedParams.toString()}`;
|
|
1280
|
-
return
|
|
1281
|
-
<div class="${classes}">
|
|
1468
|
+
return `<div class="${classes}">
|
|
1282
1469
|
<iframe
|
|
1283
1470
|
height="${height}"
|
|
1284
1471
|
style="width: 100%; border: 0;"
|
|
@@ -1302,8 +1489,7 @@ function renderVimeoEmbed(url, options, classes) {
|
|
|
1302
1489
|
if (options.mute === "1") params.set("muted", "1");
|
|
1303
1490
|
if (options.loop === "1") params.set("loop", "1");
|
|
1304
1491
|
const embedUrl = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;
|
|
1305
|
-
return
|
|
1306
|
-
<div class="${classes}">
|
|
1492
|
+
return `<div class="${classes}">
|
|
1307
1493
|
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
|
|
1308
1494
|
<iframe
|
|
1309
1495
|
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;"
|
|
@@ -1319,8 +1505,7 @@ function renderVimeoEmbed(url, options, classes) {
|
|
|
1319
1505
|
function renderSpotifyEmbed(url, options, classes) {
|
|
1320
1506
|
const embedUrl = url.replace("open.spotify.com", "open.spotify.com/embed");
|
|
1321
1507
|
const height = options.height || "380";
|
|
1322
|
-
return
|
|
1323
|
-
<div class="${classes}">
|
|
1508
|
+
return `<div class="${classes}">
|
|
1324
1509
|
<iframe
|
|
1325
1510
|
style="border-radius: 12px;"
|
|
1326
1511
|
src="${embedUrl}"
|
|
@@ -1343,8 +1528,7 @@ function renderCodeSandboxEmbed(url, options, classes) {
|
|
|
1343
1528
|
if (!embedUrl.includes("?")) {
|
|
1344
1529
|
embedUrl += `?view=${view}`;
|
|
1345
1530
|
}
|
|
1346
|
-
return
|
|
1347
|
-
<div class="${classes}">
|
|
1531
|
+
return `<div class="${classes}">
|
|
1348
1532
|
<iframe
|
|
1349
1533
|
src="${embedUrl}"
|
|
1350
1534
|
style="width: 100%; height: ${height}px; border: 0; border-radius: 4px; overflow: hidden;"
|
|
@@ -1357,8 +1541,7 @@ function renderCodeSandboxEmbed(url, options, classes) {
|
|
|
1357
1541
|
function renderFigmaEmbed(url, options, classes) {
|
|
1358
1542
|
const embedUrl = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;
|
|
1359
1543
|
const height = options.height || "450";
|
|
1360
|
-
return
|
|
1361
|
-
<div class="${classes}">
|
|
1544
|
+
return `<div class="${classes}">
|
|
1362
1545
|
<iframe
|
|
1363
1546
|
style="border: none;"
|
|
1364
1547
|
width="100%"
|
|
@@ -1369,8 +1552,7 @@ function renderFigmaEmbed(url, options, classes) {
|
|
|
1369
1552
|
</div>`;
|
|
1370
1553
|
}
|
|
1371
1554
|
function renderTwitterEmbed(url, _options, classes) {
|
|
1372
|
-
return
|
|
1373
|
-
<div class="${classes}">
|
|
1555
|
+
return `<div class="${classes}">
|
|
1374
1556
|
<div class="p-4">
|
|
1375
1557
|
<div class="flex items-center gap-3 mb-3">
|
|
1376
1558
|
<svg class="w-6 h-6 fill-current text-blue-500" viewBox="0 0 24 24">
|
|
@@ -1398,8 +1580,7 @@ function renderGitHubEmbed(url, _options, classes) {
|
|
|
1398
1580
|
if (!owner || !repo) {
|
|
1399
1581
|
return createErrorEmbed("Invalid GitHub URL", url, classes);
|
|
1400
1582
|
}
|
|
1401
|
-
return
|
|
1402
|
-
<div class="${classes}">
|
|
1583
|
+
return `<div class="${classes}">
|
|
1403
1584
|
<div class="p-4">
|
|
1404
1585
|
<div class="flex items-center gap-3 mb-3">
|
|
1405
1586
|
<svg class="w-6 h-6 fill-current" viewBox="0 0 24 24">
|
|
@@ -1422,8 +1603,7 @@ function renderGitHubEmbed(url, _options, classes) {
|
|
|
1422
1603
|
}
|
|
1423
1604
|
function renderGenericEmbed(url, _options, classes) {
|
|
1424
1605
|
const domain = extractDomain(url);
|
|
1425
|
-
return
|
|
1426
|
-
<div class="${classes}">
|
|
1606
|
+
return `<div class="${classes}">
|
|
1427
1607
|
<div class="p-4">
|
|
1428
1608
|
<div class="flex items-center gap-3 mb-3">
|
|
1429
1609
|
<div class="w-10 h-10 rounded-lg bg-muted flex items-center justify-center">
|
|
@@ -1447,8 +1627,7 @@ function renderGenericEmbed(url, _options, classes) {
|
|
|
1447
1627
|
</div>`;
|
|
1448
1628
|
}
|
|
1449
1629
|
function createErrorEmbed(error, url, classes) {
|
|
1450
|
-
return
|
|
1451
|
-
<div class="${classes}">
|
|
1630
|
+
return `<div class="${classes}">
|
|
1452
1631
|
<div class="p-4 text-destructive">
|
|
1453
1632
|
<div class="font-medium flex items-center gap-2">
|
|
1454
1633
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
@@ -1482,19 +1661,54 @@ var ChangerawrMarkdown = class {
|
|
|
1482
1661
|
this.extensions = /* @__PURE__ */ new Map();
|
|
1483
1662
|
this.parser = new MarkdownParser(config?.parser);
|
|
1484
1663
|
this.renderer = new MarkdownRenderer(config?.renderer);
|
|
1485
|
-
this.
|
|
1664
|
+
this.registerCoreExtensions();
|
|
1665
|
+
this.registerFeatureExtensions();
|
|
1486
1666
|
if (config?.extensions) {
|
|
1487
1667
|
config.extensions.forEach((extension) => {
|
|
1488
1668
|
this.registerExtension(extension);
|
|
1489
1669
|
});
|
|
1490
1670
|
}
|
|
1491
|
-
this.parser.setupDefaultRulesIfEmpty();
|
|
1492
1671
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1672
|
+
registerFeatureExtensions() {
|
|
1673
|
+
this.registerExtension(AlertExtension);
|
|
1674
|
+
this.registerExtension(ButtonExtension);
|
|
1675
|
+
this.registerExtension(EmbedExtension);
|
|
1676
|
+
}
|
|
1677
|
+
registerCoreExtensions() {
|
|
1678
|
+
CoreExtensions.forEach((extension) => {
|
|
1679
|
+
this.registerExtension(extension);
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1496
1682
|
registerExtension(extension) {
|
|
1497
1683
|
try {
|
|
1684
|
+
if (!extension.name || typeof extension.name !== "string") {
|
|
1685
|
+
throw new Error("Extension must have a valid name");
|
|
1686
|
+
}
|
|
1687
|
+
if (!Array.isArray(extension.parseRules)) {
|
|
1688
|
+
throw new Error("Extension must have parseRules array");
|
|
1689
|
+
}
|
|
1690
|
+
if (!Array.isArray(extension.renderRules)) {
|
|
1691
|
+
throw new Error("Extension must have renderRules array");
|
|
1692
|
+
}
|
|
1693
|
+
extension.parseRules.forEach((rule, index) => {
|
|
1694
|
+
if (!rule.name || typeof rule.name !== "string") {
|
|
1695
|
+
throw new Error(`Parse rule ${index} must have a valid name`);
|
|
1696
|
+
}
|
|
1697
|
+
if (!rule.pattern || !(rule.pattern instanceof RegExp)) {
|
|
1698
|
+
throw new Error(`Parse rule ${index} must have a valid RegExp pattern`);
|
|
1699
|
+
}
|
|
1700
|
+
if (!rule.render || typeof rule.render !== "function") {
|
|
1701
|
+
throw new Error(`Parse rule ${index} must have a valid render function`);
|
|
1702
|
+
}
|
|
1703
|
+
});
|
|
1704
|
+
extension.renderRules.forEach((rule, index) => {
|
|
1705
|
+
if (!rule.type || typeof rule.type !== "string") {
|
|
1706
|
+
throw new Error(`Render rule ${index} must have a valid type`);
|
|
1707
|
+
}
|
|
1708
|
+
if (!rule.render || typeof rule.render !== "function") {
|
|
1709
|
+
throw new Error(`Render rule ${index} must have a valid render function`);
|
|
1710
|
+
}
|
|
1711
|
+
});
|
|
1498
1712
|
this.extensions.set(extension.name, extension);
|
|
1499
1713
|
extension.parseRules.forEach((rule) => {
|
|
1500
1714
|
this.parser.addRule(rule);
|
|
@@ -1515,9 +1729,6 @@ var ChangerawrMarkdown = class {
|
|
|
1515
1729
|
};
|
|
1516
1730
|
}
|
|
1517
1731
|
}
|
|
1518
|
-
/**
|
|
1519
|
-
* Unregister an extension
|
|
1520
|
-
*/
|
|
1521
1732
|
unregisterExtension(name) {
|
|
1522
1733
|
const extension = this.extensions.get(name);
|
|
1523
1734
|
if (!extension) {
|
|
@@ -1531,46 +1742,25 @@ var ChangerawrMarkdown = class {
|
|
|
1531
1742
|
return false;
|
|
1532
1743
|
}
|
|
1533
1744
|
}
|
|
1534
|
-
/**
|
|
1535
|
-
* Parse markdown content into tokens
|
|
1536
|
-
*/
|
|
1537
1745
|
parse(markdown3) {
|
|
1538
1746
|
return this.parser.parse(markdown3);
|
|
1539
1747
|
}
|
|
1540
|
-
/**
|
|
1541
|
-
* Render tokens to HTML
|
|
1542
|
-
*/
|
|
1543
1748
|
render(tokens) {
|
|
1544
1749
|
return this.renderer.render(tokens);
|
|
1545
1750
|
}
|
|
1546
|
-
/**
|
|
1547
|
-
* Parse and render markdown to HTML in one step
|
|
1548
|
-
*/
|
|
1549
1751
|
toHtml(markdown3) {
|
|
1550
1752
|
const tokens = this.parse(markdown3);
|
|
1551
1753
|
return this.render(tokens);
|
|
1552
1754
|
}
|
|
1553
|
-
/**
|
|
1554
|
-
* Get list of registered extensions
|
|
1555
|
-
*/
|
|
1556
1755
|
getExtensions() {
|
|
1557
1756
|
return Array.from(this.extensions.keys());
|
|
1558
1757
|
}
|
|
1559
|
-
/**
|
|
1560
|
-
* Check if extension is registered
|
|
1561
|
-
*/
|
|
1562
1758
|
hasExtension(name) {
|
|
1563
1759
|
return this.extensions.has(name);
|
|
1564
1760
|
}
|
|
1565
|
-
/**
|
|
1566
|
-
* Get parser warnings
|
|
1567
|
-
*/
|
|
1568
1761
|
getWarnings() {
|
|
1569
1762
|
return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];
|
|
1570
1763
|
}
|
|
1571
|
-
/**
|
|
1572
|
-
* Get debug information from last render
|
|
1573
|
-
*/
|
|
1574
1764
|
getDebugInfo() {
|
|
1575
1765
|
return {
|
|
1576
1766
|
warnings: this.getWarnings(),
|
|
@@ -1580,9 +1770,6 @@ var ChangerawrMarkdown = class {
|
|
|
1580
1770
|
iterationCount: 0
|
|
1581
1771
|
};
|
|
1582
1772
|
}
|
|
1583
|
-
/**
|
|
1584
|
-
* Get performance metrics for the last operation
|
|
1585
|
-
*/
|
|
1586
1773
|
getPerformanceMetrics() {
|
|
1587
1774
|
return {
|
|
1588
1775
|
parseTime: 0,
|
|
@@ -1591,28 +1778,29 @@ var ChangerawrMarkdown = class {
|
|
|
1591
1778
|
tokenCount: 0
|
|
1592
1779
|
};
|
|
1593
1780
|
}
|
|
1594
|
-
/**
|
|
1595
|
-
* Register built-in extensions
|
|
1596
|
-
*/
|
|
1597
|
-
registerBuiltInExtensions() {
|
|
1598
|
-
this.registerExtension(AlertExtension);
|
|
1599
|
-
this.registerExtension(ButtonExtension);
|
|
1600
|
-
this.registerExtension(EmbedExtension);
|
|
1601
|
-
}
|
|
1602
|
-
/**
|
|
1603
|
-
* Rebuild parser and renderer with current extensions
|
|
1604
|
-
*/
|
|
1605
1781
|
rebuildParserAndRenderer() {
|
|
1606
1782
|
const parserConfig = this.parser.getConfig();
|
|
1607
1783
|
const rendererConfig = this.renderer.getConfig();
|
|
1608
1784
|
this.parser = new MarkdownParser(parserConfig);
|
|
1609
1785
|
this.renderer = new MarkdownRenderer(rendererConfig);
|
|
1610
1786
|
const extensionsToRegister = Array.from(this.extensions.values());
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1787
|
+
const featureExtensions = extensionsToRegister.filter(
|
|
1788
|
+
(ext) => ["alert", "button", "embed"].includes(ext.name)
|
|
1789
|
+
);
|
|
1790
|
+
const coreExtensions = extensionsToRegister.filter(
|
|
1791
|
+
(ext) => ["text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(ext.name)
|
|
1792
|
+
);
|
|
1793
|
+
const customExtensions = extensionsToRegister.filter(
|
|
1794
|
+
(ext) => !["alert", "button", "embed", "text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(ext.name)
|
|
1795
|
+
);
|
|
1796
|
+
[...featureExtensions, ...coreExtensions, ...customExtensions].forEach((extension) => {
|
|
1797
|
+
extension.parseRules.forEach((rule) => {
|
|
1798
|
+
this.parser.addRule(rule);
|
|
1799
|
+
});
|
|
1800
|
+
extension.renderRules.forEach((rule) => {
|
|
1801
|
+
this.renderer.addRule(rule);
|
|
1802
|
+
});
|
|
1614
1803
|
});
|
|
1615
|
-
this.parser.setupDefaultRulesIfEmpty();
|
|
1616
1804
|
}
|
|
1617
1805
|
};
|
|
1618
1806
|
var markdown = new ChangerawrMarkdown();
|
|
@@ -2042,8 +2230,7 @@ function createHTMLEngine(config) {
|
|
|
2042
2230
|
renderer: {
|
|
2043
2231
|
format: "html",
|
|
2044
2232
|
sanitize: true,
|
|
2045
|
-
allowUnsafeHtml: false
|
|
2046
|
-
...config?.parser
|
|
2233
|
+
allowUnsafeHtml: false
|
|
2047
2234
|
}
|
|
2048
2235
|
});
|
|
2049
2236
|
}
|
|
@@ -2053,8 +2240,7 @@ function createTailwindEngine(config) {
|
|
|
2053
2240
|
renderer: {
|
|
2054
2241
|
format: "tailwind",
|
|
2055
2242
|
sanitize: true,
|
|
2056
|
-
allowUnsafeHtml: false
|
|
2057
|
-
...config?.parser
|
|
2243
|
+
allowUnsafeHtml: false
|
|
2058
2244
|
}
|
|
2059
2245
|
});
|
|
2060
2246
|
}
|
|
@@ -2073,21 +2259,18 @@ function createDebugEngine(config) {
|
|
|
2073
2259
|
}
|
|
2074
2260
|
});
|
|
2075
2261
|
}
|
|
2076
|
-
function createMinimalEngine(
|
|
2077
|
-
const engine = new ChangerawrMarkdown(
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
if (engine.hasExtension("embed")) {
|
|
2089
|
-
engine.unregisterExtension("embed");
|
|
2090
|
-
}
|
|
2262
|
+
function createMinimalEngine(extensions = []) {
|
|
2263
|
+
const engine = new ChangerawrMarkdown();
|
|
2264
|
+
const defaultExtensions = engine.getExtensions();
|
|
2265
|
+
defaultExtensions.forEach((ext) => engine.unregisterExtension(ext));
|
|
2266
|
+
extensions.forEach((ext) => engine.registerExtension(ext));
|
|
2267
|
+
return engine;
|
|
2268
|
+
}
|
|
2269
|
+
function createCoreOnlyEngine(config) {
|
|
2270
|
+
const engine = new ChangerawrMarkdown(config);
|
|
2271
|
+
engine.unregisterExtension("alert");
|
|
2272
|
+
engine.unregisterExtension("button");
|
|
2273
|
+
engine.unregisterExtension("embed");
|
|
2091
2274
|
return engine;
|
|
2092
2275
|
}
|
|
2093
2276
|
function createCustomEngine(extensions, config) {
|
|
@@ -2111,6 +2294,7 @@ var markdown2 = {
|
|
|
2111
2294
|
createTailwindEngine,
|
|
2112
2295
|
createDebugEngine,
|
|
2113
2296
|
createMinimalEngine,
|
|
2297
|
+
createCoreOnlyEngine,
|
|
2114
2298
|
createCustomEngine,
|
|
2115
2299
|
// Standalone functions
|
|
2116
2300
|
renderCum,
|
|
@@ -2119,6 +2303,24 @@ var markdown2 = {
|
|
|
2119
2303
|
ChangerawrMarkdown,
|
|
2120
2304
|
// Extensions
|
|
2121
2305
|
extensions: {
|
|
2306
|
+
// All core extensions as a bundle
|
|
2307
|
+
core: CoreExtensions,
|
|
2308
|
+
// Individual core extensions
|
|
2309
|
+
Text: TextExtension,
|
|
2310
|
+
Heading: HeadingExtension,
|
|
2311
|
+
Bold: BoldExtension,
|
|
2312
|
+
Italic: ItalicExtension,
|
|
2313
|
+
InlineCode: InlineCodeExtension,
|
|
2314
|
+
CodeBlock: CodeBlockExtension,
|
|
2315
|
+
Link: LinkExtension,
|
|
2316
|
+
Image: ImageExtension,
|
|
2317
|
+
List: ListExtension,
|
|
2318
|
+
TaskList: TaskListExtension,
|
|
2319
|
+
Blockquote: BlockquoteExtension,
|
|
2320
|
+
HorizontalRule: HorizontalRuleExtension,
|
|
2321
|
+
Paragraph: ParagraphExtension,
|
|
2322
|
+
LineBreak: LineBreakExtension,
|
|
2323
|
+
// Feature extensions
|
|
2122
2324
|
Alert: AlertExtension,
|
|
2123
2325
|
Button: ButtonExtension,
|
|
2124
2326
|
Embed: EmbedExtension
|
|
@@ -2179,6 +2381,14 @@ var presets = {
|
|
|
2179
2381
|
sanitize: true
|
|
2180
2382
|
}
|
|
2181
2383
|
},
|
|
2384
|
+
/**
|
|
2385
|
+
* Core-only preset with just markdown basics
|
|
2386
|
+
*/
|
|
2387
|
+
coreOnly: {
|
|
2388
|
+
renderer: {
|
|
2389
|
+
format: "tailwind"
|
|
2390
|
+
}
|
|
2391
|
+
},
|
|
2182
2392
|
/**
|
|
2183
2393
|
* Performance preset with minimal processing
|
|
2184
2394
|
*/
|
|
@@ -2195,6 +2405,9 @@ var presets = {
|
|
|
2195
2405
|
};
|
|
2196
2406
|
function createEngineWithPreset(presetName, additionalConfig) {
|
|
2197
2407
|
const preset = presets[presetName];
|
|
2408
|
+
if (presetName === "coreOnly") {
|
|
2409
|
+
return createCoreOnlyEngine(additionalConfig);
|
|
2410
|
+
}
|
|
2198
2411
|
return new ChangerawrMarkdown({
|
|
2199
2412
|
...preset,
|
|
2200
2413
|
...additionalConfig
|
|
@@ -2203,17 +2416,33 @@ function createEngineWithPreset(presetName, additionalConfig) {
|
|
|
2203
2416
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2204
2417
|
0 && (module.exports = {
|
|
2205
2418
|
AlertExtension,
|
|
2419
|
+
BlockquoteExtension,
|
|
2420
|
+
BoldExtension,
|
|
2206
2421
|
ButtonExtension,
|
|
2207
2422
|
ChangerawrMarkdown,
|
|
2423
|
+
CodeBlockExtension,
|
|
2424
|
+
CoreExtensions,
|
|
2208
2425
|
EmbedExtension,
|
|
2426
|
+
HeadingExtension,
|
|
2427
|
+
HorizontalRuleExtension,
|
|
2428
|
+
ImageExtension,
|
|
2429
|
+
InlineCodeExtension,
|
|
2430
|
+
ItalicExtension,
|
|
2431
|
+
LineBreakExtension,
|
|
2432
|
+
LinkExtension,
|
|
2433
|
+
ListExtension,
|
|
2209
2434
|
Logger,
|
|
2210
2435
|
MarkdownParser,
|
|
2211
2436
|
MarkdownRenderer,
|
|
2437
|
+
ParagraphExtension,
|
|
2212
2438
|
PerformanceTimer,
|
|
2439
|
+
TaskListExtension,
|
|
2440
|
+
TextExtension,
|
|
2213
2441
|
astToJSONString,
|
|
2214
2442
|
astToTokens,
|
|
2215
2443
|
basicSanitize,
|
|
2216
2444
|
compareTokens,
|
|
2445
|
+
createCoreOnlyEngine,
|
|
2217
2446
|
createCumEngine,
|
|
2218
2447
|
createCustomEngine,
|
|
2219
2448
|
createDebugEngine,
|