@emberkit/core 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +199 -0
- package/dist/boundaries/error-boundary.d.ts +29 -0
- package/dist/boundaries/error-boundary.d.ts.map +1 -0
- package/dist/boundaries/errors.d.ts +39 -0
- package/dist/boundaries/errors.d.ts.map +1 -0
- package/dist/boundaries/index.d.ts +5 -0
- package/dist/boundaries/index.d.ts.map +1 -0
- package/dist/boundaries/loading-boundary.d.ts +42 -0
- package/dist/boundaries/loading-boundary.d.ts.map +1 -0
- package/dist/cache/index.d.ts +60 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +24 -22
- package/dist/compiler/compiler.d.ts +6 -0
- package/dist/compiler/compiler.d.ts.map +1 -0
- package/dist/compiler/helpers/attributes.d.ts +4 -0
- package/dist/compiler/helpers/attributes.d.ts.map +1 -0
- package/dist/compiler/helpers/utils.d.ts +10 -0
- package/dist/compiler/helpers/utils.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +5 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/types.d.ts +40 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/context/index.d.ts +34 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/types.d.ts +10 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/dev-server/index.d.ts +30 -0
- package/dist/dev-server/index.d.ts.map +1 -0
- package/dist/dev-server/index.js +27 -27
- package/dist/forms/index.d.ts +58 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/index.js +1 -1
- package/dist/forms/mutations.d.ts +48 -0
- package/dist/forms/mutations.d.ts.map +1 -0
- package/dist/forms/mutations.js +4 -1
- package/dist/hmr/client.d.ts +18 -0
- package/dist/hmr/client.d.ts.map +1 -0
- package/dist/hmr/client.js +1 -1
- package/dist/hmr/index.d.ts +3 -0
- package/dist/hmr/index.d.ts.map +1 -0
- package/dist/hmr/types.d.ts +42 -0
- package/dist/hmr/types.d.ts.map +1 -0
- package/dist/hmr/types.js +7 -7
- package/dist/hydration/helpers/analyzer.d.ts +9 -0
- package/dist/hydration/helpers/analyzer.d.ts.map +1 -0
- package/dist/hydration/helpers/hydration.d.ts +19 -0
- package/dist/hydration/helpers/hydration.d.ts.map +1 -0
- package/dist/hydration/helpers/hydration.js +1 -1
- package/dist/hydration/index.d.ts +4 -0
- package/dist/hydration/index.d.ts.map +1 -0
- package/dist/hydration/types.d.ts +27 -0
- package/dist/hydration/types.d.ts.map +1 -0
- package/dist/hydration/types.js +32 -8
- package/dist/image/index.d.ts +9 -0
- package/dist/image/index.d.ts.map +1 -0
- package/dist/image/index.js +1 -1
- package/dist/image/processor.d.ts +57 -0
- package/dist/image/processor.d.ts.map +1 -0
- package/dist/image/processor.js +20 -15
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -2
- package/dist/jsx-dev-runtime.d.ts +11 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.d.ts +11 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/loader/helpers/loader.d.ts +6 -0
- package/dist/loader/helpers/loader.d.ts.map +1 -0
- package/dist/loader/index.d.ts +3 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/types.d.ts +34 -0
- package/dist/loader/types.d.ts.map +1 -0
- package/dist/markdown/index.d.ts +77 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +178 -172
- package/dist/mdx/index.d.ts +43 -0
- package/dist/mdx/index.d.ts.map +1 -0
- package/dist/mdx/index.js +46 -40
- package/dist/mdx/loader.d.ts +3 -0
- package/dist/mdx/loader.d.ts.map +1 -0
- package/dist/meta/head-registry.d.ts +5 -0
- package/dist/meta/head-registry.d.ts.map +1 -0
- package/dist/meta/head.d.ts +29 -0
- package/dist/meta/head.d.ts.map +1 -0
- package/dist/meta/index.d.ts +91 -0
- package/dist/meta/index.d.ts.map +1 -0
- package/dist/meta/index.js +16 -16
- package/dist/navigation/helpers/navigation.d.ts +15 -0
- package/dist/navigation/helpers/navigation.d.ts.map +1 -0
- package/dist/navigation/helpers/navigation.js +4 -4
- package/dist/navigation/helpers/useNavigate.d.ts +6 -0
- package/dist/navigation/helpers/useNavigate.d.ts.map +1 -0
- package/dist/navigation/index.d.ts +5 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/types.d.ts +24 -0
- package/dist/navigation/types.d.ts.map +1 -0
- package/dist/navigation/types.js +1 -2
- package/dist/plugin/index.d.ts +73 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +4 -4
- package/dist/router/helpers/path.d.ts +15 -0
- package/dist/router/helpers/path.d.ts.map +1 -0
- package/dist/router/helpers/route.d.ts +6 -0
- package/dist/router/helpers/route.d.ts.map +1 -0
- package/dist/router/helpers/route.js +10 -3
- package/dist/router/index.d.ts +35 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/types.d.ts +30 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +1 -3
- package/dist/runtime/helpers/element.d.ts +7 -0
- package/dist/runtime/helpers/element.d.ts.map +1 -0
- package/dist/runtime/helpers/render.d.ts +8 -0
- package/dist/runtime/helpers/render.d.ts.map +1 -0
- package/dist/runtime/helpers/render.js +37 -8
- package/dist/runtime/index.d.ts +16 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +63 -7
- package/dist/runtime/types.d.ts +65 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/signals/helpers/core.d.ts +11 -0
- package/dist/signals/helpers/core.d.ts.map +1 -0
- package/dist/signals/helpers/core.js +34 -12
- package/dist/signals/helpers/utils.d.ts +7 -0
- package/dist/signals/helpers/utils.d.ts.map +1 -0
- package/dist/signals/index.d.ts +4 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/types.d.ts +23 -0
- package/dist/signals/types.d.ts.map +1 -0
- package/dist/ssg/index.d.ts +38 -0
- package/dist/ssg/index.d.ts.map +1 -0
- package/dist/ssg/index.js +8 -15
- package/dist/ssr/helpers/render-html.d.ts +16 -0
- package/dist/ssr/helpers/render-html.d.ts.map +1 -0
- package/dist/ssr/helpers/render-html.js +3 -2
- package/dist/ssr/helpers/ssr.d.ts +14 -0
- package/dist/ssr/helpers/ssr.d.ts.map +1 -0
- package/dist/ssr/helpers/ssr.js +3 -1
- package/dist/ssr/index.d.ts +4 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +29 -0
- package/dist/ssr/types.d.ts.map +1 -0
- package/dist/vite-plugin/index.d.ts +5 -0
- package/dist/vite-plugin/index.d.ts.map +1 -0
- package/dist/vite-plugin/index.js +207 -28
- package/dist/vite-plugin/types.d.ts +44 -0
- package/dist/vite-plugin/types.d.ts.map +1 -0
- package/dist/vite-plugin/types.js +4 -0
- package/package.json +12 -10
package/dist/markdown/index.js
CHANGED
|
@@ -23,6 +23,25 @@ class MarkdownParser {
|
|
|
23
23
|
const codeBlocks = this.extractCodeBlocks(content);
|
|
24
24
|
return { html, frontmatter, headings, links, images, codeBlocks };
|
|
25
25
|
}
|
|
26
|
+
escapeHtml(text) {
|
|
27
|
+
return text
|
|
28
|
+
.replace(/&/g, '&')
|
|
29
|
+
.replace(/</g, '<')
|
|
30
|
+
.replace(/>/g, '>')
|
|
31
|
+
.replace(/"/g, '"');
|
|
32
|
+
}
|
|
33
|
+
extractCodeBlocks(content) {
|
|
34
|
+
const blocks = [];
|
|
35
|
+
const regex = /```(\w*)\n([\s\S]*?)```/g;
|
|
36
|
+
let match;
|
|
37
|
+
while ((match = regex.exec(content)) !== null) {
|
|
38
|
+
blocks.push({
|
|
39
|
+
lang: match[1],
|
|
40
|
+
code: match[2].trim(),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return blocks;
|
|
44
|
+
}
|
|
26
45
|
extractFrontmatter(markdown) {
|
|
27
46
|
const match = markdown.match(/^---\n([\s\S]*?)\n---/);
|
|
28
47
|
if (!match)
|
|
@@ -42,39 +61,118 @@ class MarkdownParser {
|
|
|
42
61
|
else if (!isNaN(Number(value)))
|
|
43
62
|
value = Number(value);
|
|
44
63
|
else if (typeof value === 'string' && value.startsWith('[')) {
|
|
45
|
-
value = value
|
|
64
|
+
value = value
|
|
65
|
+
.replace(/[\[\]]/g, '')
|
|
66
|
+
.split(',')
|
|
67
|
+
.map((s) => s.trim());
|
|
46
68
|
}
|
|
47
69
|
result[key] = value;
|
|
48
70
|
}
|
|
49
71
|
return result;
|
|
50
72
|
}
|
|
51
|
-
|
|
52
|
-
|
|
73
|
+
extractHeadings(html) {
|
|
74
|
+
const headings = [];
|
|
75
|
+
const regex = /<h(\d) id="([^"]+)">([^<]+)<\/h\1>/g;
|
|
76
|
+
let match;
|
|
77
|
+
while ((match = regex.exec(html)) !== null) {
|
|
78
|
+
headings.push({
|
|
79
|
+
level: parseInt(match[1]),
|
|
80
|
+
text: match[3],
|
|
81
|
+
id: match[2],
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return headings;
|
|
53
85
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
let
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
86
|
+
extractImages(content) {
|
|
87
|
+
const images = [];
|
|
88
|
+
const regex = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
89
|
+
let match;
|
|
90
|
+
while ((match = regex.exec(content)) !== null) {
|
|
91
|
+
const src = match[2];
|
|
92
|
+
const alt = match[1];
|
|
93
|
+
const titleMatch = src.match(/"([^"]+)"/);
|
|
94
|
+
const title = titleMatch ? titleMatch[1] : undefined;
|
|
95
|
+
images.push({ src, alt, title });
|
|
96
|
+
}
|
|
97
|
+
return images;
|
|
98
|
+
}
|
|
99
|
+
extractLinks(content) {
|
|
100
|
+
const links = [];
|
|
101
|
+
const regex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
102
|
+
let match;
|
|
103
|
+
while ((match = regex.exec(content)) !== null) {
|
|
104
|
+
const href = match[2];
|
|
105
|
+
if (!href.startsWith('#') && !links.includes(href)) {
|
|
106
|
+
links.push(href);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return links;
|
|
110
|
+
}
|
|
111
|
+
processBlockquotes(html) {
|
|
112
|
+
const lines = html.split('\n');
|
|
113
|
+
const result = [];
|
|
114
|
+
let inBlockquote = false;
|
|
115
|
+
let depth = 0;
|
|
116
|
+
for (const line of lines) {
|
|
117
|
+
const match = line.match(/^(\s*)>\s?(.*)/);
|
|
118
|
+
if (match) {
|
|
119
|
+
const indent = match[1].length;
|
|
120
|
+
const content = match[2];
|
|
121
|
+
const newDepth = Math.floor(indent / 2) + 1;
|
|
122
|
+
if (!inBlockquote) {
|
|
123
|
+
for (let i = 0; i < newDepth; i++) {
|
|
124
|
+
result.push('<blockquote>');
|
|
125
|
+
}
|
|
126
|
+
depth = newDepth;
|
|
127
|
+
inBlockquote = true;
|
|
128
|
+
}
|
|
129
|
+
else if (newDepth > depth) {
|
|
130
|
+
for (let i = depth; i < newDepth; i++) {
|
|
131
|
+
result.push('<blockquote>');
|
|
132
|
+
}
|
|
133
|
+
depth = newDepth;
|
|
134
|
+
}
|
|
135
|
+
else if (newDepth < depth) {
|
|
136
|
+
for (let i = depth; i > newDepth; i--) {
|
|
137
|
+
result.push('</blockquote>');
|
|
138
|
+
}
|
|
139
|
+
depth = newDepth;
|
|
140
|
+
}
|
|
141
|
+
result.push(content || '<br>');
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
if (inBlockquote) {
|
|
145
|
+
for (let i = depth; i > 0; i--) {
|
|
146
|
+
result.push('</blockquote>');
|
|
147
|
+
}
|
|
148
|
+
inBlockquote = false;
|
|
149
|
+
depth = 0;
|
|
150
|
+
}
|
|
151
|
+
result.push(line);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (inBlockquote) {
|
|
155
|
+
for (let i = depth; i > 0; i--) {
|
|
156
|
+
result.push('</blockquote>');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return result.join('\n');
|
|
160
|
+
}
|
|
161
|
+
processComponents(html) {
|
|
162
|
+
for (const [component, tag] of Object.entries(this.config.components)) {
|
|
163
|
+
html = html.replace(new RegExp(`<${component}>`, 'g'), `<${tag}>`);
|
|
164
|
+
html = html.replace(new RegExp(`</${component}>`, 'g'), `</${tag}>`);
|
|
165
|
+
}
|
|
76
166
|
return html;
|
|
77
167
|
}
|
|
168
|
+
processEmphasis(html) {
|
|
169
|
+
return html
|
|
170
|
+
.replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>')
|
|
171
|
+
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
|
172
|
+
.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
|
173
|
+
.replace(/~~(.+?)~~/g, '<del>$1</del>')
|
|
174
|
+
.replace(/`([^`]+)`/g, (_match, code) => `<code>${this.escapeHtml(code)}</code>`);
|
|
175
|
+
}
|
|
78
176
|
processHeadings(html) {
|
|
79
177
|
return html.replace(/^(#{1,6})\s+(.+)$/gm, (_match, hashes, text) => {
|
|
80
178
|
const level = hashes.length;
|
|
@@ -82,6 +180,29 @@ class MarkdownParser {
|
|
|
82
180
|
return `<h${level} id="${id}">${text}</h${level}>`;
|
|
83
181
|
});
|
|
84
182
|
}
|
|
183
|
+
processHorizontalRules(html) {
|
|
184
|
+
return html.replace(/^([-*_])\s*\1\s*\1[\s-]*$/gm, '<hr>');
|
|
185
|
+
}
|
|
186
|
+
processImages(html) {
|
|
187
|
+
return html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, alt, src) => {
|
|
188
|
+
return `<img src="${src}" alt="${alt}" loading="lazy">`;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
processLineBreaks(html) {
|
|
192
|
+
if (this.config.breaks) {
|
|
193
|
+
return html.replace(/\n/g, '<br>');
|
|
194
|
+
}
|
|
195
|
+
return html.replace(/\n\n/g, '</p><p>').replace(/\n/g, ' ');
|
|
196
|
+
}
|
|
197
|
+
processLinks(html) {
|
|
198
|
+
return html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_match, text, href) => {
|
|
199
|
+
const titleMatch = href.match(/^([^"]+)"([^"]+)"/);
|
|
200
|
+
if (titleMatch) {
|
|
201
|
+
return `<a href="${titleMatch[1]}" title="${titleMatch[2]}">${text}</a>`;
|
|
202
|
+
}
|
|
203
|
+
return `<a href="${href}">${text}</a>`;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
85
206
|
processLists(html) {
|
|
86
207
|
const lines = html.split('\n');
|
|
87
208
|
const result = [];
|
|
@@ -113,12 +234,6 @@ class MarkdownParser {
|
|
|
113
234
|
}
|
|
114
235
|
return result.join('\n');
|
|
115
236
|
}
|
|
116
|
-
processTaskLists(html) {
|
|
117
|
-
return html.replace(/^- \[([ x])\]\s+(.+)/gm, (_match, checked, text) => {
|
|
118
|
-
const isChecked = checked === 'x';
|
|
119
|
-
return `<li class="task"><input type="checkbox" ${isChecked ? 'checked' : ''} disabled>${text}</li>`;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
237
|
processTables(html) {
|
|
123
238
|
const rows = html.split('\n');
|
|
124
239
|
let inTable = false;
|
|
@@ -131,7 +246,10 @@ class MarkdownParser {
|
|
|
131
246
|
inTable = true;
|
|
132
247
|
headerProcessed = false;
|
|
133
248
|
}
|
|
134
|
-
const cells = row
|
|
249
|
+
const cells = row
|
|
250
|
+
.split('|')
|
|
251
|
+
.filter((c) => c.trim())
|
|
252
|
+
.map((c) => c.trim());
|
|
135
253
|
if (row.match(/^\|[\s-:]+\|$/)) {
|
|
136
254
|
continue;
|
|
137
255
|
}
|
|
@@ -163,144 +281,39 @@ class MarkdownParser {
|
|
|
163
281
|
}
|
|
164
282
|
return result.join('\n');
|
|
165
283
|
}
|
|
166
|
-
|
|
167
|
-
return html.replace(
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
return `<a href="${titleMatch[1]}" title="${titleMatch[2]}">${text}</a>`;
|
|
171
|
-
}
|
|
172
|
-
return `<a href="${href}">${text}</a>`;
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
processImages(html) {
|
|
176
|
-
return html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, alt, src) => {
|
|
177
|
-
return `<img src="${src}" alt="${alt}" loading="lazy">`;
|
|
284
|
+
processTaskLists(html) {
|
|
285
|
+
return html.replace(/^- \[([ x])\]\s+(.+)/gm, (_match, checked, text) => {
|
|
286
|
+
const isChecked = checked === 'x';
|
|
287
|
+
return `<li class="task"><input type="checkbox" ${isChecked ? 'checked' : ''} disabled>${text}</li>`;
|
|
178
288
|
});
|
|
179
289
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const result = [];
|
|
183
|
-
let inBlockquote = false;
|
|
184
|
-
let depth = 0;
|
|
185
|
-
for (const line of lines) {
|
|
186
|
-
const match = line.match(/^(\s*)>\s?(.*)/);
|
|
187
|
-
if (match) {
|
|
188
|
-
const indent = match[1].length;
|
|
189
|
-
const content = match[2];
|
|
190
|
-
const newDepth = Math.floor(indent / 2) + 1;
|
|
191
|
-
if (!inBlockquote) {
|
|
192
|
-
for (let i = 0; i < newDepth; i++) {
|
|
193
|
-
result.push('<blockquote>');
|
|
194
|
-
}
|
|
195
|
-
depth = newDepth;
|
|
196
|
-
inBlockquote = true;
|
|
197
|
-
}
|
|
198
|
-
else if (newDepth > depth) {
|
|
199
|
-
for (let i = depth; i < newDepth; i++) {
|
|
200
|
-
result.push('<blockquote>');
|
|
201
|
-
}
|
|
202
|
-
depth = newDepth;
|
|
203
|
-
}
|
|
204
|
-
else if (newDepth < depth) {
|
|
205
|
-
for (let i = depth; i > newDepth; i--) {
|
|
206
|
-
result.push('</blockquote>');
|
|
207
|
-
}
|
|
208
|
-
depth = newDepth;
|
|
209
|
-
}
|
|
210
|
-
result.push(content || '<br>');
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
if (inBlockquote) {
|
|
214
|
-
for (let i = depth; i > 0; i--) {
|
|
215
|
-
result.push('</blockquote>');
|
|
216
|
-
}
|
|
217
|
-
inBlockquote = false;
|
|
218
|
-
depth = 0;
|
|
219
|
-
}
|
|
220
|
-
result.push(line);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
if (inBlockquote) {
|
|
224
|
-
for (let i = depth; i > 0; i--) {
|
|
225
|
-
result.push('</blockquote>');
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
return result.join('\n');
|
|
229
|
-
}
|
|
230
|
-
processEmphasis(html) {
|
|
231
|
-
return html
|
|
232
|
-
.replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>')
|
|
233
|
-
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
|
234
|
-
.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
|
235
|
-
.replace(/~~(.+?)~~/g, '<del>$1</del>')
|
|
236
|
-
.replace(/`([^`]+)`/g, (_match, code) => `<code>${this.escapeHtml(code)}</code>`);
|
|
237
|
-
}
|
|
238
|
-
processHorizontalRules(html) {
|
|
239
|
-
return html.replace(/^([-*_])\s*\1\s*\1[\s-]*$/gm, '<hr>');
|
|
240
|
-
}
|
|
241
|
-
processLineBreaks(html) {
|
|
242
|
-
if (this.config.breaks) {
|
|
243
|
-
return html.replace(/\n/g, '<br>');
|
|
244
|
-
}
|
|
245
|
-
return html.replace(/\n\n/g, '</p><p>').replace(/\n/g, ' ');
|
|
290
|
+
removeFrontmatter(markdown) {
|
|
291
|
+
return markdown.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
246
292
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
293
|
+
renderMarkdown(content) {
|
|
294
|
+
// Step 1: Extract all fenced code blocks before any markdown processing
|
|
295
|
+
const codeBlocks = [];
|
|
296
|
+
let html = content.replace(/```(\w*)\n([\s\S]*?)```/g, (_match, lang, code) => {
|
|
297
|
+
const escaped = this.escapeHtml(code.trim());
|
|
298
|
+
codeBlocks.push(`<pre><code class="language-${lang}">${escaped}</code></pre>`);
|
|
299
|
+
return `\n__CODE_BLOCK_${codeBlocks.length - 1}__\n`;
|
|
300
|
+
});
|
|
301
|
+
// Step 2: Process all other markdown
|
|
302
|
+
html = this.processHeadings(html);
|
|
303
|
+
html = this.processHorizontalRules(html);
|
|
304
|
+
html = this.processLists(html);
|
|
305
|
+
html = this.processTaskLists(html);
|
|
306
|
+
html = this.processTables(html);
|
|
307
|
+
html = this.processImages(html);
|
|
308
|
+
html = this.processLinks(html);
|
|
309
|
+
html = this.processBlockquotes(html);
|
|
310
|
+
html = this.processEmphasis(html);
|
|
311
|
+
html = this.processLineBreaks(html);
|
|
312
|
+
html = this.processComponents(html);
|
|
313
|
+
// Step 3: Restore code blocks
|
|
314
|
+
html = html.replace(/__CODE_BLOCK_(\d+)__/g, (_, index) => codeBlocks[Number(index)]);
|
|
252
315
|
return html;
|
|
253
316
|
}
|
|
254
|
-
extractHeadings(html) {
|
|
255
|
-
const headings = [];
|
|
256
|
-
const regex = /<h(\d) id="([^"]+)">([^<]+)<\/h\1>/g;
|
|
257
|
-
let match;
|
|
258
|
-
while ((match = regex.exec(html)) !== null) {
|
|
259
|
-
headings.push({
|
|
260
|
-
level: parseInt(match[1]),
|
|
261
|
-
text: match[3],
|
|
262
|
-
id: match[2],
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
return headings;
|
|
266
|
-
}
|
|
267
|
-
extractLinks(content) {
|
|
268
|
-
const links = [];
|
|
269
|
-
const regex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
270
|
-
let match;
|
|
271
|
-
while ((match = regex.exec(content)) !== null) {
|
|
272
|
-
const href = match[2];
|
|
273
|
-
if (!href.startsWith('#') && !links.includes(href)) {
|
|
274
|
-
links.push(href);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return links;
|
|
278
|
-
}
|
|
279
|
-
extractImages(content) {
|
|
280
|
-
const images = [];
|
|
281
|
-
const regex = /!\[([^\]]*)\]\(([^)]+)\)/g;
|
|
282
|
-
let match;
|
|
283
|
-
while ((match = regex.exec(content)) !== null) {
|
|
284
|
-
const src = match[2];
|
|
285
|
-
const alt = match[1];
|
|
286
|
-
const titleMatch = src.match(/"([^"]+)"/);
|
|
287
|
-
const title = titleMatch ? titleMatch[1] : undefined;
|
|
288
|
-
images.push({ src, alt, title });
|
|
289
|
-
}
|
|
290
|
-
return images;
|
|
291
|
-
}
|
|
292
|
-
extractCodeBlocks(content) {
|
|
293
|
-
const blocks = [];
|
|
294
|
-
const regex = /```(\w*)\n([\s\S]*?)```/g;
|
|
295
|
-
let match;
|
|
296
|
-
while ((match = regex.exec(content)) !== null) {
|
|
297
|
-
blocks.push({
|
|
298
|
-
lang: match[1],
|
|
299
|
-
code: match[2].trim(),
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
return blocks;
|
|
303
|
-
}
|
|
304
317
|
slugify(text) {
|
|
305
318
|
return text
|
|
306
319
|
.toLowerCase()
|
|
@@ -309,13 +322,6 @@ class MarkdownParser {
|
|
|
309
322
|
.replace(/-+/g, '-')
|
|
310
323
|
.trim();
|
|
311
324
|
}
|
|
312
|
-
escapeHtml(text) {
|
|
313
|
-
return text
|
|
314
|
-
.replace(/&/g, '&')
|
|
315
|
-
.replace(/</g, '<')
|
|
316
|
-
.replace(/>/g, '>')
|
|
317
|
-
.replace(/"/g, '"');
|
|
318
|
-
}
|
|
319
325
|
}
|
|
320
326
|
export function createMarkdownParser(options) {
|
|
321
327
|
return new MarkdownParser(options);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { JSXElement } from '../runtime/types.js';
|
|
2
|
+
import { parseMarkdown } from '../markdown/index.js';
|
|
3
|
+
export interface MDXConfig {
|
|
4
|
+
gfm?: boolean;
|
|
5
|
+
breaks?: boolean;
|
|
6
|
+
tables?: boolean;
|
|
7
|
+
components?: Record<string, (props: Record<string, unknown>) => JSXElement>;
|
|
8
|
+
scope?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface MDXComponent {
|
|
11
|
+
(props: Record<string, unknown>): JSXElement;
|
|
12
|
+
frontmatter?: Record<string, unknown>;
|
|
13
|
+
metadata?: MDXMetadata;
|
|
14
|
+
}
|
|
15
|
+
export interface MDXMetadata {
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
author?: string;
|
|
19
|
+
date?: string;
|
|
20
|
+
tags?: string[];
|
|
21
|
+
readingTime?: number;
|
|
22
|
+
}
|
|
23
|
+
declare class MDXCompiler {
|
|
24
|
+
private components;
|
|
25
|
+
private config;
|
|
26
|
+
constructor(config?: MDXConfig);
|
|
27
|
+
compile(source: string): (props: Record<string, unknown>) => JSXElement;
|
|
28
|
+
getComponent(name: string): ((props: Record<string, unknown>) => JSXElement) | undefined;
|
|
29
|
+
registerComponent(name: string, component: (props: Record<string, unknown>) => JSXElement): void;
|
|
30
|
+
unregisterComponent(name: string): void;
|
|
31
|
+
private createComponent;
|
|
32
|
+
private extractHeadingIds;
|
|
33
|
+
private generateComponent;
|
|
34
|
+
private splitParagraphs;
|
|
35
|
+
}
|
|
36
|
+
export declare function createMDXCompiler(config?: MDXConfig): MDXCompiler;
|
|
37
|
+
export declare function compileMDX(source: string, options?: MDXConfig): Promise<MDXComponent>;
|
|
38
|
+
export declare function compileSync(source: string, options?: MDXConfig): MDXComponent;
|
|
39
|
+
export declare function useMDX(source: string, options?: MDXConfig): MDXComponent;
|
|
40
|
+
export declare const DEFAULT_COMPONENTS: Record<string, (props: Record<string, unknown>) => JSXElement>;
|
|
41
|
+
export declare function mergeComponents(base: Record<string, (props: Record<string, unknown>) => JSXElement>, override: Record<string, (props: Record<string, unknown>) => JSXElement>): Record<string, (props: Record<string, unknown>) => JSXElement>;
|
|
42
|
+
export { parseMarkdown };
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mdx/index.ts"],"names":[],"mappings":"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"}
|
package/dist/mdx/index.js
CHANGED
|
@@ -1,17 +1,56 @@
|
|
|
1
1
|
import { parseMarkdown } from '../markdown/index.js';
|
|
2
2
|
class MDXCompiler {
|
|
3
|
-
config;
|
|
4
3
|
components;
|
|
4
|
+
config;
|
|
5
5
|
constructor(config = {}) {
|
|
6
6
|
this.config = config;
|
|
7
7
|
this.components = new Map(Object.entries(config.components ?? {}));
|
|
8
8
|
}
|
|
9
9
|
compile(source) {
|
|
10
|
-
const parsed = parseMarkdown(source, {
|
|
10
|
+
const parsed = parseMarkdown(source, {
|
|
11
|
+
gfm: this.config.gfm,
|
|
12
|
+
breaks: this.config.breaks,
|
|
13
|
+
tables: this.config.tables,
|
|
14
|
+
});
|
|
11
15
|
const { html, frontmatter } = parsed;
|
|
12
16
|
const componentCode = this.generateComponent(html);
|
|
13
17
|
return this.createComponent(componentCode, frontmatter);
|
|
14
18
|
}
|
|
19
|
+
getComponent(name) {
|
|
20
|
+
return this.components.get(name);
|
|
21
|
+
}
|
|
22
|
+
registerComponent(name, component) {
|
|
23
|
+
this.components.set(name, component);
|
|
24
|
+
}
|
|
25
|
+
unregisterComponent(name) {
|
|
26
|
+
this.components.delete(name);
|
|
27
|
+
}
|
|
28
|
+
createComponent(code, frontmatter) {
|
|
29
|
+
try {
|
|
30
|
+
const fn = new Function('createElement', code);
|
|
31
|
+
const component = (props) => {
|
|
32
|
+
const element = fn(createElementProxy);
|
|
33
|
+
return element;
|
|
34
|
+
};
|
|
35
|
+
if (frontmatter) {
|
|
36
|
+
component.frontmatter = frontmatter;
|
|
37
|
+
}
|
|
38
|
+
return component;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error('MDX compilation error:', error);
|
|
42
|
+
return () => ({ type: 'div', props: { children: 'MDX Error' } });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
extractHeadingIds(html) {
|
|
46
|
+
const ids = [];
|
|
47
|
+
const regex = /id="([^"]+)"/g;
|
|
48
|
+
let match;
|
|
49
|
+
while ((match = regex.exec(html)) !== null) {
|
|
50
|
+
ids.push(match[1]);
|
|
51
|
+
}
|
|
52
|
+
return ids;
|
|
53
|
+
}
|
|
15
54
|
generateComponent(html) {
|
|
16
55
|
const headings = this.extractHeadingIds(html);
|
|
17
56
|
const paragraphs = this.splitParagraphs(html);
|
|
@@ -39,47 +78,12 @@ class MDXCompiler {
|
|
|
39
78
|
code += ')';
|
|
40
79
|
return code;
|
|
41
80
|
}
|
|
42
|
-
extractHeadingIds(html) {
|
|
43
|
-
const ids = [];
|
|
44
|
-
const regex = /id="([^"]+)"/g;
|
|
45
|
-
let match;
|
|
46
|
-
while ((match = regex.exec(html)) !== null) {
|
|
47
|
-
ids.push(match[1]);
|
|
48
|
-
}
|
|
49
|
-
return ids;
|
|
50
|
-
}
|
|
51
81
|
splitParagraphs(html) {
|
|
52
82
|
return html
|
|
53
83
|
.split(/\n\n+/)
|
|
54
84
|
.map((p) => p.trim())
|
|
55
85
|
.filter(Boolean);
|
|
56
86
|
}
|
|
57
|
-
createComponent(code, frontmatter) {
|
|
58
|
-
try {
|
|
59
|
-
const fn = new Function('createElement', code);
|
|
60
|
-
const component = (props) => {
|
|
61
|
-
const element = fn(createElementProxy);
|
|
62
|
-
return element;
|
|
63
|
-
};
|
|
64
|
-
if (frontmatter) {
|
|
65
|
-
component.frontmatter = frontmatter;
|
|
66
|
-
}
|
|
67
|
-
return component;
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
console.error('MDX compilation error:', error);
|
|
71
|
-
return () => ({ type: 'div', props: { children: 'MDX Error' } });
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
registerComponent(name, component) {
|
|
75
|
-
this.components.set(name, component);
|
|
76
|
-
}
|
|
77
|
-
unregisterComponent(name) {
|
|
78
|
-
this.components.delete(name);
|
|
79
|
-
}
|
|
80
|
-
getComponent(name) {
|
|
81
|
-
return this.components.get(name);
|
|
82
|
-
}
|
|
83
87
|
}
|
|
84
88
|
const createElementProxy = {
|
|
85
89
|
createElement(tag, props, ...children) {
|
|
@@ -142,10 +146,12 @@ export const DEFAULT_COMPONENTS = {
|
|
|
142
146
|
type: 'div',
|
|
143
147
|
props: {
|
|
144
148
|
className: 'table-wrapper',
|
|
145
|
-
children: [
|
|
149
|
+
children: [
|
|
150
|
+
{
|
|
146
151
|
type: 'table',
|
|
147
|
-
props: { children: [props.children] }
|
|
148
|
-
}
|
|
152
|
+
props: { children: [props.children] },
|
|
153
|
+
},
|
|
154
|
+
],
|
|
149
155
|
},
|
|
150
156
|
};
|
|
151
157
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/mdx/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1D,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAItF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head-registry.d.ts","sourceRoot":"","sources":["../../src/meta/head-registry.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { JSXNode } from '../runtime/types.js';
|
|
2
|
+
export interface HeadProps {
|
|
3
|
+
children?: JSXNode | JSXNode[];
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
og?: {
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
type?: string;
|
|
10
|
+
url?: string;
|
|
11
|
+
image?: string;
|
|
12
|
+
locale?: string;
|
|
13
|
+
siteName?: string;
|
|
14
|
+
};
|
|
15
|
+
twitter?: {
|
|
16
|
+
card?: string;
|
|
17
|
+
site?: string;
|
|
18
|
+
creator?: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
image?: string;
|
|
22
|
+
};
|
|
23
|
+
canonical?: string;
|
|
24
|
+
robots?: string;
|
|
25
|
+
keywords?: string[];
|
|
26
|
+
author?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function Head(props: HeadProps): JSXNode;
|
|
29
|
+
//# sourceMappingURL=head.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../src/meta/head.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAOnD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6FD,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAsB9C"}
|