@slidev/parser 52.10.1 → 52.11.1
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/core.d.mts +23 -2
- package/dist/core.mjs +401 -1
- package/dist/fs.d.mts +3 -3
- package/dist/fs.mjs +9 -7
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/utils.d.mts +1 -1
- package/package.json +3 -3
- package/dist/core-BdugCXPs.d.mts +0 -23
- package/dist/core-LJx9ovOy.mjs +0 -404
- /package/dist/{utils-DGym_nV3.d.mts → utils-BwHfBd2q.d.mts} +0 -0
package/dist/core.d.mts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-BwHfBd2q.mjs";
|
|
2
|
+
import { FontOptions, ResolvedFontOptions, SlidevConfig, SlidevDetectedFeatures, SlidevMarkdown, SlidevPreparserExtension, SlidevThemeMeta, SourceSlideInfo } from "@slidev/types";
|
|
3
|
+
|
|
4
|
+
//#region src/config.d.ts
|
|
5
|
+
declare function getDefaultConfig(): SlidevConfig;
|
|
6
|
+
declare function resolveConfig(headmatter: any, themeMeta?: SlidevThemeMeta, filepath?: string, verify?: boolean): SlidevConfig;
|
|
7
|
+
declare function verifyConfig(config: SlidevConfig, themeMeta?: SlidevThemeMeta, warn?: (v: string) => void): void;
|
|
8
|
+
declare function resolveFonts(fonts?: FontOptions): ResolvedFontOptions;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/core.d.ts
|
|
11
|
+
interface SlidevParserOptions {
|
|
12
|
+
noParseYAML?: boolean;
|
|
13
|
+
preserveCR?: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare function stringify(data: SlidevMarkdown): string;
|
|
16
|
+
declare function stringifySlide(data: SourceSlideInfo, idx?: number): string;
|
|
17
|
+
declare function prettifySlide(data: SourceSlideInfo): SourceSlideInfo;
|
|
18
|
+
declare function prettify(data: SlidevMarkdown): SlidevMarkdown;
|
|
19
|
+
declare function detectFeatures(code: string): SlidevDetectedFeatures;
|
|
20
|
+
declare function parseSlide(raw: string, options?: SlidevParserOptions): Omit<SourceSlideInfo, 'filepath' | 'index' | 'start' | 'contentStart' | 'end'>;
|
|
21
|
+
declare function parse(markdown: string, filepath: string, extensions?: SlidevPreparserExtension[], options?: SlidevParserOptions): Promise<SlidevMarkdown>;
|
|
22
|
+
declare function parseSync(markdown: string, filepath: string, options?: SlidevParserOptions): SlidevMarkdown;
|
|
23
|
+
//#endregion
|
|
3
24
|
export { SlidevParserOptions, TimesplitInput, TimesplitOutput, detectFeatures, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/core.mjs
CHANGED
|
@@ -1,4 +1,404 @@
|
|
|
1
1
|
import { i as parseTimeString, n as parseRangeString, r as parseTimesplits, t as parseAspectRatio } from "./utils-BiNCPCdQ.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { ensurePrefix, toArray, uniq } from "@antfu/utils";
|
|
3
|
+
import YAML from "yaml";
|
|
3
4
|
|
|
5
|
+
//#region src/config.ts
|
|
6
|
+
function getDefaultConfig() {
|
|
7
|
+
return {
|
|
8
|
+
theme: "default",
|
|
9
|
+
title: "Slidev",
|
|
10
|
+
titleTemplate: "%s - Slidev",
|
|
11
|
+
addons: [],
|
|
12
|
+
remoteAssets: false,
|
|
13
|
+
monaco: true,
|
|
14
|
+
monacoTypesSource: "local",
|
|
15
|
+
monacoTypesAdditionalPackages: [],
|
|
16
|
+
monacoTypesIgnorePackages: [],
|
|
17
|
+
monacoRunAdditionalDeps: [],
|
|
18
|
+
monacoRunUseStrict: true,
|
|
19
|
+
download: false,
|
|
20
|
+
export: {},
|
|
21
|
+
info: false,
|
|
22
|
+
highlighter: "shiki",
|
|
23
|
+
twoslash: true,
|
|
24
|
+
lineNumbers: false,
|
|
25
|
+
colorSchema: "auto",
|
|
26
|
+
routerMode: "history",
|
|
27
|
+
aspectRatio: 16 / 9,
|
|
28
|
+
canvasWidth: 980,
|
|
29
|
+
exportFilename: "",
|
|
30
|
+
selectable: false,
|
|
31
|
+
themeConfig: {},
|
|
32
|
+
fonts: {},
|
|
33
|
+
favicon: "https://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png",
|
|
34
|
+
drawings: {},
|
|
35
|
+
plantUmlServer: "https://www.plantuml.com/plantuml",
|
|
36
|
+
codeCopy: true,
|
|
37
|
+
magicMoveCopy: true,
|
|
38
|
+
author: "",
|
|
39
|
+
record: "dev",
|
|
40
|
+
css: "unocss",
|
|
41
|
+
presenter: true,
|
|
42
|
+
browserExporter: "dev",
|
|
43
|
+
htmlAttrs: {},
|
|
44
|
+
transition: null,
|
|
45
|
+
editor: true,
|
|
46
|
+
contextMenu: null,
|
|
47
|
+
wakeLock: true,
|
|
48
|
+
remote: false,
|
|
49
|
+
mdc: false,
|
|
50
|
+
seoMeta: {},
|
|
51
|
+
notesAutoRuby: {},
|
|
52
|
+
duration: "30min",
|
|
53
|
+
timer: "stopwatch",
|
|
54
|
+
magicMoveDuration: 800
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function resolveConfig(headmatter, themeMeta = {}, filepath, verify = false) {
|
|
58
|
+
const themeHightlighter = [
|
|
59
|
+
"prism",
|
|
60
|
+
"shiki",
|
|
61
|
+
"shikiji"
|
|
62
|
+
].includes(themeMeta.highlighter || "") ? themeMeta.highlighter : void 0;
|
|
63
|
+
const themeColorSchema = ["light", "dark"].includes(themeMeta.colorSchema || "") ? themeMeta.colorSchema : void 0;
|
|
64
|
+
const defaultConfig = getDefaultConfig();
|
|
65
|
+
const config = {
|
|
66
|
+
...defaultConfig,
|
|
67
|
+
highlighter: themeHightlighter || defaultConfig.highlighter,
|
|
68
|
+
colorSchema: themeColorSchema || defaultConfig.colorSchema,
|
|
69
|
+
...themeMeta.defaults,
|
|
70
|
+
...headmatter.config,
|
|
71
|
+
...headmatter,
|
|
72
|
+
fonts: resolveFonts({
|
|
73
|
+
...themeMeta.defaults?.fonts,
|
|
74
|
+
...headmatter.config?.fonts,
|
|
75
|
+
...headmatter?.fonts
|
|
76
|
+
}),
|
|
77
|
+
drawings: resolveDrawings(headmatter.drawings, filepath),
|
|
78
|
+
htmlAttrs: {
|
|
79
|
+
...themeMeta.defaults?.htmlAttrs,
|
|
80
|
+
...headmatter.config?.htmlAttrs,
|
|
81
|
+
...headmatter?.htmlAttrs
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
if (config.highlighter === "shikiji") {
|
|
85
|
+
console.warn(`[slidev] "shikiji" is merged back to "shiki", you can safely change it "highlighter: shiki"`);
|
|
86
|
+
config.highlighter = "shiki";
|
|
87
|
+
}
|
|
88
|
+
if (config.highlighter === "prism") throw new Error(`[slidev] "prism" support has been dropped. Please use "highlighter: shiki" instead`);
|
|
89
|
+
if (config.colorSchema !== "dark" && config.colorSchema !== "light") config.colorSchema = "auto";
|
|
90
|
+
if (themeColorSchema && config.colorSchema === "auto") config.colorSchema = themeColorSchema;
|
|
91
|
+
config.aspectRatio = parseAspectRatio(config.aspectRatio);
|
|
92
|
+
if (verify) verifyConfig(config, themeMeta);
|
|
93
|
+
return config;
|
|
94
|
+
}
|
|
95
|
+
function verifyConfig(config, themeMeta = {}, warn = (v) => console.warn(`[slidev] ${v}`)) {
|
|
96
|
+
const themeHightlighter = themeMeta.highlighter === "shiki" ? themeMeta.highlighter : void 0;
|
|
97
|
+
const themeColorSchema = ["light", "dark"].includes(themeMeta.colorSchema || "") ? themeMeta.colorSchema : void 0;
|
|
98
|
+
if (themeColorSchema && config.colorSchema !== themeColorSchema) warn(`Color schema "${config.colorSchema}" does not supported by the theme`);
|
|
99
|
+
if (themeHightlighter && config.highlighter !== themeHightlighter) warn(`Syntax highlighter "${config.highlighter}" does not supported by the theme`);
|
|
100
|
+
if (config.css !== "unocss") {
|
|
101
|
+
warn(`Unsupported Atomic CSS engine "${config.css}", fallback to UnoCSS`);
|
|
102
|
+
config.css = "unocss";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function resolveFonts(fonts = {}) {
|
|
106
|
+
const { fallbacks = true, italic = false, provider = "google" } = fonts;
|
|
107
|
+
let sans = toArray(fonts.sans).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
108
|
+
let serif = toArray(fonts.serif).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
109
|
+
let mono = toArray(fonts.mono).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
110
|
+
const weights = toArray(fonts.weights || "200,400,600").flatMap((i) => i.toString().split(/,\s*/g)).map((i) => i.trim());
|
|
111
|
+
const custom = toArray(fonts.custom).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
112
|
+
const local = toArray(fonts.local).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
113
|
+
const webfonts = fonts.webfonts ? fonts.webfonts : fallbacks ? uniq([
|
|
114
|
+
...sans,
|
|
115
|
+
...serif,
|
|
116
|
+
...mono,
|
|
117
|
+
...custom
|
|
118
|
+
]) : [];
|
|
119
|
+
webfonts.filter((i) => local.includes(i));
|
|
120
|
+
function toQuoted(font) {
|
|
121
|
+
if (/^(['"]).*\1$/.test(font)) return font;
|
|
122
|
+
return `"${font}"`;
|
|
123
|
+
}
|
|
124
|
+
if (fallbacks) {
|
|
125
|
+
sans = uniq([
|
|
126
|
+
...sans.map(toQuoted),
|
|
127
|
+
"ui-sans-serif",
|
|
128
|
+
"system-ui",
|
|
129
|
+
"-apple-system",
|
|
130
|
+
"BlinkMacSystemFont",
|
|
131
|
+
"\"Segoe UI\"",
|
|
132
|
+
"Roboto",
|
|
133
|
+
"\"Helvetica Neue\"",
|
|
134
|
+
"Arial",
|
|
135
|
+
"\"Noto Sans\"",
|
|
136
|
+
"sans-serif",
|
|
137
|
+
"\"Apple Color Emoji\"",
|
|
138
|
+
"\"Segoe UI Emoji\"",
|
|
139
|
+
"\"Segoe UI Symbol\"",
|
|
140
|
+
"\"Noto Color Emoji\""
|
|
141
|
+
]);
|
|
142
|
+
serif = uniq([
|
|
143
|
+
...serif.map(toQuoted),
|
|
144
|
+
"ui-serif",
|
|
145
|
+
"Georgia",
|
|
146
|
+
"Cambria",
|
|
147
|
+
"\"Times New Roman\"",
|
|
148
|
+
"Times",
|
|
149
|
+
"serif"
|
|
150
|
+
]);
|
|
151
|
+
mono = uniq([
|
|
152
|
+
...mono.map(toQuoted),
|
|
153
|
+
"ui-monospace",
|
|
154
|
+
"SFMono-Regular",
|
|
155
|
+
"Menlo",
|
|
156
|
+
"Monaco",
|
|
157
|
+
"Consolas",
|
|
158
|
+
"\"Liberation Mono\"",
|
|
159
|
+
"\"Courier New\"",
|
|
160
|
+
"monospace"
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
sans,
|
|
165
|
+
serif,
|
|
166
|
+
mono,
|
|
167
|
+
webfonts,
|
|
168
|
+
provider,
|
|
169
|
+
local,
|
|
170
|
+
italic,
|
|
171
|
+
weights
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function resolveDrawings(options = {}, filepath) {
|
|
175
|
+
const { enabled = true, persist = false, presenterOnly = false, syncAll = true } = options;
|
|
176
|
+
return {
|
|
177
|
+
enabled,
|
|
178
|
+
persist: typeof persist === "string" ? persist : persist ? `.slidev/drawings${filepath ? `/${filepath.match(/([^\\/]+?)(\.\w+)?$/)?.[1]}` : ""}` : false,
|
|
179
|
+
presenterOnly,
|
|
180
|
+
syncAll
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/core.ts
|
|
186
|
+
function stringify(data) {
|
|
187
|
+
return `${data.slides.map(stringifySlide).join("\n").trim()}\n`;
|
|
188
|
+
}
|
|
189
|
+
function stringifySlide(data, idx = 0) {
|
|
190
|
+
return data.raw.startsWith("---") || idx === 0 ? data.raw : `---\n${ensurePrefix("\n", data.raw)}`;
|
|
191
|
+
}
|
|
192
|
+
function prettifySlide(data) {
|
|
193
|
+
data.content = data.content.trim() ? `\n${data.content.trim()}\n` : "";
|
|
194
|
+
data.raw = data.frontmatterDoc?.contents ? data.frontmatterStyle === "yaml" ? `\`\`\`yaml\n${data.frontmatterDoc.toString().trim()}\n\`\`\`\n${data.content}` : `---\n${data.frontmatterDoc.toString().trim()}\n---\n${data.content}` : data.content;
|
|
195
|
+
if (data.note) data.raw += `\n<!--\n${data.note.trim()}\n-->\n`;
|
|
196
|
+
return data;
|
|
197
|
+
}
|
|
198
|
+
function prettify(data) {
|
|
199
|
+
data.slides.forEach(prettifySlide);
|
|
200
|
+
return data;
|
|
201
|
+
}
|
|
202
|
+
function matter(code, options) {
|
|
203
|
+
let type;
|
|
204
|
+
let raw;
|
|
205
|
+
let content = code.replace(/^---.*\r?\n([\s\S]*?)---/, (_, f) => {
|
|
206
|
+
type = "frontmatter";
|
|
207
|
+
raw = f;
|
|
208
|
+
return "";
|
|
209
|
+
});
|
|
210
|
+
if (type !== "frontmatter") content = content.replace(/^\s*```ya?ml([\s\S]*?)```/, (_, f) => {
|
|
211
|
+
type = "yaml";
|
|
212
|
+
raw = f;
|
|
213
|
+
return "";
|
|
214
|
+
});
|
|
215
|
+
const doc = raw && !options.noParseYAML ? YAML.parseDocument(raw) : void 0;
|
|
216
|
+
return {
|
|
217
|
+
type,
|
|
218
|
+
raw,
|
|
219
|
+
doc,
|
|
220
|
+
data: doc?.toJSON(),
|
|
221
|
+
content
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function detectFeatures(code) {
|
|
225
|
+
return {
|
|
226
|
+
katex: !!code.match(/\$.*?\$/) || !!code.match(/\$\$/),
|
|
227
|
+
monaco: code.match(/\{monaco.*\}/) ? scanMonacoReferencedMods(code) : false,
|
|
228
|
+
tweet: !!code.match(/<Tweet\b/),
|
|
229
|
+
mermaid: !!code.match(/^```mermaid/m)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function parseSlide(raw, options = {}) {
|
|
233
|
+
const matterResult = matter(raw, options);
|
|
234
|
+
let note;
|
|
235
|
+
const frontmatter = matterResult.data || {};
|
|
236
|
+
let content = matterResult.content.trim();
|
|
237
|
+
const revision = hash(raw.trim());
|
|
238
|
+
const comments = Array.from(content.matchAll(/<!--([\s\S]*?)-->/g));
|
|
239
|
+
if (comments.length) {
|
|
240
|
+
const last = comments[comments.length - 1];
|
|
241
|
+
if (last.index !== void 0 && last.index + last[0].length >= content.length) {
|
|
242
|
+
note = last[1].trim();
|
|
243
|
+
content = content.slice(0, last.index).trim();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
let title;
|
|
247
|
+
let level;
|
|
248
|
+
if (frontmatter.title || frontmatter.name) title = frontmatter.title || frontmatter.name;
|
|
249
|
+
else {
|
|
250
|
+
const match = content.match(/^(#+) (.*)$/m);
|
|
251
|
+
title = match?.[2]?.trim();
|
|
252
|
+
level = match?.[1]?.length;
|
|
253
|
+
}
|
|
254
|
+
if (frontmatter.level) level = frontmatter.level || 1;
|
|
255
|
+
return {
|
|
256
|
+
raw,
|
|
257
|
+
title,
|
|
258
|
+
level,
|
|
259
|
+
revision,
|
|
260
|
+
content,
|
|
261
|
+
contentRaw: content,
|
|
262
|
+
frontmatter,
|
|
263
|
+
frontmatterStyle: matterResult.type,
|
|
264
|
+
frontmatterDoc: matterResult.doc,
|
|
265
|
+
frontmatterRaw: matterResult.raw,
|
|
266
|
+
note
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
async function parse(markdown, filepath, extensions, options = {}) {
|
|
270
|
+
const lines = markdown.split(options.preserveCR ? "\n" : /\r?\n/g);
|
|
271
|
+
const slides = [];
|
|
272
|
+
let start = 0;
|
|
273
|
+
let contentStart = 0;
|
|
274
|
+
async function slice(end) {
|
|
275
|
+
if (start === end) return;
|
|
276
|
+
const slide = {
|
|
277
|
+
...parseSlide(lines.slice(start, end).join("\n"), options),
|
|
278
|
+
filepath,
|
|
279
|
+
index: slides.length,
|
|
280
|
+
start,
|
|
281
|
+
contentStart,
|
|
282
|
+
end
|
|
283
|
+
};
|
|
284
|
+
if (extensions) for (const e of extensions) {
|
|
285
|
+
if (e.transformSlide) {
|
|
286
|
+
const newContent = await e.transformSlide(slide.content, slide.frontmatter);
|
|
287
|
+
if (newContent !== void 0) slide.content = newContent;
|
|
288
|
+
if (typeof slide.frontmatter.title === "string") slide.title = slide.frontmatter.title;
|
|
289
|
+
if (typeof slide.frontmatter.level === "number") slide.level = slide.frontmatter.level;
|
|
290
|
+
}
|
|
291
|
+
if (e.transformNote) {
|
|
292
|
+
const newNote = await e.transformNote(slide.note, slide.frontmatter);
|
|
293
|
+
if (newNote !== void 0) slide.note = newNote;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
slides.push(slide);
|
|
297
|
+
start = end + 1;
|
|
298
|
+
contentStart = end + 1;
|
|
299
|
+
}
|
|
300
|
+
if (extensions) {
|
|
301
|
+
for (const e of extensions) if (e.transformRawLines) await e.transformRawLines(lines);
|
|
302
|
+
}
|
|
303
|
+
for (let i = 0; i < lines.length; i++) {
|
|
304
|
+
const line = lines[i].trimEnd();
|
|
305
|
+
if (line.startsWith("---")) {
|
|
306
|
+
await slice(i);
|
|
307
|
+
const next = lines[i + 1];
|
|
308
|
+
if (line[3] !== "-" && next?.trim()) {
|
|
309
|
+
start = i;
|
|
310
|
+
for (i += 1; i < lines.length; i++) if (lines[i].trimEnd() === "---") break;
|
|
311
|
+
contentStart = i + 1;
|
|
312
|
+
}
|
|
313
|
+
} else if (line.trimStart().startsWith("```")) {
|
|
314
|
+
const codeBlockLevel = line.match(/^\s*`+/)[0];
|
|
315
|
+
let j = i + 1;
|
|
316
|
+
for (; j < lines.length; j++) if (lines[j].startsWith(codeBlockLevel)) break;
|
|
317
|
+
if (j !== lines.length) i = j;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (start <= lines.length - 1) await slice(lines.length);
|
|
321
|
+
return {
|
|
322
|
+
filepath,
|
|
323
|
+
raw: markdown,
|
|
324
|
+
slides
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function parseSync(markdown, filepath, options = {}) {
|
|
328
|
+
const lines = markdown.split(options.preserveCR ? "\n" : /\r?\n/g);
|
|
329
|
+
const slides = [];
|
|
330
|
+
let start = 0;
|
|
331
|
+
let contentStart = 0;
|
|
332
|
+
function slice(end) {
|
|
333
|
+
if (start === end) return;
|
|
334
|
+
const slide = {
|
|
335
|
+
...parseSlide(lines.slice(start, end).join("\n"), options),
|
|
336
|
+
filepath,
|
|
337
|
+
index: slides.length,
|
|
338
|
+
start,
|
|
339
|
+
contentStart,
|
|
340
|
+
end
|
|
341
|
+
};
|
|
342
|
+
slides.push(slide);
|
|
343
|
+
start = end + 1;
|
|
344
|
+
contentStart = end + 1;
|
|
345
|
+
}
|
|
346
|
+
for (let i = 0; i < lines.length; i++) {
|
|
347
|
+
const line = lines[i].trimEnd();
|
|
348
|
+
if (line.startsWith("---")) {
|
|
349
|
+
slice(i);
|
|
350
|
+
const next = lines[i + 1];
|
|
351
|
+
if (line[3] !== "-" && next?.trim()) {
|
|
352
|
+
start = i;
|
|
353
|
+
for (i += 1; i < lines.length; i++) if (lines[i].trimEnd() === "---") break;
|
|
354
|
+
contentStart = i + 1;
|
|
355
|
+
}
|
|
356
|
+
} else if (line.trimStart().startsWith("```")) {
|
|
357
|
+
const codeBlockLevel = line.match(/^\s*`+/)[0];
|
|
358
|
+
let j = i + 1;
|
|
359
|
+
for (; j < lines.length; j++) if (lines[j].startsWith(codeBlockLevel)) break;
|
|
360
|
+
if (j !== lines.length) i = j;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (start <= lines.length - 1) slice(lines.length);
|
|
364
|
+
return {
|
|
365
|
+
filepath,
|
|
366
|
+
raw: markdown,
|
|
367
|
+
slides
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function scanMonacoReferencedMods(md) {
|
|
371
|
+
const types = /* @__PURE__ */ new Set();
|
|
372
|
+
const deps = /* @__PURE__ */ new Set();
|
|
373
|
+
md.replace(/^```(\w+)\s*\{monaco([^}]*)\}\s*(\S[\s\S]*?)^```/gm, (full, lang = "ts", kind, code) => {
|
|
374
|
+
lang = lang.trim();
|
|
375
|
+
const isDep = kind === "-run";
|
|
376
|
+
if ([
|
|
377
|
+
"js",
|
|
378
|
+
"javascript",
|
|
379
|
+
"ts",
|
|
380
|
+
"typescript"
|
|
381
|
+
].includes(lang)) {
|
|
382
|
+
for (const [, , specifier] of code.matchAll(/\s+from\s+(["'])([/.\w@-]+)\1/g)) if (specifier) {
|
|
383
|
+
if (!"./".includes(specifier)) types.add(specifier);
|
|
384
|
+
if (isDep) deps.add(specifier);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return "";
|
|
388
|
+
});
|
|
389
|
+
return {
|
|
390
|
+
types: Array.from(types),
|
|
391
|
+
deps: Array.from(deps)
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function hash(str) {
|
|
395
|
+
let hash$1 = 0;
|
|
396
|
+
for (let i = 0; i < str.length; i++) {
|
|
397
|
+
hash$1 = (hash$1 << 5) - hash$1 + str.charCodeAt(i);
|
|
398
|
+
hash$1 |= 0;
|
|
399
|
+
}
|
|
400
|
+
return hash$1.toString(36).slice(0, 12);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
//#endregion
|
|
4
404
|
export { detectFeatures, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/fs.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-BwHfBd2q.mjs";
|
|
2
|
+
import { SlidevParserOptions, detectFeatures, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
import { PreparserExtensionLoader, SlidevData, SlidevMarkdown } from "@slidev/types";
|
|
4
4
|
|
|
5
5
|
//#region src/fs.d.ts
|
|
@@ -9,7 +9,7 @@ declare function injectPreparserExtensionLoader(fn: PreparserExtensionLoader): v
|
|
|
9
9
|
* because config and themeMeta depends on the theme to be loaded.
|
|
10
10
|
*/
|
|
11
11
|
type LoadedSlidevData = Omit<SlidevData, 'config' | 'themeMeta'>;
|
|
12
|
-
declare function load(userRoot: string, filepath: string,
|
|
12
|
+
declare function load(userRoot: string, filepath: string, sources?: Record<string, string> | ((path: string) => Promise<string>), mode?: string): Promise<LoadedSlidevData>;
|
|
13
13
|
declare function save(markdown: SlidevMarkdown): Promise<string>;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { LoadedSlidevData, SlidevParserOptions, TimesplitInput, TimesplitOutput, detectFeatures, getDefaultConfig, injectPreparserExtensionLoader, load, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, save, stringify, stringifySlide, verifyConfig };
|
package/dist/fs.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { i as parseTimeString, n as parseRangeString, r as parseTimesplits, t as parseAspectRatio } from "./utils-BiNCPCdQ.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { detectFeatures, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
import { slash } from "@antfu/utils";
|
|
4
4
|
import YAML from "yaml";
|
|
5
|
-
import
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
6
7
|
import { dirname, resolve } from "node:path";
|
|
7
8
|
|
|
8
9
|
//#region src/fs.ts
|
|
@@ -10,8 +11,9 @@ let preparserExtensionLoader = null;
|
|
|
10
11
|
function injectPreparserExtensionLoader(fn) {
|
|
11
12
|
preparserExtensionLoader = fn;
|
|
12
13
|
}
|
|
13
|
-
async function load(userRoot, filepath,
|
|
14
|
-
const
|
|
14
|
+
async function load(userRoot, filepath, sources = {}, mode) {
|
|
15
|
+
const loadSource = typeof sources === "function" ? sources : async (path) => sources[path] ?? readFile(path, "utf-8");
|
|
16
|
+
const markdown = await loadSource(filepath);
|
|
15
17
|
let extensions;
|
|
16
18
|
if (preparserExtensionLoader) {
|
|
17
19
|
const lines = markdown.split(/\r?\n/g);
|
|
@@ -30,7 +32,7 @@ async function load(userRoot, filepath, loadedSource = {}, mode) {
|
|
|
30
32
|
async function loadMarkdown(path, range$1, frontmatterOverride, importers) {
|
|
31
33
|
let md = markdownFiles[path];
|
|
32
34
|
if (!md) {
|
|
33
|
-
md = await parse(
|
|
35
|
+
md = await parse(await loadSource(path), path, extensions);
|
|
34
36
|
markdownFiles[path] = md;
|
|
35
37
|
watchFiles[path] = /* @__PURE__ */ new Set();
|
|
36
38
|
}
|
|
@@ -61,7 +63,7 @@ async function load(userRoot, filepath, loadedSource = {}, mode) {
|
|
|
61
63
|
...frontmatterOverride
|
|
62
64
|
};
|
|
63
65
|
delete frontmatterOverride.src;
|
|
64
|
-
if (!
|
|
66
|
+
if (!existsSync(path)) {
|
|
65
67
|
md.errors ??= [];
|
|
66
68
|
md.errors.push({
|
|
67
69
|
row: slide.start,
|
|
@@ -98,7 +100,7 @@ async function load(userRoot, filepath, loadedSource = {}, mode) {
|
|
|
98
100
|
}
|
|
99
101
|
async function save(markdown) {
|
|
100
102
|
const fileContent = stringify(markdown);
|
|
101
|
-
|
|
103
|
+
await writeFile(markdown.filepath, fileContent, "utf-8");
|
|
102
104
|
return fileContent;
|
|
103
105
|
}
|
|
104
106
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-BwHfBd2q.mjs";
|
|
2
|
+
import { SlidevParserOptions, detectFeatures, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
export { SlidevParserOptions, TimesplitInput, TimesplitOutput, detectFeatures, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { i as parseTimeString, n as parseRangeString, r as parseTimesplits, t as parseAspectRatio } from "./utils-BiNCPCdQ.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { detectFeatures, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
|
|
4
4
|
export { detectFeatures, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/utils.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-BwHfBd2q.mjs";
|
|
2
2
|
export { TimesplitInput, TimesplitOutput, parseAspectRatio, parseRangeString, parseTimeString, parseTimesplits };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/parser",
|
|
3
|
-
"version": "52.
|
|
3
|
+
"version": "52.11.1",
|
|
4
4
|
"description": "Markdown parser for Slidev",
|
|
5
5
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@antfu/utils": "^9.3.0",
|
|
33
|
-
"yaml": "^2.8.
|
|
34
|
-
"@slidev/types": "52.
|
|
33
|
+
"yaml": "^2.8.2",
|
|
34
|
+
"@slidev/types": "52.11.1"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsdown",
|
package/dist/core-BdugCXPs.d.mts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { FontOptions, ResolvedFontOptions, SlidevConfig, SlidevDetectedFeatures, SlidevMarkdown, SlidevPreparserExtension, SlidevThemeMeta, SourceSlideInfo } from "@slidev/types";
|
|
2
|
-
|
|
3
|
-
//#region src/config.d.ts
|
|
4
|
-
declare function getDefaultConfig(): SlidevConfig;
|
|
5
|
-
declare function resolveConfig(headmatter: any, themeMeta?: SlidevThemeMeta, filepath?: string, verify?: boolean): SlidevConfig;
|
|
6
|
-
declare function verifyConfig(config: SlidevConfig, themeMeta?: SlidevThemeMeta, warn?: (v: string) => void): void;
|
|
7
|
-
declare function resolveFonts(fonts?: FontOptions): ResolvedFontOptions;
|
|
8
|
-
//#endregion
|
|
9
|
-
//#region src/core.d.ts
|
|
10
|
-
interface SlidevParserOptions {
|
|
11
|
-
noParseYAML?: boolean;
|
|
12
|
-
preserveCR?: boolean;
|
|
13
|
-
}
|
|
14
|
-
declare function stringify(data: SlidevMarkdown): string;
|
|
15
|
-
declare function stringifySlide(data: SourceSlideInfo, idx?: number): string;
|
|
16
|
-
declare function prettifySlide(data: SourceSlideInfo): SourceSlideInfo;
|
|
17
|
-
declare function prettify(data: SlidevMarkdown): SlidevMarkdown;
|
|
18
|
-
declare function detectFeatures(code: string): SlidevDetectedFeatures;
|
|
19
|
-
declare function parseSlide(raw: string, options?: SlidevParserOptions): Omit<SourceSlideInfo, 'filepath' | 'index' | 'start' | 'contentStart' | 'end'>;
|
|
20
|
-
declare function parse(markdown: string, filepath: string, extensions?: SlidevPreparserExtension[], options?: SlidevParserOptions): Promise<SlidevMarkdown>;
|
|
21
|
-
declare function parseSync(markdown: string, filepath: string, options?: SlidevParserOptions): SlidevMarkdown;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { parseSync as a, stringify as c, resolveConfig as d, resolveFonts as f, parseSlide as i, stringifySlide as l, detectFeatures as n, prettify as o, verifyConfig as p, parse as r, prettifySlide as s, SlidevParserOptions as t, getDefaultConfig as u };
|
package/dist/core-LJx9ovOy.mjs
DELETED
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import { t as parseAspectRatio } from "./utils-BiNCPCdQ.mjs";
|
|
2
|
-
import { ensurePrefix, toArray, uniq } from "@antfu/utils";
|
|
3
|
-
import YAML from "yaml";
|
|
4
|
-
|
|
5
|
-
//#region src/config.ts
|
|
6
|
-
function getDefaultConfig() {
|
|
7
|
-
return {
|
|
8
|
-
theme: "default",
|
|
9
|
-
title: "Slidev",
|
|
10
|
-
titleTemplate: "%s - Slidev",
|
|
11
|
-
addons: [],
|
|
12
|
-
remoteAssets: false,
|
|
13
|
-
monaco: true,
|
|
14
|
-
monacoTypesSource: "local",
|
|
15
|
-
monacoTypesAdditionalPackages: [],
|
|
16
|
-
monacoTypesIgnorePackages: [],
|
|
17
|
-
monacoRunAdditionalDeps: [],
|
|
18
|
-
monacoRunUseStrict: true,
|
|
19
|
-
download: false,
|
|
20
|
-
export: {},
|
|
21
|
-
info: false,
|
|
22
|
-
highlighter: "shiki",
|
|
23
|
-
twoslash: true,
|
|
24
|
-
lineNumbers: false,
|
|
25
|
-
colorSchema: "auto",
|
|
26
|
-
routerMode: "history",
|
|
27
|
-
aspectRatio: 16 / 9,
|
|
28
|
-
canvasWidth: 980,
|
|
29
|
-
exportFilename: "",
|
|
30
|
-
selectable: false,
|
|
31
|
-
themeConfig: {},
|
|
32
|
-
fonts: {},
|
|
33
|
-
favicon: "https://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png",
|
|
34
|
-
drawings: {},
|
|
35
|
-
plantUmlServer: "https://www.plantuml.com/plantuml",
|
|
36
|
-
codeCopy: true,
|
|
37
|
-
magicMoveCopy: true,
|
|
38
|
-
author: "",
|
|
39
|
-
record: "dev",
|
|
40
|
-
css: "unocss",
|
|
41
|
-
presenter: true,
|
|
42
|
-
browserExporter: "dev",
|
|
43
|
-
htmlAttrs: {},
|
|
44
|
-
transition: null,
|
|
45
|
-
editor: true,
|
|
46
|
-
contextMenu: null,
|
|
47
|
-
wakeLock: true,
|
|
48
|
-
remote: false,
|
|
49
|
-
mdc: false,
|
|
50
|
-
seoMeta: {},
|
|
51
|
-
notesAutoRuby: {},
|
|
52
|
-
duration: "30min",
|
|
53
|
-
timer: "stopwatch",
|
|
54
|
-
magicMoveDuration: 800
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function resolveConfig(headmatter, themeMeta = {}, filepath, verify = false) {
|
|
58
|
-
const themeHightlighter = [
|
|
59
|
-
"prism",
|
|
60
|
-
"shiki",
|
|
61
|
-
"shikiji"
|
|
62
|
-
].includes(themeMeta.highlighter || "") ? themeMeta.highlighter : void 0;
|
|
63
|
-
const themeColorSchema = ["light", "dark"].includes(themeMeta.colorSchema || "") ? themeMeta.colorSchema : void 0;
|
|
64
|
-
const defaultConfig = getDefaultConfig();
|
|
65
|
-
const config = {
|
|
66
|
-
...defaultConfig,
|
|
67
|
-
highlighter: themeHightlighter || defaultConfig.highlighter,
|
|
68
|
-
colorSchema: themeColorSchema || defaultConfig.colorSchema,
|
|
69
|
-
...themeMeta.defaults,
|
|
70
|
-
...headmatter.config,
|
|
71
|
-
...headmatter,
|
|
72
|
-
fonts: resolveFonts({
|
|
73
|
-
...themeMeta.defaults?.fonts,
|
|
74
|
-
...headmatter.config?.fonts,
|
|
75
|
-
...headmatter?.fonts
|
|
76
|
-
}),
|
|
77
|
-
drawings: resolveDrawings(headmatter.drawings, filepath),
|
|
78
|
-
htmlAttrs: {
|
|
79
|
-
...themeMeta.defaults?.htmlAttrs,
|
|
80
|
-
...headmatter.config?.htmlAttrs,
|
|
81
|
-
...headmatter?.htmlAttrs
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
if (config.highlighter === "shikiji") {
|
|
85
|
-
console.warn(`[slidev] "shikiji" is merged back to "shiki", you can safely change it "highlighter: shiki"`);
|
|
86
|
-
config.highlighter = "shiki";
|
|
87
|
-
}
|
|
88
|
-
if (config.highlighter === "prism") throw new Error(`[slidev] "prism" support has been dropped. Please use "highlighter: shiki" instead`);
|
|
89
|
-
if (config.colorSchema !== "dark" && config.colorSchema !== "light") config.colorSchema = "auto";
|
|
90
|
-
if (themeColorSchema && config.colorSchema === "auto") config.colorSchema = themeColorSchema;
|
|
91
|
-
config.aspectRatio = parseAspectRatio(config.aspectRatio);
|
|
92
|
-
if (verify) verifyConfig(config, themeMeta);
|
|
93
|
-
return config;
|
|
94
|
-
}
|
|
95
|
-
function verifyConfig(config, themeMeta = {}, warn = (v) => console.warn(`[slidev] ${v}`)) {
|
|
96
|
-
const themeHightlighter = themeMeta.highlighter === "shiki" ? themeMeta.highlighter : void 0;
|
|
97
|
-
const themeColorSchema = ["light", "dark"].includes(themeMeta.colorSchema || "") ? themeMeta.colorSchema : void 0;
|
|
98
|
-
if (themeColorSchema && config.colorSchema !== themeColorSchema) warn(`Color schema "${config.colorSchema}" does not supported by the theme`);
|
|
99
|
-
if (themeHightlighter && config.highlighter !== themeHightlighter) warn(`Syntax highlighter "${config.highlighter}" does not supported by the theme`);
|
|
100
|
-
if (config.css !== "unocss") {
|
|
101
|
-
warn(`Unsupported Atomic CSS engine "${config.css}", fallback to UnoCSS`);
|
|
102
|
-
config.css = "unocss";
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function resolveFonts(fonts = {}) {
|
|
106
|
-
const { fallbacks = true, italic = false, provider = "google" } = fonts;
|
|
107
|
-
let sans = toArray(fonts.sans).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
108
|
-
let serif = toArray(fonts.serif).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
109
|
-
let mono = toArray(fonts.mono).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
110
|
-
const weights = toArray(fonts.weights || "200,400,600").flatMap((i) => i.toString().split(/,\s*/g)).map((i) => i.trim());
|
|
111
|
-
const custom = toArray(fonts.custom).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
112
|
-
const local = toArray(fonts.local).flatMap((i) => i.split(/,\s*/g)).map((i) => i.trim());
|
|
113
|
-
const webfonts = fonts.webfonts ? fonts.webfonts : fallbacks ? uniq([
|
|
114
|
-
...sans,
|
|
115
|
-
...serif,
|
|
116
|
-
...mono,
|
|
117
|
-
...custom
|
|
118
|
-
]) : [];
|
|
119
|
-
webfonts.filter((i) => local.includes(i));
|
|
120
|
-
function toQuoted(font) {
|
|
121
|
-
if (/^(['"]).*\1$/.test(font)) return font;
|
|
122
|
-
return `"${font}"`;
|
|
123
|
-
}
|
|
124
|
-
if (fallbacks) {
|
|
125
|
-
sans = uniq([
|
|
126
|
-
...sans.map(toQuoted),
|
|
127
|
-
"ui-sans-serif",
|
|
128
|
-
"system-ui",
|
|
129
|
-
"-apple-system",
|
|
130
|
-
"BlinkMacSystemFont",
|
|
131
|
-
"\"Segoe UI\"",
|
|
132
|
-
"Roboto",
|
|
133
|
-
"\"Helvetica Neue\"",
|
|
134
|
-
"Arial",
|
|
135
|
-
"\"Noto Sans\"",
|
|
136
|
-
"sans-serif",
|
|
137
|
-
"\"Apple Color Emoji\"",
|
|
138
|
-
"\"Segoe UI Emoji\"",
|
|
139
|
-
"\"Segoe UI Symbol\"",
|
|
140
|
-
"\"Noto Color Emoji\""
|
|
141
|
-
]);
|
|
142
|
-
serif = uniq([
|
|
143
|
-
...serif.map(toQuoted),
|
|
144
|
-
"ui-serif",
|
|
145
|
-
"Georgia",
|
|
146
|
-
"Cambria",
|
|
147
|
-
"\"Times New Roman\"",
|
|
148
|
-
"Times",
|
|
149
|
-
"serif"
|
|
150
|
-
]);
|
|
151
|
-
mono = uniq([
|
|
152
|
-
...mono.map(toQuoted),
|
|
153
|
-
"ui-monospace",
|
|
154
|
-
"SFMono-Regular",
|
|
155
|
-
"Menlo",
|
|
156
|
-
"Monaco",
|
|
157
|
-
"Consolas",
|
|
158
|
-
"\"Liberation Mono\"",
|
|
159
|
-
"\"Courier New\"",
|
|
160
|
-
"monospace"
|
|
161
|
-
]);
|
|
162
|
-
}
|
|
163
|
-
return {
|
|
164
|
-
sans,
|
|
165
|
-
serif,
|
|
166
|
-
mono,
|
|
167
|
-
webfonts,
|
|
168
|
-
provider,
|
|
169
|
-
local,
|
|
170
|
-
italic,
|
|
171
|
-
weights
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function resolveDrawings(options = {}, filepath) {
|
|
175
|
-
const { enabled = true, persist = false, presenterOnly = false, syncAll = true } = options;
|
|
176
|
-
return {
|
|
177
|
-
enabled,
|
|
178
|
-
persist: typeof persist === "string" ? persist : persist ? `.slidev/drawings${filepath ? `/${filepath.match(/([^\\/]+?)(\.\w+)?$/)?.[1]}` : ""}` : false,
|
|
179
|
-
presenterOnly,
|
|
180
|
-
syncAll
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
//#endregion
|
|
185
|
-
//#region src/core.ts
|
|
186
|
-
function stringify(data) {
|
|
187
|
-
return `${data.slides.map(stringifySlide).join("\n").trim()}\n`;
|
|
188
|
-
}
|
|
189
|
-
function stringifySlide(data, idx = 0) {
|
|
190
|
-
return data.raw.startsWith("---") || idx === 0 ? data.raw : `---\n${ensurePrefix("\n", data.raw)}`;
|
|
191
|
-
}
|
|
192
|
-
function prettifySlide(data) {
|
|
193
|
-
data.content = data.content.trim() ? `\n${data.content.trim()}\n` : "";
|
|
194
|
-
data.raw = data.frontmatterDoc?.contents ? data.frontmatterStyle === "yaml" ? `\`\`\`yaml\n${data.frontmatterDoc.toString().trim()}\n\`\`\`\n${data.content}` : `---\n${data.frontmatterDoc.toString().trim()}\n---\n${data.content}` : data.content;
|
|
195
|
-
if (data.note) data.raw += `\n<!--\n${data.note.trim()}\n-->\n`;
|
|
196
|
-
return data;
|
|
197
|
-
}
|
|
198
|
-
function prettify(data) {
|
|
199
|
-
data.slides.forEach(prettifySlide);
|
|
200
|
-
return data;
|
|
201
|
-
}
|
|
202
|
-
function matter(code, options) {
|
|
203
|
-
let type;
|
|
204
|
-
let raw;
|
|
205
|
-
let content = code.replace(/^---.*\r?\n([\s\S]*?)---/, (_, f) => {
|
|
206
|
-
type = "frontmatter";
|
|
207
|
-
raw = f;
|
|
208
|
-
return "";
|
|
209
|
-
});
|
|
210
|
-
if (type !== "frontmatter") content = content.replace(/^\s*```ya?ml([\s\S]*?)```/, (_, f) => {
|
|
211
|
-
type = "yaml";
|
|
212
|
-
raw = f;
|
|
213
|
-
return "";
|
|
214
|
-
});
|
|
215
|
-
const doc = raw && !options.noParseYAML ? YAML.parseDocument(raw) : void 0;
|
|
216
|
-
return {
|
|
217
|
-
type,
|
|
218
|
-
raw,
|
|
219
|
-
doc,
|
|
220
|
-
data: doc?.toJSON(),
|
|
221
|
-
content
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
function detectFeatures(code) {
|
|
225
|
-
return {
|
|
226
|
-
katex: !!code.match(/\$.*?\$/) || !!code.match(/\$\$/),
|
|
227
|
-
monaco: code.match(/\{monaco.*\}/) ? scanMonacoReferencedMods(code) : false,
|
|
228
|
-
tweet: !!code.match(/<Tweet\b/),
|
|
229
|
-
mermaid: !!code.match(/^```mermaid/m)
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
function parseSlide(raw, options = {}) {
|
|
233
|
-
const matterResult = matter(raw, options);
|
|
234
|
-
let note;
|
|
235
|
-
const frontmatter = matterResult.data || {};
|
|
236
|
-
let content = matterResult.content.trim();
|
|
237
|
-
const revision = hash(raw.trim());
|
|
238
|
-
const comments = Array.from(content.matchAll(/<!--([\s\S]*?)-->/g));
|
|
239
|
-
if (comments.length) {
|
|
240
|
-
const last = comments[comments.length - 1];
|
|
241
|
-
if (last.index !== void 0 && last.index + last[0].length >= content.length) {
|
|
242
|
-
note = last[1].trim();
|
|
243
|
-
content = content.slice(0, last.index).trim();
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
let title;
|
|
247
|
-
let level;
|
|
248
|
-
if (frontmatter.title || frontmatter.name) title = frontmatter.title || frontmatter.name;
|
|
249
|
-
else {
|
|
250
|
-
const match = content.match(/^(#+) (.*)$/m);
|
|
251
|
-
title = match?.[2]?.trim();
|
|
252
|
-
level = match?.[1]?.length;
|
|
253
|
-
}
|
|
254
|
-
if (frontmatter.level) level = frontmatter.level || 1;
|
|
255
|
-
return {
|
|
256
|
-
raw,
|
|
257
|
-
title,
|
|
258
|
-
level,
|
|
259
|
-
revision,
|
|
260
|
-
content,
|
|
261
|
-
contentRaw: content,
|
|
262
|
-
frontmatter,
|
|
263
|
-
frontmatterStyle: matterResult.type,
|
|
264
|
-
frontmatterDoc: matterResult.doc,
|
|
265
|
-
frontmatterRaw: matterResult.raw,
|
|
266
|
-
note
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
async function parse(markdown, filepath, extensions, options = {}) {
|
|
270
|
-
const lines = markdown.split(options.preserveCR ? "\n" : /\r?\n/g);
|
|
271
|
-
const slides = [];
|
|
272
|
-
let start = 0;
|
|
273
|
-
let contentStart = 0;
|
|
274
|
-
async function slice(end) {
|
|
275
|
-
if (start === end) return;
|
|
276
|
-
const slide = {
|
|
277
|
-
...parseSlide(lines.slice(start, end).join("\n"), options),
|
|
278
|
-
filepath,
|
|
279
|
-
index: slides.length,
|
|
280
|
-
start,
|
|
281
|
-
contentStart,
|
|
282
|
-
end
|
|
283
|
-
};
|
|
284
|
-
if (extensions) for (const e of extensions) {
|
|
285
|
-
if (e.transformSlide) {
|
|
286
|
-
const newContent = await e.transformSlide(slide.content, slide.frontmatter);
|
|
287
|
-
if (newContent !== void 0) slide.content = newContent;
|
|
288
|
-
if (typeof slide.frontmatter.title === "string") slide.title = slide.frontmatter.title;
|
|
289
|
-
if (typeof slide.frontmatter.level === "number") slide.level = slide.frontmatter.level;
|
|
290
|
-
}
|
|
291
|
-
if (e.transformNote) {
|
|
292
|
-
const newNote = await e.transformNote(slide.note, slide.frontmatter);
|
|
293
|
-
if (newNote !== void 0) slide.note = newNote;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
slides.push(slide);
|
|
297
|
-
start = end + 1;
|
|
298
|
-
contentStart = end + 1;
|
|
299
|
-
}
|
|
300
|
-
if (extensions) {
|
|
301
|
-
for (const e of extensions) if (e.transformRawLines) await e.transformRawLines(lines);
|
|
302
|
-
}
|
|
303
|
-
for (let i = 0; i < lines.length; i++) {
|
|
304
|
-
const line = lines[i].trimEnd();
|
|
305
|
-
if (line.startsWith("---")) {
|
|
306
|
-
await slice(i);
|
|
307
|
-
const next = lines[i + 1];
|
|
308
|
-
if (line[3] !== "-" && next?.trim()) {
|
|
309
|
-
start = i;
|
|
310
|
-
for (i += 1; i < lines.length; i++) if (lines[i].trimEnd() === "---") break;
|
|
311
|
-
contentStart = i + 1;
|
|
312
|
-
}
|
|
313
|
-
} else if (line.trimStart().startsWith("```")) {
|
|
314
|
-
const codeBlockLevel = line.match(/^\s*`+/)[0];
|
|
315
|
-
let j = i + 1;
|
|
316
|
-
for (; j < lines.length; j++) if (lines[j].startsWith(codeBlockLevel)) break;
|
|
317
|
-
if (j !== lines.length) i = j;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
if (start <= lines.length - 1) await slice(lines.length);
|
|
321
|
-
return {
|
|
322
|
-
filepath,
|
|
323
|
-
raw: markdown,
|
|
324
|
-
slides
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
function parseSync(markdown, filepath, options = {}) {
|
|
328
|
-
const lines = markdown.split(options.preserveCR ? "\n" : /\r?\n/g);
|
|
329
|
-
const slides = [];
|
|
330
|
-
let start = 0;
|
|
331
|
-
let contentStart = 0;
|
|
332
|
-
function slice(end) {
|
|
333
|
-
if (start === end) return;
|
|
334
|
-
const slide = {
|
|
335
|
-
...parseSlide(lines.slice(start, end).join("\n"), options),
|
|
336
|
-
filepath,
|
|
337
|
-
index: slides.length,
|
|
338
|
-
start,
|
|
339
|
-
contentStart,
|
|
340
|
-
end
|
|
341
|
-
};
|
|
342
|
-
slides.push(slide);
|
|
343
|
-
start = end + 1;
|
|
344
|
-
contentStart = end + 1;
|
|
345
|
-
}
|
|
346
|
-
for (let i = 0; i < lines.length; i++) {
|
|
347
|
-
const line = lines[i].trimEnd();
|
|
348
|
-
if (line.startsWith("---")) {
|
|
349
|
-
slice(i);
|
|
350
|
-
const next = lines[i + 1];
|
|
351
|
-
if (line[3] !== "-" && next?.trim()) {
|
|
352
|
-
start = i;
|
|
353
|
-
for (i += 1; i < lines.length; i++) if (lines[i].trimEnd() === "---") break;
|
|
354
|
-
contentStart = i + 1;
|
|
355
|
-
}
|
|
356
|
-
} else if (line.trimStart().startsWith("```")) {
|
|
357
|
-
const codeBlockLevel = line.match(/^\s*`+/)[0];
|
|
358
|
-
let j = i + 1;
|
|
359
|
-
for (; j < lines.length; j++) if (lines[j].startsWith(codeBlockLevel)) break;
|
|
360
|
-
if (j !== lines.length) i = j;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
if (start <= lines.length - 1) slice(lines.length);
|
|
364
|
-
return {
|
|
365
|
-
filepath,
|
|
366
|
-
raw: markdown,
|
|
367
|
-
slides
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
function scanMonacoReferencedMods(md) {
|
|
371
|
-
const types = /* @__PURE__ */ new Set();
|
|
372
|
-
const deps = /* @__PURE__ */ new Set();
|
|
373
|
-
md.replace(/^```(\w+)\s*\{monaco([^}]*)\}\s*(\S[\s\S]*?)^```/gm, (full, lang = "ts", kind, code) => {
|
|
374
|
-
lang = lang.trim();
|
|
375
|
-
const isDep = kind === "-run";
|
|
376
|
-
if ([
|
|
377
|
-
"js",
|
|
378
|
-
"javascript",
|
|
379
|
-
"ts",
|
|
380
|
-
"typescript"
|
|
381
|
-
].includes(lang)) {
|
|
382
|
-
for (const [, , specifier] of code.matchAll(/\s+from\s+(["'])([/.\w@-]+)\1/g)) if (specifier) {
|
|
383
|
-
if (!"./".includes(specifier)) types.add(specifier);
|
|
384
|
-
if (isDep) deps.add(specifier);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
return "";
|
|
388
|
-
});
|
|
389
|
-
return {
|
|
390
|
-
types: Array.from(types),
|
|
391
|
-
deps: Array.from(deps)
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
function hash(str) {
|
|
395
|
-
let hash$1 = 0;
|
|
396
|
-
for (let i = 0; i < str.length; i++) {
|
|
397
|
-
hash$1 = (hash$1 << 5) - hash$1 + str.charCodeAt(i);
|
|
398
|
-
hash$1 |= 0;
|
|
399
|
-
}
|
|
400
|
-
return hash$1.toString(36).slice(0, 12);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
//#endregion
|
|
404
|
-
export { prettify as a, stringifySlide as c, resolveFonts as d, verifyConfig as f, parseSync as i, getDefaultConfig as l, parse as n, prettifySlide as o, parseSlide as r, stringify as s, detectFeatures as t, resolveConfig as u };
|
|
File without changes
|