@slidev/cli 0.48.0-beta.14 → 0.48.0-beta.16
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/{build-YCAT4XDK.mjs → build-BFCSVURA.mjs} +4 -39
- package/dist/{chunk-CNK7IOIE.mjs → chunk-6SJIO2WJ.mjs} +3 -3
- package/dist/{chunk-7HOZGSL4.mjs → chunk-G3BP3FUT.mjs} +0 -1
- package/dist/{chunk-6NOVKCAJ.mjs → chunk-TMXTXTYI.mjs} +1578 -1419
- package/dist/cli.mjs +9 -9
- package/dist/{export-SM2ZATWB.mjs → export-JD32O5W6.mjs} +1 -1
- package/dist/index.mjs +3 -3
- package/package.json +6 -8
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
resolveImportPath,
|
|
6
6
|
toAtFS
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-G3BP3FUT.mjs";
|
|
8
8
|
import {
|
|
9
9
|
__commonJS,
|
|
10
10
|
__toESM
|
|
@@ -2496,7 +2496,7 @@ var require_semver2 = __commonJS({
|
|
|
2496
2496
|
});
|
|
2497
2497
|
|
|
2498
2498
|
// package.json
|
|
2499
|
-
var version = "0.48.0-beta.
|
|
2499
|
+
var version = "0.48.0-beta.16";
|
|
2500
2500
|
|
|
2501
2501
|
// node/common.ts
|
|
2502
2502
|
import { existsSync, promises as fs } from "node:fs";
|
|
@@ -2563,9 +2563,9 @@ async function mergeViteConfigs({ roots, entry }, viteConfig, config, command) {
|
|
|
2563
2563
|
}
|
|
2564
2564
|
|
|
2565
2565
|
// node/plugins/preset.ts
|
|
2566
|
-
import { join as
|
|
2566
|
+
import { join as join6 } from "node:path";
|
|
2567
2567
|
import { existsSync as existsSync3 } from "node:fs";
|
|
2568
|
-
import
|
|
2568
|
+
import process2 from "node:process";
|
|
2569
2569
|
import { fileURLToPath } from "node:url";
|
|
2570
2570
|
import Vue from "@vitejs/plugin-vue";
|
|
2571
2571
|
import VueJsx from "@vitejs/plugin-vue-jsx";
|
|
@@ -2645,6 +2645,11 @@ var EXCLUDE = [
|
|
|
2645
2645
|
"vue-demi",
|
|
2646
2646
|
"vue"
|
|
2647
2647
|
];
|
|
2648
|
+
var ASYNC_MODULES = [
|
|
2649
|
+
"file-saver",
|
|
2650
|
+
"vue",
|
|
2651
|
+
"@vue"
|
|
2652
|
+
];
|
|
2648
2653
|
function createConfigPlugin(options) {
|
|
2649
2654
|
return {
|
|
2650
2655
|
name: "slidev:config",
|
|
@@ -2680,8 +2685,40 @@ function createConfigPlugin(options) {
|
|
|
2680
2685
|
])
|
|
2681
2686
|
}
|
|
2682
2687
|
},
|
|
2683
|
-
publicDir: join3(options.userRoot, "public")
|
|
2688
|
+
publicDir: join3(options.userRoot, "public"),
|
|
2689
|
+
build: {
|
|
2690
|
+
rollupOptions: {
|
|
2691
|
+
output: {
|
|
2692
|
+
chunkFileNames(chunkInfo) {
|
|
2693
|
+
const DEFAULT = "[name]-[hash].js";
|
|
2694
|
+
if (chunkInfo.name.includes("/") || chunkInfo.name === "entry")
|
|
2695
|
+
return DEFAULT;
|
|
2696
|
+
if (chunkInfo.moduleIds.filter((i) => isSlidevClient(i)).length > chunkInfo.moduleIds.length * 0.6)
|
|
2697
|
+
return "slidev/[name]-[hash].js";
|
|
2698
|
+
if (chunkInfo.moduleIds.filter((i) => i.includes("/monaco-editor/")).length > chunkInfo.moduleIds.length * 0.6)
|
|
2699
|
+
return "monaco/[name]-[hash].js";
|
|
2700
|
+
return DEFAULT;
|
|
2701
|
+
},
|
|
2702
|
+
manualChunks(id) {
|
|
2703
|
+
if (id.startsWith("/@slidev-monaco-types/") || id.includes("/@slidev/monaco-types") || id.match(/(\.d\.[mc]?ts|package.json)\?raw$/))
|
|
2704
|
+
return "monaco/bundled-types";
|
|
2705
|
+
if (id.includes("/shiki/") || id.includes("/@shikijs/"))
|
|
2706
|
+
return `modules/shiki`;
|
|
2707
|
+
if (id.startsWith("~icons/"))
|
|
2708
|
+
return "modules/unplugin-icons";
|
|
2709
|
+
if (id.includes("/client/main.ts"))
|
|
2710
|
+
return "entry";
|
|
2711
|
+
const matchedAsyncModule = ASYNC_MODULES.find((i) => id.includes(`/node_modules/${i}`));
|
|
2712
|
+
if (matchedAsyncModule)
|
|
2713
|
+
return `modules/${matchedAsyncModule.replace("@", "").replace("/", "-")}`;
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2684
2718
|
};
|
|
2719
|
+
function isSlidevClient(id) {
|
|
2720
|
+
return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
|
|
2721
|
+
}
|
|
2685
2722
|
if (isInstalledGlobally) {
|
|
2686
2723
|
injection.cacheDir = join3(options.cliRoot, "node_modules/.vite");
|
|
2687
2724
|
injection.root = options.cliRoot;
|
|
@@ -2718,1504 +2755,1560 @@ function getDefine(options) {
|
|
|
2718
2755
|
}
|
|
2719
2756
|
|
|
2720
2757
|
// node/plugins/loaders.ts
|
|
2721
|
-
import { basename as basename2, join as join4 } from "node:path";
|
|
2722
|
-
import {
|
|
2758
|
+
import { basename as basename2, join as join4, resolve as resolve2 } from "node:path";
|
|
2759
|
+
import { builtinModules } from "node:module";
|
|
2760
|
+
import { isString, isTruthy as isTruthy2, notNullish, objectMap, range } from "@antfu/utils";
|
|
2723
2761
|
import fg2 from "fast-glob";
|
|
2724
|
-
import
|
|
2725
|
-
import
|
|
2762
|
+
import fs5 from "fs-extra";
|
|
2763
|
+
import Markdown2 from "markdown-it";
|
|
2726
2764
|
import { bold, gray, red, yellow } from "kolorist";
|
|
2727
|
-
import
|
|
2765
|
+
import mila2 from "markdown-it-link-attributes";
|
|
2728
2766
|
import * as parser from "@slidev/parser/fs";
|
|
2729
2767
|
import equal from "fast-deep-equal";
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2768
|
+
|
|
2769
|
+
// node/plugins/markdown.ts
|
|
2770
|
+
import fs4 from "node:fs/promises";
|
|
2771
|
+
import Markdown from "unplugin-vue-markdown/vite";
|
|
2772
|
+
import { isTruthy, slash } from "@antfu/utils";
|
|
2773
|
+
|
|
2774
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
2775
|
+
var SpecialCharacters;
|
|
2776
|
+
(function(SpecialCharacters2) {
|
|
2777
|
+
SpecialCharacters2[SpecialCharacters2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
|
|
2778
|
+
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
2779
|
+
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
2780
|
+
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
2781
|
+
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
2782
|
+
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
2783
|
+
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
2784
|
+
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
2785
|
+
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
2786
|
+
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
2787
|
+
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
2788
|
+
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
2789
|
+
|
|
2790
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
2791
|
+
import Token from "markdown-it/lib/token.mjs";
|
|
2792
|
+
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
2793
|
+
function taskLists(md2, options = { enabled: false, label: false, lineNumber: false }) {
|
|
2794
|
+
md2.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
2795
|
+
md2.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
2796
|
+
const token = tokens[0];
|
|
2797
|
+
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
2798
|
+
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
2799
|
+
const line = token.attrGet("line");
|
|
2800
|
+
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
2801
|
+
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
2802
|
+
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
2803
|
+
};
|
|
2804
|
+
md2.renderer.rules.taskListItemLabel_close = () => {
|
|
2805
|
+
return "</label>";
|
|
2806
|
+
};
|
|
2807
|
+
md2.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
2808
|
+
const token = tokens[0];
|
|
2809
|
+
const id = token.attrGet("id");
|
|
2810
|
+
return `<label for="${id}">`;
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
function processToken(state, options) {
|
|
2814
|
+
const allTokens = state.tokens;
|
|
2815
|
+
for (let i = 2; i < allTokens.length; i++) {
|
|
2816
|
+
if (!isTodoItem(allTokens, i)) {
|
|
2817
|
+
continue;
|
|
2818
|
+
}
|
|
2819
|
+
todoify(allTokens[i], options);
|
|
2820
|
+
allTokens[i - 2].attrJoin("class", `task-list-item ${options.enabled ? " enabled" : ""}`);
|
|
2821
|
+
const parentToken = findParentToken(allTokens, i - 2);
|
|
2822
|
+
if (parentToken) {
|
|
2823
|
+
const classes = parentToken.attrGet("class") ?? "";
|
|
2824
|
+
if (!classes.match(/(^| )contains-task-list/)) {
|
|
2825
|
+
parentToken.attrJoin("class", "contains-task-list");
|
|
2749
2826
|
}
|
|
2750
|
-
}
|
|
2751
|
-
}
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
return false;
|
|
2752
2830
|
}
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2831
|
+
function findParentToken(tokens, index) {
|
|
2832
|
+
const targetLevel = tokens[index].level - 1;
|
|
2833
|
+
for (let currentTokenIndex = index - 1; currentTokenIndex >= 0; currentTokenIndex--) {
|
|
2834
|
+
if (tokens[currentTokenIndex].level === targetLevel) {
|
|
2835
|
+
return tokens[currentTokenIndex];
|
|
2836
|
+
}
|
|
2758
2837
|
}
|
|
2759
|
-
|
|
2760
|
-
function renderNote(text = "") {
|
|
2761
|
-
let clickCount = 0;
|
|
2762
|
-
const html = md.render(
|
|
2763
|
-
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
2764
|
-
clickCount += Number(count);
|
|
2765
|
-
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
2766
|
-
})
|
|
2767
|
-
);
|
|
2768
|
-
return html;
|
|
2838
|
+
return void 0;
|
|
2769
2839
|
}
|
|
2770
|
-
function
|
|
2840
|
+
function isTodoItem(tokens, index) {
|
|
2841
|
+
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
2842
|
+
}
|
|
2843
|
+
function todoify(token, options) {
|
|
2844
|
+
if (token.children == null) {
|
|
2845
|
+
return;
|
|
2846
|
+
}
|
|
2847
|
+
const id = generateIdForToken(token);
|
|
2848
|
+
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
2849
|
+
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
2850
|
+
if (options.label) {
|
|
2851
|
+
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
2852
|
+
token.children.push(createLabelEndToken());
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
function generateIdForToken(token) {
|
|
2856
|
+
if (token.map) {
|
|
2857
|
+
return `task-item-${token.map[0]}`;
|
|
2858
|
+
} else {
|
|
2859
|
+
return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
function createCheckboxToken(token, enabled, id) {
|
|
2863
|
+
const checkbox = new Token("taskListItemCheckbox", "", 0);
|
|
2864
|
+
if (!enabled) {
|
|
2865
|
+
checkbox.attrSet("disabled", "true");
|
|
2866
|
+
}
|
|
2867
|
+
if (token.map) {
|
|
2868
|
+
checkbox.attrSet("line", token.map[0].toString());
|
|
2869
|
+
}
|
|
2870
|
+
checkbox.attrSet("id", id);
|
|
2871
|
+
const checkboxRegexResult = checkboxRegex.exec(token.content);
|
|
2872
|
+
const isChecked = checkboxRegexResult?.[1].toLowerCase() === "x";
|
|
2873
|
+
if (isChecked) {
|
|
2874
|
+
checkbox.attrSet("checked", "true");
|
|
2875
|
+
}
|
|
2876
|
+
return checkbox;
|
|
2877
|
+
}
|
|
2878
|
+
function createLabelBeginToken(id) {
|
|
2879
|
+
const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
|
|
2880
|
+
labelBeginToken.attrSet("id", id);
|
|
2881
|
+
return labelBeginToken;
|
|
2882
|
+
}
|
|
2883
|
+
function createLabelEndToken() {
|
|
2884
|
+
return new Token("taskListItemLabel_close", "", -1);
|
|
2885
|
+
}
|
|
2886
|
+
function isInline(token) {
|
|
2887
|
+
return token.type === "inline";
|
|
2888
|
+
}
|
|
2889
|
+
function isParagraph(token) {
|
|
2890
|
+
return token.type === "paragraph_open";
|
|
2891
|
+
}
|
|
2892
|
+
function isListItem(token) {
|
|
2893
|
+
return token.type === "list_item_open";
|
|
2894
|
+
}
|
|
2895
|
+
function startsWithTodoMarkdown(token) {
|
|
2896
|
+
return checkboxRegex.test(token.content);
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/toc/plugin.js
|
|
2900
|
+
import { Optional } from "@mrdrogdrog/optional";
|
|
2901
|
+
|
|
2902
|
+
// node/plugins/markdown.ts
|
|
2903
|
+
import { encode as encodePlantUml } from "plantuml-encoder";
|
|
2904
|
+
import Mdc from "markdown-it-mdc";
|
|
2905
|
+
import { codeToKeyedTokens, createMagicMoveMachine } from "shiki-magic-move/core";
|
|
2906
|
+
import mila from "markdown-it-link-attributes";
|
|
2907
|
+
import mif from "markdown-it-footnote";
|
|
2908
|
+
import lz from "lz-string";
|
|
2909
|
+
|
|
2910
|
+
// node/plugins/markdown-it-katex.ts
|
|
2911
|
+
import katex from "katex";
|
|
2912
|
+
function isValidDelim(state, pos) {
|
|
2913
|
+
const max = state.posMax;
|
|
2914
|
+
let can_open = true;
|
|
2915
|
+
let can_close = true;
|
|
2916
|
+
const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
|
|
2917
|
+
const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
|
|
2918
|
+
if (prevChar === 32 || prevChar === 9 || /* \t */
|
|
2919
|
+
nextChar >= 48 && nextChar <= 57)
|
|
2920
|
+
can_close = false;
|
|
2921
|
+
if (nextChar === 32 || nextChar === 9)
|
|
2922
|
+
can_open = false;
|
|
2771
2923
|
return {
|
|
2772
|
-
|
|
2773
|
-
|
|
2924
|
+
can_open,
|
|
2925
|
+
can_close
|
|
2774
2926
|
};
|
|
2775
2927
|
}
|
|
2776
|
-
function
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
server = _server;
|
|
2787
|
-
updateServerWatcher();
|
|
2788
|
-
server.middlewares.use(async (req, res, next) => {
|
|
2789
|
-
const match = req.url?.match(regexId);
|
|
2790
|
-
if (!match)
|
|
2791
|
-
return next();
|
|
2792
|
-
const [, no, type] = match;
|
|
2793
|
-
const idx = Number.parseInt(no);
|
|
2794
|
-
if (type === "json" && req.method === "GET") {
|
|
2795
|
-
res.write(JSON.stringify(withRenderedNote(data.slides[idx])));
|
|
2796
|
-
return res.end();
|
|
2797
|
-
}
|
|
2798
|
-
if (type === "json" && req.method === "POST") {
|
|
2799
|
-
const body = await getBodyJson(req);
|
|
2800
|
-
const slide = data.slides[idx];
|
|
2801
|
-
if (body.content && body.content !== slide.source.content)
|
|
2802
|
-
hmrPages.add(idx);
|
|
2803
|
-
Object.assign(slide.source, body);
|
|
2804
|
-
parser.prettifySlide(slide.source);
|
|
2805
|
-
await parser.save(data.markdownFiles[slide.source.filepath]);
|
|
2806
|
-
res.statusCode = 200;
|
|
2807
|
-
res.write(JSON.stringify(withRenderedNote(slide)));
|
|
2808
|
-
return res.end();
|
|
2809
|
-
}
|
|
2810
|
-
next();
|
|
2811
|
-
});
|
|
2812
|
-
},
|
|
2813
|
-
async handleHotUpdate(ctx) {
|
|
2814
|
-
if (!data.watchFiles.includes(ctx.file))
|
|
2815
|
-
return;
|
|
2816
|
-
await ctx.read();
|
|
2817
|
-
const newData = await serverOptions.loadData?.();
|
|
2818
|
-
if (!newData)
|
|
2819
|
-
return [];
|
|
2820
|
-
const moduleIds = /* @__PURE__ */ new Set();
|
|
2821
|
-
if (data.slides.length !== newData.slides.length) {
|
|
2822
|
-
moduleIds.add("/@slidev/routes");
|
|
2823
|
-
range(newData.slides.length).map((i) => hmrPages.add(i));
|
|
2824
|
-
}
|
|
2825
|
-
if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
|
|
2826
|
-
moduleIds.add("/@slidev/routes");
|
|
2827
|
-
range(data.slides.length).map((i) => hmrPages.add(i));
|
|
2828
|
-
}
|
|
2829
|
-
if (!equal(data.config, newData.config))
|
|
2830
|
-
moduleIds.add("/@slidev/configs");
|
|
2831
|
-
if (!equal(data.features, newData.features)) {
|
|
2832
|
-
setTimeout(() => {
|
|
2833
|
-
ctx.server.ws.send({ type: "full-reload" });
|
|
2834
|
-
}, 1);
|
|
2835
|
-
}
|
|
2836
|
-
const length = Math.max(data.slides.length, newData.slides.length);
|
|
2837
|
-
for (let i = 0; i < length; i++) {
|
|
2838
|
-
const a = data.slides[i];
|
|
2839
|
-
const b = newData.slides[i];
|
|
2840
|
-
if (a?.content.trim() === b?.content.trim() && a?.title?.trim() === b?.title?.trim() && equal(a.frontmatter, b.frontmatter) && Object.entries(a.snippetsUsed ?? {}).every(([file, oldContent]) => {
|
|
2841
|
-
try {
|
|
2842
|
-
const newContent = fs3.readFileSync(file, "utf-8");
|
|
2843
|
-
return oldContent === newContent;
|
|
2844
|
-
} catch {
|
|
2845
|
-
return false;
|
|
2846
|
-
}
|
|
2847
|
-
})) {
|
|
2848
|
-
if (a?.note !== b?.note) {
|
|
2849
|
-
ctx.server.ws.send({
|
|
2850
|
-
type: "custom",
|
|
2851
|
-
event: "slidev-update-note",
|
|
2852
|
-
data: {
|
|
2853
|
-
id: i,
|
|
2854
|
-
note: b.note || "",
|
|
2855
|
-
noteHTML: renderNote(b.note || "")
|
|
2856
|
-
}
|
|
2857
|
-
});
|
|
2858
|
-
}
|
|
2859
|
-
continue;
|
|
2860
|
-
}
|
|
2861
|
-
ctx.server.ws.send({
|
|
2862
|
-
type: "custom",
|
|
2863
|
-
event: "slidev-update",
|
|
2864
|
-
data: {
|
|
2865
|
-
id: i,
|
|
2866
|
-
data: withRenderedNote(newData.slides[i])
|
|
2867
|
-
}
|
|
2868
|
-
});
|
|
2869
|
-
hmrPages.add(i);
|
|
2870
|
-
}
|
|
2871
|
-
Object.assign(data, newData);
|
|
2872
|
-
if (hmrPages.size > 0)
|
|
2873
|
-
moduleIds.add("/@slidev/titles.md");
|
|
2874
|
-
const vueModules = Array.from(hmrPages).flatMap((i) => [
|
|
2875
|
-
ctx.server.moduleGraph.getModuleById(`${slidePrefix}${i + 1}.frontmatter`),
|
|
2876
|
-
ctx.server.moduleGraph.getModuleById(`${slidePrefix}${i + 1}.md`)
|
|
2877
|
-
]);
|
|
2878
|
-
hmrPages.clear();
|
|
2879
|
-
const moduleEntries = [
|
|
2880
|
-
...vueModules,
|
|
2881
|
-
...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
|
|
2882
|
-
].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
|
|
2883
|
-
updateServerWatcher();
|
|
2884
|
-
return moduleEntries;
|
|
2885
|
-
},
|
|
2886
|
-
resolveId(id) {
|
|
2887
|
-
if (id.startsWith(slidePrefix) || id.startsWith("/@slidev/"))
|
|
2888
|
-
return id;
|
|
2889
|
-
return null;
|
|
2890
|
-
},
|
|
2891
|
-
load(id) {
|
|
2892
|
-
if (id === "/@slidev/routes")
|
|
2893
|
-
return generateRoutes();
|
|
2894
|
-
if (id === "/@slidev/layouts")
|
|
2895
|
-
return generateLayouts();
|
|
2896
|
-
if (id === "/@slidev/styles")
|
|
2897
|
-
return generateUserStyles();
|
|
2898
|
-
if (id === "/@slidev/monaco-types")
|
|
2899
|
-
return generateMonacoTypes();
|
|
2900
|
-
if (id === "/@slidev/configs")
|
|
2901
|
-
return generateConfigs();
|
|
2902
|
-
if (id === "/@slidev/global-components/top")
|
|
2903
|
-
return generateGlobalComponents("top");
|
|
2904
|
-
if (id === "/@slidev/global-components/bottom")
|
|
2905
|
-
return generateGlobalComponents("bottom");
|
|
2906
|
-
if (id === "/@slidev/custom-nav-controls")
|
|
2907
|
-
return generateCustomNavControls();
|
|
2908
|
-
if (id === "/@slidev/titles.md") {
|
|
2909
|
-
return {
|
|
2910
|
-
code: data.slides.map(({ title }, i) => `<template ${i === 0 ? "v-if" : "v-else-if"}="+no === ${i + 1}">
|
|
2911
|
-
|
|
2912
|
-
${title}
|
|
2913
|
-
|
|
2914
|
-
</template>`).join(""),
|
|
2915
|
-
map: { mappings: "" }
|
|
2916
|
-
};
|
|
2917
|
-
}
|
|
2918
|
-
if (id.startsWith(slidePrefix)) {
|
|
2919
|
-
const remaning = id.slice(slidePrefix.length);
|
|
2920
|
-
const match = remaning.match(regexIdQuery);
|
|
2921
|
-
if (match) {
|
|
2922
|
-
const [, no, type] = match;
|
|
2923
|
-
const pageNo = Number.parseInt(no) - 1;
|
|
2924
|
-
const slide = data.slides[pageNo];
|
|
2925
|
-
if (!slide)
|
|
2926
|
-
return;
|
|
2927
|
-
if (type === "md") {
|
|
2928
|
-
return {
|
|
2929
|
-
code: slide?.content,
|
|
2930
|
-
map: { mappings: "" }
|
|
2931
|
-
};
|
|
2932
|
-
} else if (type === "frontmatter") {
|
|
2933
|
-
const slideBase = {
|
|
2934
|
-
...withRenderedNote(slide),
|
|
2935
|
-
frontmatter: void 0,
|
|
2936
|
-
source: void 0,
|
|
2937
|
-
// remove raw content in build, optimize the bundle size
|
|
2938
|
-
...mode === "build" ? { raw: "", content: "", note: "" } : {}
|
|
2939
|
-
};
|
|
2940
|
-
const fontmatter = getFrontmatter(pageNo);
|
|
2941
|
-
return {
|
|
2942
|
-
code: [
|
|
2943
|
-
"// @unocss-include",
|
|
2944
|
-
'import { reactive, computed } from "vue"',
|
|
2945
|
-
`export const frontmatter = reactive(${JSON.stringify(fontmatter)})`,
|
|
2946
|
-
`export const meta = reactive({
|
|
2947
|
-
layout: computed(() => frontmatter.layout),
|
|
2948
|
-
transition: computed(() => frontmatter.transition),
|
|
2949
|
-
class: computed(() => frontmatter.class),
|
|
2950
|
-
clicks: computed(() => frontmatter.clicks),
|
|
2951
|
-
name: computed(() => frontmatter.name),
|
|
2952
|
-
preload: computed(() => frontmatter.preload),
|
|
2953
|
-
slide: {
|
|
2954
|
-
...(${JSON.stringify(slideBase)}),
|
|
2955
|
-
frontmatter,
|
|
2956
|
-
filepath: ${JSON.stringify(slide.source.filepath)},
|
|
2957
|
-
start: ${JSON.stringify(slide.source.start)},
|
|
2958
|
-
id: ${pageNo},
|
|
2959
|
-
no: ${no},
|
|
2960
|
-
},
|
|
2961
|
-
__clicksContext: null,
|
|
2962
|
-
__preloaded: false,
|
|
2963
|
-
})`,
|
|
2964
|
-
"export default frontmatter",
|
|
2965
|
-
// handle HMR, update frontmatter with update
|
|
2966
|
-
"if (import.meta.hot) {",
|
|
2967
|
-
" import.meta.hot.accept(({ frontmatter: update }) => {",
|
|
2968
|
-
" if(!update) return",
|
|
2969
|
-
" Object.keys(frontmatter).forEach(key => {",
|
|
2970
|
-
" if (!(key in update)) delete frontmatter[key]",
|
|
2971
|
-
" })",
|
|
2972
|
-
" Object.assign(frontmatter, update)",
|
|
2973
|
-
" })",
|
|
2974
|
-
"}"
|
|
2975
|
-
].join("\n"),
|
|
2976
|
-
map: { mappings: "" }
|
|
2977
|
-
};
|
|
2978
|
-
}
|
|
2979
|
-
}
|
|
2980
|
-
return {
|
|
2981
|
-
code: "",
|
|
2982
|
-
map: { mappings: "" }
|
|
2983
|
-
};
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
},
|
|
2987
|
-
{
|
|
2988
|
-
name: "slidev:layout-transform:pre",
|
|
2989
|
-
enforce: "pre",
|
|
2990
|
-
async transform(code, id) {
|
|
2991
|
-
if (!id.startsWith(slidePrefix))
|
|
2992
|
-
return;
|
|
2993
|
-
const remaning = id.slice(slidePrefix.length);
|
|
2994
|
-
const match = remaning.match(regexIdQuery);
|
|
2995
|
-
if (!match)
|
|
2996
|
-
return;
|
|
2997
|
-
const [, no, type] = match;
|
|
2998
|
-
if (type !== "md")
|
|
2999
|
-
return;
|
|
3000
|
-
const pageNo = Number.parseInt(no) - 1;
|
|
3001
|
-
return transformMarkdown(code, pageNo);
|
|
3002
|
-
}
|
|
3003
|
-
},
|
|
3004
|
-
{
|
|
3005
|
-
name: "slidev:context-transform:pre",
|
|
3006
|
-
enforce: "pre",
|
|
3007
|
-
async transform(code, id) {
|
|
3008
|
-
if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
|
|
3009
|
-
return;
|
|
3010
|
-
return transformVue(code);
|
|
3011
|
-
}
|
|
3012
|
-
},
|
|
3013
|
-
{
|
|
3014
|
-
name: "slidev:title-transform:pre",
|
|
3015
|
-
enforce: "pre",
|
|
3016
|
-
transform(code, id) {
|
|
3017
|
-
if (id !== "/@slidev/titles.md")
|
|
3018
|
-
return;
|
|
3019
|
-
return transformTitles(code);
|
|
3020
|
-
}
|
|
3021
|
-
},
|
|
3022
|
-
{
|
|
3023
|
-
name: "slidev:slide-transform:post",
|
|
3024
|
-
enforce: "post",
|
|
3025
|
-
transform(code, id) {
|
|
3026
|
-
if (!id.match(/\/@slidev\/slides\/\d+\.md($|\?)/))
|
|
3027
|
-
return;
|
|
3028
|
-
const replaced = code.replace("if (_rerender_only)", "if (false)");
|
|
3029
|
-
if (replaced !== code)
|
|
3030
|
-
return replaced;
|
|
3031
|
-
}
|
|
3032
|
-
},
|
|
3033
|
-
{
|
|
3034
|
-
name: "slidev:index-html-transform",
|
|
3035
|
-
transformIndexHtml() {
|
|
3036
|
-
const { info, author, keywords } = data.headmatter;
|
|
3037
|
-
return [
|
|
3038
|
-
{
|
|
3039
|
-
tag: "title",
|
|
3040
|
-
children: getTitle()
|
|
3041
|
-
},
|
|
3042
|
-
info && {
|
|
3043
|
-
tag: "meta",
|
|
3044
|
-
attrs: {
|
|
3045
|
-
name: "description",
|
|
3046
|
-
content: info
|
|
3047
|
-
}
|
|
3048
|
-
},
|
|
3049
|
-
author && {
|
|
3050
|
-
tag: "meta",
|
|
3051
|
-
attrs: {
|
|
3052
|
-
name: "author",
|
|
3053
|
-
content: author
|
|
3054
|
-
}
|
|
3055
|
-
},
|
|
3056
|
-
keywords && {
|
|
3057
|
-
tag: "meta",
|
|
3058
|
-
attrs: {
|
|
3059
|
-
name: "keywords",
|
|
3060
|
-
content: Array.isArray(keywords) ? keywords.join(", ") : keywords
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
3063
|
-
].filter(isTruthy);
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
];
|
|
3067
|
-
function updateServerWatcher() {
|
|
3068
|
-
if (!server)
|
|
3069
|
-
return;
|
|
3070
|
-
server.watcher.add(data.watchFiles);
|
|
2928
|
+
function math_inline(state, silent) {
|
|
2929
|
+
let match, token, res, pos;
|
|
2930
|
+
if (state.src[state.pos] !== "$")
|
|
2931
|
+
return false;
|
|
2932
|
+
res = isValidDelim(state, state.pos);
|
|
2933
|
+
if (!res.can_open) {
|
|
2934
|
+
if (!silent)
|
|
2935
|
+
state.pending += "$";
|
|
2936
|
+
state.pos += 1;
|
|
2937
|
+
return true;
|
|
3071
2938
|
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
2939
|
+
const start = state.pos + 1;
|
|
2940
|
+
match = start;
|
|
2941
|
+
while ((match = state.src.indexOf("$", match)) !== -1) {
|
|
2942
|
+
pos = match - 1;
|
|
2943
|
+
while (state.src[pos] === "\\")
|
|
2944
|
+
pos -= 1;
|
|
2945
|
+
if ((match - pos) % 2 === 1)
|
|
2946
|
+
break;
|
|
2947
|
+
match += 1;
|
|
3077
2948
|
}
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
console.error(red(`
|
|
3084
|
-
Unknown layout "${bold(layoutName)}".${yellow(" Available layouts are:")}`) + Object.keys(layouts).map((i, idx) => (idx % 3 === 0 ? "\n " : "") + gray(i.padEnd(15, " "))).join(" "));
|
|
3085
|
-
console.error();
|
|
3086
|
-
layoutName = "default";
|
|
3087
|
-
}
|
|
3088
|
-
delete frontmatter.title;
|
|
3089
|
-
const imports = [
|
|
3090
|
-
`import InjectedLayout from "${toAtFS(layouts[layoutName])}"`,
|
|
3091
|
-
`import frontmatter from "${toAtFS(`${slidePrefix + (pageNo + 1)}.frontmatter`)}"`,
|
|
3092
|
-
templateImportContextUtils,
|
|
3093
|
-
"_provideFrontmatter(frontmatter)",
|
|
3094
|
-
templateInitContext,
|
|
3095
|
-
templateInjectionMarker
|
|
3096
|
-
];
|
|
3097
|
-
code = code.replace(/(<script setup.*>)/g, `$1
|
|
3098
|
-
${imports.join("\n")}
|
|
3099
|
-
`);
|
|
3100
|
-
const injectA = code.indexOf("<template>") + "<template>".length;
|
|
3101
|
-
const injectB = code.lastIndexOf("</template>");
|
|
3102
|
-
let body = code.slice(injectA, injectB).trim();
|
|
3103
|
-
if (body.startsWith("<div>") && body.endsWith("</div>"))
|
|
3104
|
-
body = body.slice(5, -6);
|
|
3105
|
-
code = `${code.slice(0, injectA)}
|
|
3106
|
-
<InjectedLayout v-bind="_frontmatterToProps(frontmatter,${pageNo})">
|
|
3107
|
-
${body}
|
|
3108
|
-
</InjectedLayout>
|
|
3109
|
-
${code.slice(injectB)}`;
|
|
3110
|
-
return code;
|
|
3111
|
-
}
|
|
3112
|
-
function transformVue(code) {
|
|
3113
|
-
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
|
|
3114
|
-
return code;
|
|
3115
|
-
const imports = [
|
|
3116
|
-
templateImportContextUtils,
|
|
3117
|
-
templateInitContext,
|
|
3118
|
-
templateInjectionMarker
|
|
3119
|
-
];
|
|
3120
|
-
const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
|
|
3121
|
-
if (matchScript && matchScript[2]) {
|
|
3122
|
-
return code.replace(/(<script.*>)/g, `$1
|
|
3123
|
-
${imports.join("\n")}
|
|
3124
|
-
`);
|
|
3125
|
-
} else if (matchScript && !matchScript[2]) {
|
|
3126
|
-
const matchExport = code.match(/export\s+default\s+{/);
|
|
3127
|
-
if (matchExport) {
|
|
3128
|
-
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
3129
|
-
let component = code.slice(exportIndex);
|
|
3130
|
-
component = component.slice(0, component.indexOf("</script>"));
|
|
3131
|
-
const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
|
|
3132
|
-
const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
|
|
3133
|
-
code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
|
|
3134
|
-
let injectIndex = exportIndex + provideImport.length;
|
|
3135
|
-
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
3136
|
-
const matchInject = component.match(/.*inject\s*:\s*([\[{])/);
|
|
3137
|
-
if (matchInject) {
|
|
3138
|
-
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
3139
|
-
if (matchInject[1] === "[") {
|
|
3140
|
-
let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
|
|
3141
|
-
const injectEndIndex = injects.indexOf("]");
|
|
3142
|
-
injects = injects.slice(0, injectEndIndex);
|
|
3143
|
-
injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
|
|
3144
|
-
return `${code.slice(0, injectIndex - 1)}{
|
|
3145
|
-
${injectObject}
|
|
3146
|
-
}${code.slice(injectIndex + injectEndIndex + 1)}`;
|
|
3147
|
-
} else {
|
|
3148
|
-
return `${code.slice(0, injectIndex)}
|
|
3149
|
-
${injectObject}
|
|
3150
|
-
${code.slice(injectIndex)}`;
|
|
3151
|
-
}
|
|
3152
|
-
}
|
|
3153
|
-
return `${code.slice(0, injectIndex)}
|
|
3154
|
-
inject: { ${injectObject} },
|
|
3155
|
-
${code.slice(injectIndex)}`;
|
|
3156
|
-
}
|
|
3157
|
-
}
|
|
3158
|
-
return `<script setup>
|
|
3159
|
-
${imports.join("\n")}
|
|
3160
|
-
</script>
|
|
3161
|
-
${code}`;
|
|
2949
|
+
if (match === -1) {
|
|
2950
|
+
if (!silent)
|
|
2951
|
+
state.pending += "$";
|
|
2952
|
+
state.pos = start;
|
|
2953
|
+
return true;
|
|
3162
2954
|
}
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
2955
|
+
if (match - start === 0) {
|
|
2956
|
+
if (!silent)
|
|
2957
|
+
state.pending += "$$";
|
|
2958
|
+
state.pos = start + 1;
|
|
2959
|
+
return true;
|
|
3166
2960
|
}
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
if (
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
const layoutPaths = await fg2("layouts/**/*.{vue,ts}", {
|
|
3174
|
-
cwd: root,
|
|
3175
|
-
absolute: true,
|
|
3176
|
-
suppressErrors: true
|
|
3177
|
-
});
|
|
3178
|
-
for (const layoutPath of layoutPaths) {
|
|
3179
|
-
const layout = basename2(layoutPath).replace(/\.\w+$/, "");
|
|
3180
|
-
if (layouts[layout])
|
|
3181
|
-
continue;
|
|
3182
|
-
layouts[layout] = layoutPath;
|
|
3183
|
-
}
|
|
3184
|
-
}
|
|
3185
|
-
_layouts_cache_time = now;
|
|
3186
|
-
_layouts_cache = layouts;
|
|
3187
|
-
return layouts;
|
|
2961
|
+
res = isValidDelim(state, match);
|
|
2962
|
+
if (!res.can_close) {
|
|
2963
|
+
if (!silent)
|
|
2964
|
+
state.pending += "$";
|
|
2965
|
+
state.pos = start;
|
|
2966
|
+
return true;
|
|
3188
2967
|
}
|
|
3189
|
-
|
|
3190
|
-
|
|
2968
|
+
if (!silent) {
|
|
2969
|
+
token = state.push("math_inline", "math", 0);
|
|
2970
|
+
token.markup = "$";
|
|
2971
|
+
token.content = state.src.slice(start, match);
|
|
3191
2972
|
}
|
|
3192
|
-
|
|
3193
|
-
|
|
2973
|
+
state.pos = match + 1;
|
|
2974
|
+
return true;
|
|
2975
|
+
}
|
|
2976
|
+
function math_block(state, start, end, silent) {
|
|
2977
|
+
let firstLine;
|
|
2978
|
+
let lastLine;
|
|
2979
|
+
let next;
|
|
2980
|
+
let lastPos;
|
|
2981
|
+
let found = false;
|
|
2982
|
+
let pos = state.bMarks[start] + state.tShift[start];
|
|
2983
|
+
let max = state.eMarks[start];
|
|
2984
|
+
if (pos + 2 > max)
|
|
2985
|
+
return false;
|
|
2986
|
+
if (state.src.slice(pos, pos + 2) !== "$$")
|
|
2987
|
+
return false;
|
|
2988
|
+
pos += 2;
|
|
2989
|
+
firstLine = state.src.slice(pos, max);
|
|
2990
|
+
if (silent)
|
|
2991
|
+
return true;
|
|
2992
|
+
if (firstLine.trim().slice(-2) === "$$") {
|
|
2993
|
+
firstLine = firstLine.trim().slice(0, -2);
|
|
2994
|
+
found = true;
|
|
3194
2995
|
}
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
for (const root of roots) {
|
|
3204
|
-
const styles = [
|
|
3205
|
-
join4(root, "styles", "index.ts"),
|
|
3206
|
-
join4(root, "styles", "index.js"),
|
|
3207
|
-
join4(root, "styles", "index.css"),
|
|
3208
|
-
join4(root, "styles.css"),
|
|
3209
|
-
join4(root, "style.css")
|
|
3210
|
-
];
|
|
3211
|
-
for (const style of styles) {
|
|
3212
|
-
if (fs3.existsSync(style)) {
|
|
3213
|
-
imports.push(`import "${toAtFS(style)}"`);
|
|
3214
|
-
continue;
|
|
3215
|
-
}
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
if (data.features.katex)
|
|
3219
|
-
imports.push(`import "${await resolveUrl("katex/dist/katex.min.css")}"`);
|
|
3220
|
-
if (data.config.highlighter === "shiki") {
|
|
3221
|
-
imports.push(
|
|
3222
|
-
`import "${await resolveUrl("@shikijs/vitepress-twoslash/style.css")}"`,
|
|
3223
|
-
`import "${resolveUrlOfClient("styles/shiki-twoslash.css")}"`
|
|
3224
|
-
);
|
|
3225
|
-
}
|
|
3226
|
-
if (data.config.css === "unocss") {
|
|
3227
|
-
imports.unshift(
|
|
3228
|
-
`import "${await resolveUrl("@unocss/reset/tailwind.css")}"`,
|
|
3229
|
-
'import "uno:preflights.css"',
|
|
3230
|
-
'import "uno:typography.css"',
|
|
3231
|
-
'import "uno:shortcuts.css"'
|
|
3232
|
-
);
|
|
3233
|
-
imports.push('import "uno.css"');
|
|
2996
|
+
for (next = start; !found; ) {
|
|
2997
|
+
next++;
|
|
2998
|
+
if (next >= end)
|
|
2999
|
+
break;
|
|
3000
|
+
pos = state.bMarks[next] + state.tShift[next];
|
|
3001
|
+
max = state.eMarks[next];
|
|
3002
|
+
if (pos < max && state.tShift[next] < state.blkIndent) {
|
|
3003
|
+
break;
|
|
3234
3004
|
}
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
}
|
|
3240
|
-
async function generateLayouts() {
|
|
3241
|
-
const imports = [];
|
|
3242
|
-
const layouts = objectMap(
|
|
3243
|
-
await getLayouts(),
|
|
3244
|
-
(k, v) => {
|
|
3245
|
-
imports.push(`import __layout_${k} from "${toAtFS(v)}"`);
|
|
3246
|
-
return [k, `__layout_${k}`];
|
|
3247
|
-
}
|
|
3248
|
-
);
|
|
3249
|
-
return [
|
|
3250
|
-
imports.join("\n"),
|
|
3251
|
-
`export default {
|
|
3252
|
-
${Object.entries(layouts).map(([k, v]) => `"${k}": ${v}`).join(",\n")}
|
|
3253
|
-
}`
|
|
3254
|
-
].join("\n\n");
|
|
3255
|
-
}
|
|
3256
|
-
async function generateRoutes() {
|
|
3257
|
-
const imports = [];
|
|
3258
|
-
const redirects = [];
|
|
3259
|
-
const layouts = await getLayouts();
|
|
3260
|
-
imports.push(
|
|
3261
|
-
`import { markRaw } from 'vue'`,
|
|
3262
|
-
`import __layout__end from '${layouts.end}'`
|
|
3263
|
-
);
|
|
3264
|
-
let no = 1;
|
|
3265
|
-
const routes = data.slides.map((i, idx) => {
|
|
3266
|
-
imports.push(`import n${no} from '${slidePrefix}${idx + 1}.md'`);
|
|
3267
|
-
imports.push(`import { meta as f${no} } from '${slidePrefix}${idx + 1}.frontmatter'`);
|
|
3268
|
-
const route = `{ path: '${no}', name: 'page-${no}', component: n${no}, meta: f${no} }`;
|
|
3269
|
-
if (i.frontmatter?.routeAlias)
|
|
3270
|
-
redirects.push(`{ path: '${i.frontmatter?.routeAlias}', redirect: { path: '${no}' } }`);
|
|
3271
|
-
no += 1;
|
|
3272
|
-
return route;
|
|
3273
|
-
});
|
|
3274
|
-
const routesStr = `export const rawRoutes = [
|
|
3275
|
-
${routes.join(",\n")}
|
|
3276
|
-
].map(markRaw)`;
|
|
3277
|
-
const redirectsStr = `export const redirects = [
|
|
3278
|
-
${redirects.join(",\n")}
|
|
3279
|
-
].map(markRaw)`;
|
|
3280
|
-
return [...imports, routesStr, redirectsStr].join("\n");
|
|
3281
|
-
}
|
|
3282
|
-
function getTitle() {
|
|
3283
|
-
if (isString(data.config.title)) {
|
|
3284
|
-
const tokens = md.parseInline(data.config.title, {});
|
|
3285
|
-
return stringifyMarkdownTokens(tokens);
|
|
3005
|
+
if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
|
|
3006
|
+
lastPos = state.src.slice(0, max).lastIndexOf("$$");
|
|
3007
|
+
lastLine = state.src.slice(pos, lastPos);
|
|
3008
|
+
found = true;
|
|
3286
3009
|
}
|
|
3287
|
-
return data.config.title;
|
|
3288
|
-
}
|
|
3289
|
-
function generateConfigs() {
|
|
3290
|
-
const config = {
|
|
3291
|
-
...data.config,
|
|
3292
|
-
remote,
|
|
3293
|
-
title: getTitle()
|
|
3294
|
-
};
|
|
3295
|
-
if (isString(config.info))
|
|
3296
|
-
config.info = md.render(config.info);
|
|
3297
|
-
return `export default ${JSON.stringify(config)}`;
|
|
3298
|
-
}
|
|
3299
|
-
async function generateGlobalComponents(layer) {
|
|
3300
|
-
const components = roots.flatMap((root) => {
|
|
3301
|
-
if (layer === "top") {
|
|
3302
|
-
return [
|
|
3303
|
-
join4(root, "global.vue"),
|
|
3304
|
-
join4(root, "global-top.vue"),
|
|
3305
|
-
join4(root, "GlobalTop.vue")
|
|
3306
|
-
];
|
|
3307
|
-
} else {
|
|
3308
|
-
return [
|
|
3309
|
-
join4(root, "global-bottom.vue"),
|
|
3310
|
-
join4(root, "GlobalBottom.vue")
|
|
3311
|
-
];
|
|
3312
|
-
}
|
|
3313
|
-
}).filter((i) => fs3.existsSync(i));
|
|
3314
|
-
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
3315
|
-
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
3316
|
-
return `
|
|
3317
|
-
${imports}
|
|
3318
|
-
import { h } from 'vue'
|
|
3319
|
-
export default {
|
|
3320
|
-
render() {
|
|
3321
|
-
return [${render}]
|
|
3322
3010
|
}
|
|
3011
|
+
state.line = next + 1;
|
|
3012
|
+
const token = state.push("math_block", "math", 0);
|
|
3013
|
+
token.block = true;
|
|
3014
|
+
token.content = (firstLine && firstLine.trim() ? `${firstLine}
|
|
3015
|
+
` : "") + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
|
|
3016
|
+
token.map = [start, state.line];
|
|
3017
|
+
token.markup = "$$";
|
|
3018
|
+
return true;
|
|
3323
3019
|
}
|
|
3020
|
+
function math_plugin(md2, options) {
|
|
3021
|
+
options = options || {};
|
|
3022
|
+
const katexInline = function(latex) {
|
|
3023
|
+
options.displayMode = false;
|
|
3024
|
+
try {
|
|
3025
|
+
return katex.renderToString(latex, options);
|
|
3026
|
+
} catch (error) {
|
|
3027
|
+
if (options.throwOnError)
|
|
3028
|
+
console.warn(error);
|
|
3029
|
+
return latex;
|
|
3030
|
+
}
|
|
3031
|
+
};
|
|
3032
|
+
const inlineRenderer = function(tokens, idx) {
|
|
3033
|
+
return katexInline(tokens[idx].content);
|
|
3034
|
+
};
|
|
3035
|
+
const katexBlock = function(latex) {
|
|
3036
|
+
options.displayMode = true;
|
|
3037
|
+
try {
|
|
3038
|
+
return `<p>${katex.renderToString(latex, options)}</p>`;
|
|
3039
|
+
} catch (error) {
|
|
3040
|
+
if (options.throwOnError)
|
|
3041
|
+
console.warn(error);
|
|
3042
|
+
return latex;
|
|
3043
|
+
}
|
|
3044
|
+
};
|
|
3045
|
+
const blockRenderer = function(tokens, idx) {
|
|
3046
|
+
return `${katexBlock(tokens[idx].content)}
|
|
3324
3047
|
`;
|
|
3048
|
+
};
|
|
3049
|
+
md2.inline.ruler.after("escape", "math_inline", math_inline);
|
|
3050
|
+
md2.block.ruler.after("blockquote", "math_block", math_block, {
|
|
3051
|
+
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
3052
|
+
});
|
|
3053
|
+
md2.renderer.rules.math_inline = inlineRenderer;
|
|
3054
|
+
md2.renderer.rules.math_block = blockRenderer;
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
// node/plugins/markdown-it-prism.ts
|
|
3058
|
+
import { createRequire } from "node:module";
|
|
3059
|
+
import Prism from "prismjs";
|
|
3060
|
+
import loadLanguages from "prismjs/components/index.js";
|
|
3061
|
+
import * as htmlparser2 from "htmlparser2";
|
|
3062
|
+
var require2 = createRequire(import.meta.url);
|
|
3063
|
+
var Tag = class {
|
|
3064
|
+
tagname;
|
|
3065
|
+
attributes;
|
|
3066
|
+
constructor(tagname, attributes) {
|
|
3067
|
+
this.tagname = tagname;
|
|
3068
|
+
this.attributes = attributes;
|
|
3325
3069
|
}
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3070
|
+
asOpen() {
|
|
3071
|
+
return `<${this.tagname} ${Object.entries(this.attributes).map(([key, value]) => `${key}="${value}"`).join(" ")}>`;
|
|
3072
|
+
}
|
|
3073
|
+
asClosed() {
|
|
3074
|
+
return `</${this.tagname}>`;
|
|
3075
|
+
}
|
|
3076
|
+
};
|
|
3077
|
+
var DEFAULTS = {
|
|
3078
|
+
plugins: [],
|
|
3079
|
+
init: () => {
|
|
3080
|
+
},
|
|
3081
|
+
defaultLanguageForUnknown: void 0,
|
|
3082
|
+
defaultLanguageForUnspecified: void 0,
|
|
3083
|
+
defaultLanguage: void 0
|
|
3084
|
+
};
|
|
3085
|
+
function loadPrismLang(lang) {
|
|
3086
|
+
if (!lang)
|
|
3087
|
+
return void 0;
|
|
3088
|
+
let langObject = Prism.languages[lang];
|
|
3089
|
+
if (langObject === void 0) {
|
|
3090
|
+
loadLanguages([lang]);
|
|
3091
|
+
langObject = Prism.languages[lang];
|
|
3341
3092
|
}
|
|
3093
|
+
return langObject;
|
|
3342
3094
|
}
|
|
3343
|
-
|
|
3095
|
+
function loadPrismPlugin(name) {
|
|
3096
|
+
try {
|
|
3097
|
+
require2(`prismjs/plugins/${name}/prism-${name}`);
|
|
3098
|
+
} catch (e) {
|
|
3099
|
+
throw new Error(`Cannot load Prism plugin "${name}". Please check the spelling.`);
|
|
3344
3100
|
}
|
|
3345
3101
|
}
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
return;
|
|
3357
|
-
const pkgJson = JSON.parse(await fs4.readFile(pkgJsonPath, "utf-8"));
|
|
3358
|
-
const typePath = pkgJson.types || pkgJson.typings;
|
|
3359
|
-
if (!typePath)
|
|
3360
|
-
return;
|
|
3361
|
-
return [dirname2(pkgJsonPath), pkgJson, typePath];
|
|
3102
|
+
function selectLanguage(options, lang) {
|
|
3103
|
+
let langToUse = lang;
|
|
3104
|
+
if (langToUse === "" && options.defaultLanguageForUnspecified !== void 0)
|
|
3105
|
+
langToUse = options.defaultLanguageForUnspecified;
|
|
3106
|
+
let prismLang = loadPrismLang(langToUse);
|
|
3107
|
+
if (prismLang === void 0 && options.defaultLanguageForUnknown !== void 0) {
|
|
3108
|
+
langToUse = options.defaultLanguageForUnknown;
|
|
3109
|
+
prismLang = loadPrismLang(langToUse);
|
|
3110
|
+
}
|
|
3111
|
+
return [langToUse, prismLang];
|
|
3362
3112
|
}
|
|
3363
|
-
function
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3113
|
+
function highlight(markdownit, options, text, lang) {
|
|
3114
|
+
const [langToUse, prismLang] = selectLanguage(options, lang);
|
|
3115
|
+
let code = text.trimEnd();
|
|
3116
|
+
code = prismLang ? highlightPrism(code, prismLang, langToUse) : markdownit.utils.escapeHtml(code);
|
|
3117
|
+
code = code.split(/\r?\n/g).map((line) => `<span class="line">${line}</span>`).join("\n");
|
|
3118
|
+
const classAttribute = langToUse ? ` class="slidev-code ${markdownit.options.langPrefix}${markdownit.utils.escapeHtml(langToUse)}"` : "";
|
|
3119
|
+
return escapeVueInCode(`<pre${classAttribute}><code>${code}</code></pre>`);
|
|
3120
|
+
}
|
|
3121
|
+
function highlightPrism(code, prismLang, langToUse) {
|
|
3122
|
+
const openTags = [];
|
|
3123
|
+
const parser2 = new htmlparser2.Parser({
|
|
3124
|
+
onopentag(tagname, attributes) {
|
|
3125
|
+
openTags.push(new Tag(tagname, attributes));
|
|
3370
3126
|
},
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
if (match) {
|
|
3374
|
-
const pkg = match[1];
|
|
3375
|
-
const packageData = await getPackageData(pkg) || await getPackageData(`@types/${pkg}`);
|
|
3376
|
-
if (!packageData)
|
|
3377
|
-
return;
|
|
3378
|
-
const [pkgDir, pkgJson, typePath] = packageData;
|
|
3379
|
-
return [
|
|
3380
|
-
"import * as monaco from 'monaco-editor'",
|
|
3381
|
-
`import Type from "${slash(join5(pkgDir, typePath))}?raw"`,
|
|
3382
|
-
...Object.keys(pkgJson.dependencies || {}).map((i) => `import "/@slidev-monaco-types/${i}"`),
|
|
3383
|
-
`monaco.languages.typescript.typescriptDefaults.addExtraLib(\`declare module "${pkg}" { \${Type} }\`)`
|
|
3384
|
-
].join("\n");
|
|
3385
|
-
}
|
|
3127
|
+
onclosetag() {
|
|
3128
|
+
openTags.pop();
|
|
3386
3129
|
}
|
|
3387
|
-
};
|
|
3130
|
+
});
|
|
3131
|
+
code = Prism.highlight(code, prismLang, langToUse);
|
|
3132
|
+
code = code.split(/\r?\n/g).map((line) => {
|
|
3133
|
+
const prefix = openTags.map((tag) => tag.asOpen()).join("");
|
|
3134
|
+
parser2.write(line);
|
|
3135
|
+
const postfix = openTags.reverse().map((tag) => tag.asClosed()).join("");
|
|
3136
|
+
return prefix + line + postfix;
|
|
3137
|
+
}).join("\n");
|
|
3138
|
+
parser2.end();
|
|
3139
|
+
return code;
|
|
3388
3140
|
}
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
function
|
|
3395
|
-
const
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
var getInjections = getInjections2;
|
|
3405
|
-
const name = id.slice(setupEntry.length + 1).replace(/\?.*$/, "");
|
|
3406
|
-
const imports = [];
|
|
3407
|
-
const injections = [];
|
|
3408
|
-
const setups = uniq2([
|
|
3409
|
-
...themeRoots,
|
|
3410
|
-
...addonRoots,
|
|
3411
|
-
userRoot
|
|
3412
|
-
]).map((i) => join6(i, "setup", name));
|
|
3413
|
-
setups.forEach((path2, idx) => {
|
|
3414
|
-
if (!existsSync2(path2))
|
|
3415
|
-
return;
|
|
3416
|
-
imports.push(`import __n${idx} from '${toAtFS(path2)}'`);
|
|
3417
|
-
let fn = `:AWAIT:__n${idx}`;
|
|
3418
|
-
if (/\binjection_return\b/g.test(code))
|
|
3419
|
-
fn = `injection_return = ${fn}`;
|
|
3420
|
-
if (/\binjection_arg\b/g.test(code)) {
|
|
3421
|
-
fn += "(";
|
|
3422
|
-
const matches = Array.from(code.matchAll(/\binjection_arg(_\d+)?\b/g));
|
|
3423
|
-
const dedupedMatches = Array.from(new Set(matches.map((m) => m[0])));
|
|
3424
|
-
fn += dedupedMatches.join(", ");
|
|
3425
|
-
fn += ", :LAST:)";
|
|
3426
|
-
} else {
|
|
3427
|
-
fn += "(:LAST:)";
|
|
3428
|
-
}
|
|
3429
|
-
injections.push(
|
|
3430
|
-
`// ${path2}`,
|
|
3431
|
-
fn
|
|
3432
|
-
);
|
|
3433
|
-
});
|
|
3434
|
-
code = code.replace("/* __imports__ */", imports.join("\n"));
|
|
3435
|
-
code = code.replace("/* __injections__ */", getInjections2());
|
|
3436
|
-
code = code.replace("/* __async_injections__ */", getInjections2(true));
|
|
3437
|
-
code = code.replace("/* __chained_injections__ */", getInjections2(false, true));
|
|
3438
|
-
code = code.replace("/* __chained_async_injections__ */", getInjections2(true, true));
|
|
3439
|
-
return code;
|
|
3440
|
-
}
|
|
3441
|
-
return null;
|
|
3442
|
-
}
|
|
3443
|
-
};
|
|
3141
|
+
function checkLanguageOption(options, optionName) {
|
|
3142
|
+
const language = options[optionName];
|
|
3143
|
+
if (language !== void 0 && loadPrismLang(language) === void 0)
|
|
3144
|
+
throw new Error(`Bad option ${optionName}: There is no Prism language '${language}'.`);
|
|
3145
|
+
}
|
|
3146
|
+
function markdownItPrism(markdownit, useroptions) {
|
|
3147
|
+
const options = Object.assign({}, DEFAULTS, useroptions);
|
|
3148
|
+
checkLanguageOption(options, "defaultLanguage");
|
|
3149
|
+
checkLanguageOption(options, "defaultLanguageForUnknown");
|
|
3150
|
+
checkLanguageOption(options, "defaultLanguageForUnspecified");
|
|
3151
|
+
options.defaultLanguageForUnknown = options.defaultLanguageForUnknown || options.defaultLanguage;
|
|
3152
|
+
options.defaultLanguageForUnspecified = options.defaultLanguageForUnspecified || options.defaultLanguage;
|
|
3153
|
+
options.plugins.forEach(loadPrismPlugin);
|
|
3154
|
+
options.init(Prism);
|
|
3155
|
+
markdownit.options.highlight = (text, lang) => highlight(markdownit, options, text, lang);
|
|
3444
3156
|
}
|
|
3445
3157
|
|
|
3446
|
-
// node/plugins/
|
|
3447
|
-
import
|
|
3448
|
-
import
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
3456
|
-
var SpecialCharacters;
|
|
3457
|
-
(function(SpecialCharacters2) {
|
|
3458
|
-
SpecialCharacters2[SpecialCharacters2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
|
|
3459
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
3460
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
3461
|
-
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
3462
|
-
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
3463
|
-
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
3464
|
-
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
3465
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
3466
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
3467
|
-
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
3468
|
-
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
3469
|
-
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
3470
|
-
|
|
3471
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
3472
|
-
import Token from "markdown-it/lib/token.mjs";
|
|
3473
|
-
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
3474
|
-
function taskLists(md2, options = { enabled: false, label: false, lineNumber: false }) {
|
|
3475
|
-
md2.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
3476
|
-
md2.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
3477
|
-
const token = tokens[0];
|
|
3478
|
-
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
3479
|
-
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
3480
|
-
const line = token.attrGet("line");
|
|
3481
|
-
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
3482
|
-
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
3483
|
-
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
3484
|
-
};
|
|
3485
|
-
md2.renderer.rules.taskListItemLabel_close = () => {
|
|
3486
|
-
return "</label>";
|
|
3487
|
-
};
|
|
3488
|
-
md2.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
3489
|
-
const token = tokens[0];
|
|
3490
|
-
const id = token.attrGet("id");
|
|
3491
|
-
return `<label for="${id}">`;
|
|
3492
|
-
};
|
|
3493
|
-
}
|
|
3494
|
-
function processToken(state, options) {
|
|
3495
|
-
const allTokens = state.tokens;
|
|
3496
|
-
for (let i = 2; i < allTokens.length; i++) {
|
|
3497
|
-
if (!isTodoItem(allTokens, i)) {
|
|
3498
|
-
continue;
|
|
3158
|
+
// node/plugins/transformSnippet.ts
|
|
3159
|
+
import path from "node:path";
|
|
3160
|
+
import fs3 from "fs-extra";
|
|
3161
|
+
function dedent(text) {
|
|
3162
|
+
const lines = text.split("\n");
|
|
3163
|
+
const minIndentLength = lines.reduce((acc, line) => {
|
|
3164
|
+
for (let i = 0; i < line.length; i++) {
|
|
3165
|
+
if (line[i] !== " " && line[i] !== " ")
|
|
3166
|
+
return Math.min(i, acc);
|
|
3499
3167
|
}
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3168
|
+
return acc;
|
|
3169
|
+
}, Number.POSITIVE_INFINITY);
|
|
3170
|
+
if (minIndentLength < Number.POSITIVE_INFINITY)
|
|
3171
|
+
return lines.map((x) => x.slice(minIndentLength)).join("\n");
|
|
3172
|
+
return text;
|
|
3173
|
+
}
|
|
3174
|
+
function testLine(line, regexp, regionName, end = false) {
|
|
3175
|
+
const [full, tag, name] = regexp.exec(line.trim()) || [];
|
|
3176
|
+
return full && tag && name === regionName && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/);
|
|
3177
|
+
}
|
|
3178
|
+
function findRegion(lines, regionName) {
|
|
3179
|
+
const regionRegexps = [
|
|
3180
|
+
/^\/\/ ?#?((?:end)?region) ([\w*-]+)$/,
|
|
3181
|
+
// javascript, typescript, java
|
|
3182
|
+
/^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/,
|
|
3183
|
+
// css, less, scss
|
|
3184
|
+
/^#pragma ((?:end)?region) ([\w*-]+)$/,
|
|
3185
|
+
// C, C++
|
|
3186
|
+
/^<!-- #?((?:end)?region) ([\w*-]+) -->$/,
|
|
3187
|
+
// HTML, markdown
|
|
3188
|
+
/^#((?:End )Region) ([\w*-]+)$/,
|
|
3189
|
+
// Visual Basic
|
|
3190
|
+
/^::#((?:end)region) ([\w*-]+)$/,
|
|
3191
|
+
// Bat
|
|
3192
|
+
/^# ?((?:end)?region) ([\w*-]+)$/
|
|
3193
|
+
// C#, PHP, Powershell, Python, perl & misc
|
|
3194
|
+
];
|
|
3195
|
+
let regexp = null;
|
|
3196
|
+
let start = -1;
|
|
3197
|
+
for (const [lineId, line] of lines.entries()) {
|
|
3198
|
+
if (regexp === null) {
|
|
3199
|
+
for (const reg of regionRegexps) {
|
|
3200
|
+
if (testLine(line, reg, regionName)) {
|
|
3201
|
+
start = lineId + 1;
|
|
3202
|
+
regexp = reg;
|
|
3203
|
+
break;
|
|
3204
|
+
}
|
|
3507
3205
|
}
|
|
3206
|
+
} else if (testLine(line, regexp, regionName, true)) {
|
|
3207
|
+
return { start, end: lineId, regexp };
|
|
3508
3208
|
}
|
|
3509
3209
|
}
|
|
3510
|
-
return
|
|
3210
|
+
return null;
|
|
3511
3211
|
}
|
|
3512
|
-
function
|
|
3513
|
-
const
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3212
|
+
function transformSnippet(md2, options, id) {
|
|
3213
|
+
const slideId = id.match(/(\d+)\.md$/)?.[1];
|
|
3214
|
+
if (!slideId)
|
|
3215
|
+
return md2;
|
|
3216
|
+
const data = options.data;
|
|
3217
|
+
const slideInfo = data.slides[+slideId - 1];
|
|
3218
|
+
const dir = path.dirname(slideInfo.source?.filepath ?? options.entry ?? options.userRoot);
|
|
3219
|
+
return md2.replace(
|
|
3220
|
+
/^<<< *(.+?)(#[\w-]+)? *(?: (\S+?))? *(\{.*)?$/mg,
|
|
3221
|
+
(full, filepath = "", regionName = "", lang = "", meta = "") => {
|
|
3222
|
+
const firstLine = `\`\`\`${lang || path.extname(filepath).slice(1)} ${meta}`;
|
|
3223
|
+
const src = /^\@[\/]/.test(filepath) ? path.resolve(options.userRoot, filepath.slice(2)) : path.resolve(dir, filepath);
|
|
3224
|
+
data.watchFiles.push(src);
|
|
3225
|
+
const isAFile = fs3.statSync(src).isFile();
|
|
3226
|
+
if (!fs3.existsSync(src) || !isAFile) {
|
|
3227
|
+
throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
|
|
3228
|
+
}
|
|
3229
|
+
let content = fs3.readFileSync(src, "utf8");
|
|
3230
|
+
slideInfo.snippetsUsed ??= {};
|
|
3231
|
+
slideInfo.snippetsUsed[src] = content;
|
|
3232
|
+
if (regionName) {
|
|
3233
|
+
const lines = content.split(/\r?\n/);
|
|
3234
|
+
const region = findRegion(lines, regionName.slice(1));
|
|
3235
|
+
if (region) {
|
|
3236
|
+
content = dedent(
|
|
3237
|
+
lines.slice(region.start, region.end).filter((line) => !region.regexp.test(line.trim())).join("\n")
|
|
3238
|
+
);
|
|
3239
|
+
}
|
|
3240
|
+
}
|
|
3241
|
+
return `${firstLine}
|
|
3242
|
+
${content}
|
|
3243
|
+
\`\`\``;
|
|
3517
3244
|
}
|
|
3518
|
-
|
|
3519
|
-
return void 0;
|
|
3520
|
-
}
|
|
3521
|
-
function isTodoItem(tokens, index) {
|
|
3522
|
-
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
3523
|
-
}
|
|
3524
|
-
function todoify(token, options) {
|
|
3525
|
-
if (token.children == null) {
|
|
3526
|
-
return;
|
|
3527
|
-
}
|
|
3528
|
-
const id = generateIdForToken(token);
|
|
3529
|
-
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
3530
|
-
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
3531
|
-
if (options.label) {
|
|
3532
|
-
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
3533
|
-
token.children.push(createLabelEndToken());
|
|
3534
|
-
}
|
|
3245
|
+
);
|
|
3535
3246
|
}
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3247
|
+
|
|
3248
|
+
// node/plugins/markdown.ts
|
|
3249
|
+
var shiki;
|
|
3250
|
+
var shikiOptions;
|
|
3251
|
+
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
3252
|
+
const { data: { config }, roots, mode, entry, clientRoot } = options;
|
|
3253
|
+
const setups = [];
|
|
3254
|
+
const entryPath = slash(entry);
|
|
3255
|
+
if (config.highlighter === "shiki") {
|
|
3256
|
+
const [
|
|
3257
|
+
options2,
|
|
3258
|
+
{ getHighlighter, bundledLanguages },
|
|
3259
|
+
markdownItShiki,
|
|
3260
|
+
transformerTwoslash
|
|
3261
|
+
] = await Promise.all([
|
|
3262
|
+
loadShikiSetups(clientRoot, roots),
|
|
3263
|
+
import("shiki").then(({ getHighlighter: getHighlighter2, bundledLanguages: bundledLanguages2 }) => ({ bundledLanguages: bundledLanguages2, getHighlighter: getHighlighter2 })),
|
|
3264
|
+
import("@shikijs/markdown-it/core").then(({ fromHighlighter }) => fromHighlighter),
|
|
3265
|
+
import("@shikijs/vitepress-twoslash").then(({ transformerTwoslash: transformerTwoslash2 }) => transformerTwoslash2)
|
|
3266
|
+
]);
|
|
3267
|
+
shikiOptions = options2;
|
|
3268
|
+
shiki = await getHighlighter({
|
|
3269
|
+
...options2,
|
|
3270
|
+
langs: options2.langs ?? Object.keys(bundledLanguages),
|
|
3271
|
+
themes: "themes" in options2 ? Object.values(options2.themes) : [options2.theme]
|
|
3272
|
+
});
|
|
3273
|
+
const transformers = [
|
|
3274
|
+
...options2.transformers || [],
|
|
3275
|
+
transformerTwoslash({
|
|
3276
|
+
explicitTrigger: true,
|
|
3277
|
+
twoslashOptions: {
|
|
3278
|
+
handbookOptions: {
|
|
3279
|
+
noErrorValidation: true
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
}),
|
|
3283
|
+
{
|
|
3284
|
+
pre(pre) {
|
|
3285
|
+
this.addClassToHast(pre, "slidev-code");
|
|
3286
|
+
delete pre.properties.tabindex;
|
|
3287
|
+
},
|
|
3288
|
+
postprocess(code) {
|
|
3289
|
+
return escapeVueInCode(code);
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
];
|
|
3293
|
+
const plugin = markdownItShiki(shiki, {
|
|
3294
|
+
...options2,
|
|
3295
|
+
transformers
|
|
3296
|
+
});
|
|
3297
|
+
setups.push((md2) => md2.use(plugin));
|
|
3539
3298
|
} else {
|
|
3540
|
-
|
|
3299
|
+
setups.push((md2) => md2.use(markdownItPrism));
|
|
3541
3300
|
}
|
|
3301
|
+
if (config.mdc)
|
|
3302
|
+
setups.push((md2) => md2.use(Mdc));
|
|
3303
|
+
const KatexOptions = await loadSetups(options.clientRoot, roots, "katex.ts", {}, { strict: false }, false);
|
|
3304
|
+
return Markdown({
|
|
3305
|
+
include: [/\.md$/],
|
|
3306
|
+
wrapperClasses: "",
|
|
3307
|
+
headEnabled: false,
|
|
3308
|
+
frontmatter: false,
|
|
3309
|
+
escapeCodeTagInterpolation: false,
|
|
3310
|
+
markdownItOptions: {
|
|
3311
|
+
quotes: `""''`,
|
|
3312
|
+
html: true,
|
|
3313
|
+
xhtmlOut: true,
|
|
3314
|
+
linkify: true,
|
|
3315
|
+
...mdOptions?.markdownItOptions
|
|
3316
|
+
},
|
|
3317
|
+
...mdOptions,
|
|
3318
|
+
markdownItSetup(md2) {
|
|
3319
|
+
md2.use(mila, {
|
|
3320
|
+
attrs: {
|
|
3321
|
+
target: "_blank",
|
|
3322
|
+
rel: "noopener"
|
|
3323
|
+
}
|
|
3324
|
+
});
|
|
3325
|
+
md2.use(mif);
|
|
3326
|
+
md2.use(taskLists, { enabled: true, lineNumber: true, label: true });
|
|
3327
|
+
md2.use(math_plugin, KatexOptions);
|
|
3328
|
+
setups.forEach((i) => i(md2));
|
|
3329
|
+
mdOptions?.markdownItSetup?.(md2);
|
|
3330
|
+
},
|
|
3331
|
+
transforms: {
|
|
3332
|
+
before(code, id) {
|
|
3333
|
+
if (id === entryPath)
|
|
3334
|
+
return "";
|
|
3335
|
+
const monaco = config.monaco === true || config.monaco === mode ? transformMarkdownMonaco : truncateMancoMark;
|
|
3336
|
+
if (config.highlighter === "shiki")
|
|
3337
|
+
code = transformMagicMove(code, shiki, shikiOptions);
|
|
3338
|
+
code = transformSlotSugar(code);
|
|
3339
|
+
code = transformSnippet(code, options, id);
|
|
3340
|
+
code = transformMermaid(code);
|
|
3341
|
+
code = transformPlantUml(code, config.plantUmlServer);
|
|
3342
|
+
code = monaco(code);
|
|
3343
|
+
code = transformHighlighter(code);
|
|
3344
|
+
code = transformPageCSS(code, id);
|
|
3345
|
+
code = transformKaTex(code);
|
|
3346
|
+
return code;
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
});
|
|
3542
3350
|
}
|
|
3543
|
-
function
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
function createLabelBeginToken(id) {
|
|
3560
|
-
const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
|
|
3561
|
-
labelBeginToken.attrSet("id", id);
|
|
3562
|
-
return labelBeginToken;
|
|
3351
|
+
function transformKaTex(md2) {
|
|
3352
|
+
return md2.replace(
|
|
3353
|
+
/^\$\$(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?\s*?)?\n([\s\S]+?)^\$\$/mg,
|
|
3354
|
+
(full, rangeStr = "", options = "", code) => {
|
|
3355
|
+
const ranges = rangeStr.split(/\|/g).map((i) => i.trim());
|
|
3356
|
+
code = code.trimEnd();
|
|
3357
|
+
options = options.trim() || "{}";
|
|
3358
|
+
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
3359
|
+
|
|
3360
|
+
$$
|
|
3361
|
+
${code}
|
|
3362
|
+
$$
|
|
3363
|
+
</KaTexBlockWrapper>
|
|
3364
|
+
`;
|
|
3365
|
+
}
|
|
3366
|
+
);
|
|
3563
3367
|
}
|
|
3564
|
-
function
|
|
3565
|
-
|
|
3368
|
+
function transformMarkdownMonaco(md2) {
|
|
3369
|
+
md2 = md2.replace(
|
|
3370
|
+
/^```(\w+?)\s*{monaco-diff}\s*?({.*?})?\s*?\n([\s\S]+?)^~~~\s*?\n([\s\S]+?)^```/mg,
|
|
3371
|
+
(full, lang = "ts", options = "{}", code, diff) => {
|
|
3372
|
+
lang = lang.trim();
|
|
3373
|
+
options = options.trim() || "{}";
|
|
3374
|
+
const encoded = lz.compressToBase64(code);
|
|
3375
|
+
const encodedDiff = lz.compressToBase64(diff);
|
|
3376
|
+
return `<Monaco code-lz="${encoded}" diff-lz="${encodedDiff}" lang="${lang}" v-bind="${options}" />`;
|
|
3377
|
+
}
|
|
3378
|
+
);
|
|
3379
|
+
md2 = md2.replace(
|
|
3380
|
+
/^```(\w+?)\s*{monaco}\s*?({.*?})?\s*?\n([\s\S]+?)^```/mg,
|
|
3381
|
+
(full, lang = "ts", options = "{}", code) => {
|
|
3382
|
+
lang = lang.trim();
|
|
3383
|
+
options = options.trim() || "{}";
|
|
3384
|
+
const encoded = lz.compressToBase64(code);
|
|
3385
|
+
return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
3386
|
+
}
|
|
3387
|
+
);
|
|
3388
|
+
return md2;
|
|
3566
3389
|
}
|
|
3567
|
-
function
|
|
3568
|
-
|
|
3390
|
+
function scanMonacoModules(md2) {
|
|
3391
|
+
const typeModules = /* @__PURE__ */ new Set();
|
|
3392
|
+
md2.replace(
|
|
3393
|
+
/^```(\w+?)\s*{monaco([\w:,-]*)}[\s\n]*([\s\S]+?)^```/mg,
|
|
3394
|
+
(full, lang = "ts", options, code) => {
|
|
3395
|
+
options = options || "";
|
|
3396
|
+
lang = lang.trim();
|
|
3397
|
+
if (lang === "ts" || lang === "typescript") {
|
|
3398
|
+
Array.from(code.matchAll(/\s+from\s+(["'])([\/\w@-]+)\1/g)).map((i) => i[2]).filter(isTruthy).map((i) => typeModules.add(i));
|
|
3399
|
+
}
|
|
3400
|
+
return "";
|
|
3401
|
+
}
|
|
3402
|
+
);
|
|
3403
|
+
return Array.from(typeModules);
|
|
3569
3404
|
}
|
|
3570
|
-
function
|
|
3571
|
-
return
|
|
3405
|
+
function truncateMancoMark(md2) {
|
|
3406
|
+
return md2.replace(/{monaco.*?}/g, "");
|
|
3572
3407
|
}
|
|
3573
|
-
function
|
|
3574
|
-
|
|
3408
|
+
function transformSlotSugar(md2) {
|
|
3409
|
+
const lines = md2.split(/\r?\n/g);
|
|
3410
|
+
let prevSlot = false;
|
|
3411
|
+
const { isLineInsideCodeblocks } = getCodeBlocks(md2);
|
|
3412
|
+
lines.forEach((line, idx) => {
|
|
3413
|
+
if (isLineInsideCodeblocks(idx))
|
|
3414
|
+
return;
|
|
3415
|
+
const match = line.trimEnd().match(/^::\s*([\w\.\-\:]+)\s*::$/);
|
|
3416
|
+
if (match) {
|
|
3417
|
+
lines[idx] = `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
3418
|
+
`;
|
|
3419
|
+
prevSlot = true;
|
|
3420
|
+
}
|
|
3421
|
+
});
|
|
3422
|
+
if (prevSlot)
|
|
3423
|
+
lines[lines.length - 1] += "\n\n</template>";
|
|
3424
|
+
return lines.join("\n");
|
|
3575
3425
|
}
|
|
3576
|
-
|
|
3577
|
-
|
|
3426
|
+
var reMagicMoveBlock = /^````(?:md|markdown) magic-move(?:[ ]*?({.*?})?([^\n]*?))?\n([\s\S]+?)^````$/mg;
|
|
3427
|
+
var reCodeBlock = /^```(\w+?)(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?(.*?))?\n([\s\S]+?)^```$/mg;
|
|
3428
|
+
function transformMagicMove(md2, shiki2, shikiOptions2) {
|
|
3429
|
+
return md2.replace(
|
|
3430
|
+
reMagicMoveBlock,
|
|
3431
|
+
(full, _options = "", _attrs = "", body) => {
|
|
3432
|
+
if (!shiki2 || !shikiOptions2)
|
|
3433
|
+
throw new Error("Shiki is required for Magic Move. You may need to set `highlighter: shiki` in your Slidev config.");
|
|
3434
|
+
const matches = Array.from(body.matchAll(reCodeBlock));
|
|
3435
|
+
if (!matches.length)
|
|
3436
|
+
throw new Error("Magic Move block must contain at least one code block");
|
|
3437
|
+
const langs = new Set(matches.map((i) => i[1]));
|
|
3438
|
+
if (langs.size > 1)
|
|
3439
|
+
throw new Error(`Magic Move block must contain code blocks with the same language, got ${Array.from(langs).join(", ")}`);
|
|
3440
|
+
const lang = Array.from(langs)[0];
|
|
3441
|
+
const magicMove = createMagicMoveMachine(
|
|
3442
|
+
(code) => codeToKeyedTokens(shiki2, code, {
|
|
3443
|
+
...shikiOptions2,
|
|
3444
|
+
lang
|
|
3445
|
+
})
|
|
3446
|
+
);
|
|
3447
|
+
const steps = matches.map((i) => magicMove.commit((i[5] || "").trimEnd()));
|
|
3448
|
+
const compressed = lz.compressToBase64(JSON.stringify(steps));
|
|
3449
|
+
return `<ShikiMagicMove steps-lz="${compressed}" />`;
|
|
3450
|
+
}
|
|
3451
|
+
);
|
|
3578
3452
|
}
|
|
3453
|
+
function transformHighlighter(md2) {
|
|
3454
|
+
return md2.replace(
|
|
3455
|
+
reCodeBlock,
|
|
3456
|
+
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
3457
|
+
const ranges = rangeStr.split(/\|/g).map((i) => i.trim());
|
|
3458
|
+
code = code.trimEnd();
|
|
3459
|
+
options = options.trim() || "{}";
|
|
3460
|
+
return `
|
|
3461
|
+
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
3579
3462
|
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
// node/plugins/markdown.ts
|
|
3584
|
-
import { encode as encode2 } from "plantuml-encoder";
|
|
3585
|
-
import Mdc from "markdown-it-mdc";
|
|
3586
|
-
import { codeToKeyedTokens, createMagicMoveMachine } from "shiki-magic-move/core";
|
|
3463
|
+
\`\`\`${lang}${attrs}
|
|
3464
|
+
${code}
|
|
3465
|
+
\`\`\`
|
|
3587
3466
|
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
can_open = false;
|
|
3467
|
+
</CodeBlockWrapper>`;
|
|
3468
|
+
}
|
|
3469
|
+
);
|
|
3470
|
+
}
|
|
3471
|
+
function getCodeBlocks(md2) {
|
|
3472
|
+
const codeblocks = Array.from(md2.matchAll(/^```[\s\S]*?^```/mg)).map((m) => {
|
|
3473
|
+
const start = m.index;
|
|
3474
|
+
const end = m.index + m[0].length;
|
|
3475
|
+
const startLine = md2.slice(0, start).match(/\n/g)?.length || 0;
|
|
3476
|
+
const endLine = md2.slice(0, end).match(/\n/g)?.length || 0;
|
|
3477
|
+
return [start, end, startLine, endLine];
|
|
3478
|
+
});
|
|
3601
3479
|
return {
|
|
3602
|
-
|
|
3603
|
-
|
|
3480
|
+
codeblocks,
|
|
3481
|
+
isInsideCodeblocks(idx) {
|
|
3482
|
+
return codeblocks.some(([s, e]) => s <= idx && idx <= e);
|
|
3483
|
+
},
|
|
3484
|
+
isLineInsideCodeblocks(line) {
|
|
3485
|
+
return codeblocks.some(([, , s, e]) => s <= line && line <= e);
|
|
3486
|
+
}
|
|
3604
3487
|
};
|
|
3605
3488
|
}
|
|
3606
|
-
function
|
|
3607
|
-
|
|
3608
|
-
if (
|
|
3609
|
-
return
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3489
|
+
function transformPageCSS(md2, id) {
|
|
3490
|
+
const page = id.match(/(\d+)\.md$/)?.[1];
|
|
3491
|
+
if (!page)
|
|
3492
|
+
return md2;
|
|
3493
|
+
const { isInsideCodeblocks } = getCodeBlocks(md2);
|
|
3494
|
+
const result = md2.replace(
|
|
3495
|
+
/(\n<style[^>]*?>)([\s\S]+?)(<\/style>)/g,
|
|
3496
|
+
(full, start, css, end, index) => {
|
|
3497
|
+
if (index < 0 || isInsideCodeblocks(index))
|
|
3498
|
+
return full;
|
|
3499
|
+
if (!start.includes("scoped"))
|
|
3500
|
+
start = start.replace("<style", "<style scoped");
|
|
3501
|
+
return `${start}
|
|
3502
|
+
${css}${end}`;
|
|
3503
|
+
}
|
|
3504
|
+
);
|
|
3505
|
+
return result;
|
|
3506
|
+
}
|
|
3507
|
+
function transformMermaid(md2) {
|
|
3508
|
+
return md2.replace(/^```mermaid\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", code = "") => {
|
|
3509
|
+
code = code.trim();
|
|
3510
|
+
options = options.trim() || "{}";
|
|
3511
|
+
const encoded = lz.compressToBase64(code);
|
|
3512
|
+
return `<Mermaid code-lz="${encoded}" v-bind="${options}" />`;
|
|
3513
|
+
});
|
|
3514
|
+
}
|
|
3515
|
+
function transformPlantUml(md2, server) {
|
|
3516
|
+
return md2.replace(/^```plantuml\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", content = "") => {
|
|
3517
|
+
const code = encodePlantUml(content.trim());
|
|
3518
|
+
options = options.trim() || "{}";
|
|
3519
|
+
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
3520
|
+
});
|
|
3521
|
+
}
|
|
3522
|
+
function escapeVueInCode(md2) {
|
|
3523
|
+
return md2.replace(/{{/g, "{{");
|
|
3524
|
+
}
|
|
3525
|
+
async function loadShikiSetups(clientRoot, roots) {
|
|
3526
|
+
const result = await loadSetups(
|
|
3527
|
+
clientRoot,
|
|
3528
|
+
roots,
|
|
3529
|
+
"shiki.ts",
|
|
3530
|
+
{
|
|
3531
|
+
/** @deprecated */
|
|
3532
|
+
async loadTheme(path2) {
|
|
3533
|
+
console.warn("[slidev] `loadTheme` in `setup/shiki.ts` is deprecated. Pass directly the theme name it's supported by Shiki. For custom themes, load it manually via `JSON.parse(fs.readFileSync(path, 'utf-8'))` and pass the raw JSON object instead.");
|
|
3534
|
+
return JSON.parse(await fs4.readFile(path2, "utf-8"));
|
|
3535
|
+
}
|
|
3536
|
+
},
|
|
3537
|
+
{},
|
|
3538
|
+
false
|
|
3539
|
+
);
|
|
3540
|
+
if ("theme" in result && "themes" in result)
|
|
3541
|
+
delete result.theme;
|
|
3542
|
+
if (result.theme && typeof result.theme !== "string" && !result.theme.name && !result.theme.tokenColors) {
|
|
3543
|
+
result.themes = result.theme;
|
|
3544
|
+
delete result.theme;
|
|
3645
3545
|
}
|
|
3646
|
-
if (!
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3546
|
+
if (!result.theme && !result.themes) {
|
|
3547
|
+
result.themes = {
|
|
3548
|
+
dark: "vitesse-dark",
|
|
3549
|
+
light: "vitesse-light"
|
|
3550
|
+
};
|
|
3650
3551
|
}
|
|
3651
|
-
|
|
3652
|
-
|
|
3552
|
+
if (result.themes)
|
|
3553
|
+
result.defaultColor = false;
|
|
3554
|
+
return result;
|
|
3653
3555
|
}
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
lastPos = state.src.slice(0, max).lastIndexOf("$$");
|
|
3685
|
-
lastLine = state.src.slice(pos, lastPos);
|
|
3686
|
-
found = true;
|
|
3687
|
-
}
|
|
3556
|
+
|
|
3557
|
+
// node/plugins/loaders.ts
|
|
3558
|
+
var regexId = /^\/\@slidev\/slide\/(\d+)\.(md|json)(?:\?import)?$/;
|
|
3559
|
+
var regexIdQuery = /(\d+?)\.(md|json|frontmatter)$/;
|
|
3560
|
+
var templateInjectionMarker = "/* @slidev-injection */";
|
|
3561
|
+
var templateImportContextUtils = `import {
|
|
3562
|
+
useSlideContext,
|
|
3563
|
+
provideFrontmatter as _provideFrontmatter,
|
|
3564
|
+
frontmatterToProps as _frontmatterToProps,
|
|
3565
|
+
} from "@slidev/client/context.ts"`.replace(/\n\s*/g, " ");
|
|
3566
|
+
var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = useSlideContext()`;
|
|
3567
|
+
function getBodyJson(req) {
|
|
3568
|
+
return new Promise((resolve5, reject) => {
|
|
3569
|
+
let body = "";
|
|
3570
|
+
req.on("data", (chunk) => body += chunk);
|
|
3571
|
+
req.on("error", reject);
|
|
3572
|
+
req.on("end", () => {
|
|
3573
|
+
try {
|
|
3574
|
+
resolve5(JSON.parse(body) || {});
|
|
3575
|
+
} catch (e) {
|
|
3576
|
+
reject(e);
|
|
3577
|
+
}
|
|
3578
|
+
});
|
|
3579
|
+
});
|
|
3580
|
+
}
|
|
3581
|
+
var md = Markdown2({ html: true });
|
|
3582
|
+
md.use(mila2, {
|
|
3583
|
+
attrs: {
|
|
3584
|
+
target: "_blank",
|
|
3585
|
+
rel: "noopener"
|
|
3688
3586
|
}
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3587
|
+
});
|
|
3588
|
+
function renderNote(text = "") {
|
|
3589
|
+
let clickCount = 0;
|
|
3590
|
+
const html = md.render(
|
|
3591
|
+
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
3592
|
+
clickCount += Number(count);
|
|
3593
|
+
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
3594
|
+
})
|
|
3595
|
+
);
|
|
3596
|
+
return html;
|
|
3697
3597
|
}
|
|
3698
|
-
function
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
try {
|
|
3703
|
-
return katex.renderToString(latex, options);
|
|
3704
|
-
} catch (error) {
|
|
3705
|
-
if (options.throwOnError)
|
|
3706
|
-
console.warn(error);
|
|
3707
|
-
return latex;
|
|
3708
|
-
}
|
|
3709
|
-
};
|
|
3710
|
-
const inlineRenderer = function(tokens, idx) {
|
|
3711
|
-
return katexInline(tokens[idx].content);
|
|
3712
|
-
};
|
|
3713
|
-
const katexBlock = function(latex) {
|
|
3714
|
-
options.displayMode = true;
|
|
3715
|
-
try {
|
|
3716
|
-
return `<p>${katex.renderToString(latex, options)}</p>`;
|
|
3717
|
-
} catch (error) {
|
|
3718
|
-
if (options.throwOnError)
|
|
3719
|
-
console.warn(error);
|
|
3720
|
-
return latex;
|
|
3721
|
-
}
|
|
3722
|
-
};
|
|
3723
|
-
const blockRenderer = function(tokens, idx) {
|
|
3724
|
-
return `${katexBlock(tokens[idx].content)}
|
|
3725
|
-
`;
|
|
3598
|
+
function withRenderedNote(data) {
|
|
3599
|
+
return {
|
|
3600
|
+
...data,
|
|
3601
|
+
noteHTML: renderNote(data?.note)
|
|
3726
3602
|
};
|
|
3727
|
-
md2.inline.ruler.after("escape", "math_inline", math_inline);
|
|
3728
|
-
md2.block.ruler.after("blockquote", "math_block", math_block, {
|
|
3729
|
-
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
3730
|
-
});
|
|
3731
|
-
md2.renderer.rules.math_inline = inlineRenderer;
|
|
3732
|
-
md2.renderer.rules.math_block = blockRenderer;
|
|
3733
3603
|
}
|
|
3604
|
+
function createSlidesLoader({ data, clientRoot, roots, remote, mode, userRoot }, pluginOptions, serverOptions) {
|
|
3605
|
+
const slidePrefix = "/@slidev/slides/";
|
|
3606
|
+
const hmrPages = /* @__PURE__ */ new Set();
|
|
3607
|
+
let server;
|
|
3608
|
+
let _layouts_cache_time = 0;
|
|
3609
|
+
let _layouts_cache = {};
|
|
3610
|
+
return [
|
|
3611
|
+
{
|
|
3612
|
+
name: "slidev:loader",
|
|
3613
|
+
configureServer(_server) {
|
|
3614
|
+
server = _server;
|
|
3615
|
+
updateServerWatcher();
|
|
3616
|
+
server.middlewares.use(async (req, res, next) => {
|
|
3617
|
+
const match = req.url?.match(regexId);
|
|
3618
|
+
if (!match)
|
|
3619
|
+
return next();
|
|
3620
|
+
const [, no, type] = match;
|
|
3621
|
+
const idx = Number.parseInt(no);
|
|
3622
|
+
if (type === "json" && req.method === "GET") {
|
|
3623
|
+
res.write(JSON.stringify(withRenderedNote(data.slides[idx])));
|
|
3624
|
+
return res.end();
|
|
3625
|
+
}
|
|
3626
|
+
if (type === "json" && req.method === "POST") {
|
|
3627
|
+
const body = await getBodyJson(req);
|
|
3628
|
+
const slide = data.slides[idx];
|
|
3629
|
+
if (body.content && body.content !== slide.source.content)
|
|
3630
|
+
hmrPages.add(idx);
|
|
3631
|
+
Object.assign(slide.source, body);
|
|
3632
|
+
parser.prettifySlide(slide.source);
|
|
3633
|
+
await parser.save(data.markdownFiles[slide.source.filepath]);
|
|
3634
|
+
res.statusCode = 200;
|
|
3635
|
+
res.write(JSON.stringify(withRenderedNote(slide)));
|
|
3636
|
+
return res.end();
|
|
3637
|
+
}
|
|
3638
|
+
next();
|
|
3639
|
+
});
|
|
3640
|
+
},
|
|
3641
|
+
async handleHotUpdate(ctx) {
|
|
3642
|
+
if (!data.watchFiles.includes(ctx.file))
|
|
3643
|
+
return;
|
|
3644
|
+
await ctx.read();
|
|
3645
|
+
const newData = await serverOptions.loadData?.();
|
|
3646
|
+
if (!newData)
|
|
3647
|
+
return [];
|
|
3648
|
+
const moduleIds = /* @__PURE__ */ new Set();
|
|
3649
|
+
if (data.slides.length !== newData.slides.length) {
|
|
3650
|
+
moduleIds.add("/@slidev/routes");
|
|
3651
|
+
range(newData.slides.length).map((i) => hmrPages.add(i));
|
|
3652
|
+
}
|
|
3653
|
+
if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
|
|
3654
|
+
moduleIds.add("/@slidev/routes");
|
|
3655
|
+
range(data.slides.length).map((i) => hmrPages.add(i));
|
|
3656
|
+
}
|
|
3657
|
+
if (!equal(data.config, newData.config))
|
|
3658
|
+
moduleIds.add("/@slidev/configs");
|
|
3659
|
+
if (!equal(data.features, newData.features)) {
|
|
3660
|
+
setTimeout(() => {
|
|
3661
|
+
ctx.server.ws.send({ type: "full-reload" });
|
|
3662
|
+
}, 1);
|
|
3663
|
+
}
|
|
3664
|
+
const length = Math.max(data.slides.length, newData.slides.length);
|
|
3665
|
+
for (let i = 0; i < length; i++) {
|
|
3666
|
+
const a = data.slides[i];
|
|
3667
|
+
const b = newData.slides[i];
|
|
3668
|
+
if (a?.content.trim() === b?.content.trim() && a?.title?.trim() === b?.title?.trim() && equal(a.frontmatter, b.frontmatter) && Object.entries(a.snippetsUsed ?? {}).every(([file, oldContent]) => {
|
|
3669
|
+
try {
|
|
3670
|
+
const newContent = fs5.readFileSync(file, "utf-8");
|
|
3671
|
+
return oldContent === newContent;
|
|
3672
|
+
} catch {
|
|
3673
|
+
return false;
|
|
3674
|
+
}
|
|
3675
|
+
})) {
|
|
3676
|
+
if (a?.note !== b?.note) {
|
|
3677
|
+
ctx.server.ws.send({
|
|
3678
|
+
type: "custom",
|
|
3679
|
+
event: "slidev-update-note",
|
|
3680
|
+
data: {
|
|
3681
|
+
id: i,
|
|
3682
|
+
note: b.note || "",
|
|
3683
|
+
noteHTML: renderNote(b.note || "")
|
|
3684
|
+
}
|
|
3685
|
+
});
|
|
3686
|
+
}
|
|
3687
|
+
continue;
|
|
3688
|
+
}
|
|
3689
|
+
ctx.server.ws.send({
|
|
3690
|
+
type: "custom",
|
|
3691
|
+
event: "slidev-update",
|
|
3692
|
+
data: {
|
|
3693
|
+
id: i,
|
|
3694
|
+
data: withRenderedNote(newData.slides[i])
|
|
3695
|
+
}
|
|
3696
|
+
});
|
|
3697
|
+
hmrPages.add(i);
|
|
3698
|
+
}
|
|
3699
|
+
Object.assign(data, newData);
|
|
3700
|
+
if (hmrPages.size > 0)
|
|
3701
|
+
moduleIds.add("/@slidev/titles.md");
|
|
3702
|
+
const vueModules = Array.from(hmrPages).flatMap((i) => [
|
|
3703
|
+
ctx.server.moduleGraph.getModuleById(`${slidePrefix}${i + 1}.frontmatter`),
|
|
3704
|
+
ctx.server.moduleGraph.getModuleById(`${slidePrefix}${i + 1}.md`)
|
|
3705
|
+
]);
|
|
3706
|
+
hmrPages.clear();
|
|
3707
|
+
const moduleEntries = [
|
|
3708
|
+
...vueModules,
|
|
3709
|
+
...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
|
|
3710
|
+
].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
|
|
3711
|
+
updateServerWatcher();
|
|
3712
|
+
return moduleEntries;
|
|
3713
|
+
},
|
|
3714
|
+
resolveId(id) {
|
|
3715
|
+
if (id.startsWith(slidePrefix) || id.startsWith("/@slidev/"))
|
|
3716
|
+
return id;
|
|
3717
|
+
return null;
|
|
3718
|
+
},
|
|
3719
|
+
load(id) {
|
|
3720
|
+
if (id === "/@slidev/routes")
|
|
3721
|
+
return generateRoutes();
|
|
3722
|
+
if (id === "/@slidev/layouts")
|
|
3723
|
+
return generateLayouts();
|
|
3724
|
+
if (id === "/@slidev/styles")
|
|
3725
|
+
return generateUserStyles();
|
|
3726
|
+
if (id === "/@slidev/monaco-types")
|
|
3727
|
+
return generateMonacoTypes();
|
|
3728
|
+
if (id === "/@slidev/configs")
|
|
3729
|
+
return generateConfigs();
|
|
3730
|
+
if (id === "/@slidev/global-components/top")
|
|
3731
|
+
return generateGlobalComponents("top");
|
|
3732
|
+
if (id === "/@slidev/global-components/bottom")
|
|
3733
|
+
return generateGlobalComponents("bottom");
|
|
3734
|
+
if (id === "/@slidev/custom-nav-controls")
|
|
3735
|
+
return generateCustomNavControls();
|
|
3736
|
+
if (id === "/@slidev/shiki")
|
|
3737
|
+
return generteShikiBundle();
|
|
3738
|
+
if (id === "/@slidev/titles.md") {
|
|
3739
|
+
return {
|
|
3740
|
+
code: data.slides.map(({ title }, i) => `<template ${i === 0 ? "v-if" : "v-else-if"}="+no === ${i + 1}">
|
|
3734
3741
|
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3742
|
+
${title}
|
|
3743
|
+
|
|
3744
|
+
</template>`).join(""),
|
|
3745
|
+
map: { mappings: "" }
|
|
3746
|
+
};
|
|
3747
|
+
}
|
|
3748
|
+
if (id.startsWith(slidePrefix)) {
|
|
3749
|
+
const remaning = id.slice(slidePrefix.length);
|
|
3750
|
+
const match = remaning.match(regexIdQuery);
|
|
3751
|
+
if (match) {
|
|
3752
|
+
const [, no, type] = match;
|
|
3753
|
+
const pageNo = Number.parseInt(no) - 1;
|
|
3754
|
+
const slide = data.slides[pageNo];
|
|
3755
|
+
if (!slide)
|
|
3756
|
+
return;
|
|
3757
|
+
if (type === "md") {
|
|
3758
|
+
return {
|
|
3759
|
+
code: slide?.content,
|
|
3760
|
+
map: { mappings: "" }
|
|
3761
|
+
};
|
|
3762
|
+
} else if (type === "frontmatter") {
|
|
3763
|
+
const slideBase = {
|
|
3764
|
+
...withRenderedNote(slide),
|
|
3765
|
+
frontmatter: void 0,
|
|
3766
|
+
source: void 0,
|
|
3767
|
+
// remove raw content in build, optimize the bundle size
|
|
3768
|
+
...mode === "build" ? { raw: "", content: "", note: "" } : {}
|
|
3769
|
+
};
|
|
3770
|
+
const fontmatter = getFrontmatter(pageNo);
|
|
3771
|
+
return {
|
|
3772
|
+
code: [
|
|
3773
|
+
"// @unocss-include",
|
|
3774
|
+
'import { reactive, computed } from "vue"',
|
|
3775
|
+
`export const frontmatter = reactive(${JSON.stringify(fontmatter)})`,
|
|
3776
|
+
`export const meta = reactive({
|
|
3777
|
+
layout: computed(() => frontmatter.layout),
|
|
3778
|
+
transition: computed(() => frontmatter.transition),
|
|
3779
|
+
class: computed(() => frontmatter.class),
|
|
3780
|
+
clicks: computed(() => frontmatter.clicks),
|
|
3781
|
+
name: computed(() => frontmatter.name),
|
|
3782
|
+
preload: computed(() => frontmatter.preload),
|
|
3783
|
+
slide: {
|
|
3784
|
+
...(${JSON.stringify(slideBase)}),
|
|
3785
|
+
frontmatter,
|
|
3786
|
+
filepath: ${JSON.stringify(slide.source.filepath)},
|
|
3787
|
+
start: ${JSON.stringify(slide.source.start)},
|
|
3788
|
+
id: ${pageNo},
|
|
3789
|
+
no: ${no},
|
|
3790
|
+
},
|
|
3791
|
+
__clicksContext: null,
|
|
3792
|
+
__preloaded: false,
|
|
3793
|
+
})`,
|
|
3794
|
+
"export default frontmatter",
|
|
3795
|
+
// handle HMR, update frontmatter with update
|
|
3796
|
+
"if (import.meta.hot) {",
|
|
3797
|
+
" import.meta.hot.accept(({ frontmatter: update }) => {",
|
|
3798
|
+
" if(!update) return",
|
|
3799
|
+
" Object.keys(frontmatter).forEach(key => {",
|
|
3800
|
+
" if (!(key in update)) delete frontmatter[key]",
|
|
3801
|
+
" })",
|
|
3802
|
+
" Object.assign(frontmatter, update)",
|
|
3803
|
+
" })",
|
|
3804
|
+
"}"
|
|
3805
|
+
].join("\n"),
|
|
3806
|
+
map: { mappings: "" }
|
|
3807
|
+
};
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3810
|
+
return {
|
|
3811
|
+
code: "",
|
|
3812
|
+
map: { mappings: "" }
|
|
3813
|
+
};
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
},
|
|
3817
|
+
{
|
|
3818
|
+
name: "slidev:layout-transform:pre",
|
|
3819
|
+
enforce: "pre",
|
|
3820
|
+
async transform(code, id) {
|
|
3821
|
+
if (!id.startsWith(slidePrefix))
|
|
3822
|
+
return;
|
|
3823
|
+
const remaning = id.slice(slidePrefix.length);
|
|
3824
|
+
const match = remaning.match(regexIdQuery);
|
|
3825
|
+
if (!match)
|
|
3826
|
+
return;
|
|
3827
|
+
const [, no, type] = match;
|
|
3828
|
+
if (type !== "md")
|
|
3829
|
+
return;
|
|
3830
|
+
const pageNo = Number.parseInt(no) - 1;
|
|
3831
|
+
return transformMarkdown(code, pageNo);
|
|
3832
|
+
}
|
|
3833
|
+
},
|
|
3834
|
+
{
|
|
3835
|
+
name: "slidev:context-transform:pre",
|
|
3836
|
+
enforce: "pre",
|
|
3837
|
+
async transform(code, id) {
|
|
3838
|
+
if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
|
|
3839
|
+
return;
|
|
3840
|
+
return transformVue(code);
|
|
3841
|
+
}
|
|
3842
|
+
},
|
|
3843
|
+
{
|
|
3844
|
+
name: "slidev:title-transform:pre",
|
|
3845
|
+
enforce: "pre",
|
|
3846
|
+
transform(code, id) {
|
|
3847
|
+
if (id !== "/@slidev/titles.md")
|
|
3848
|
+
return;
|
|
3849
|
+
return transformTitles(code);
|
|
3850
|
+
}
|
|
3851
|
+
},
|
|
3852
|
+
{
|
|
3853
|
+
name: "slidev:slide-transform:post",
|
|
3854
|
+
enforce: "post",
|
|
3855
|
+
transform(code, id) {
|
|
3856
|
+
if (!id.match(/\/@slidev\/slides\/\d+\.md($|\?)/))
|
|
3857
|
+
return;
|
|
3858
|
+
const replaced = code.replace("if (_rerender_only)", "if (false)");
|
|
3859
|
+
if (replaced !== code)
|
|
3860
|
+
return replaced;
|
|
3861
|
+
}
|
|
3862
|
+
},
|
|
3863
|
+
{
|
|
3864
|
+
name: "slidev:index-html-transform",
|
|
3865
|
+
transformIndexHtml() {
|
|
3866
|
+
const { info, author, keywords } = data.headmatter;
|
|
3867
|
+
return [
|
|
3868
|
+
{
|
|
3869
|
+
tag: "title",
|
|
3870
|
+
children: getTitle()
|
|
3871
|
+
},
|
|
3872
|
+
info && {
|
|
3873
|
+
tag: "meta",
|
|
3874
|
+
attrs: {
|
|
3875
|
+
name: "description",
|
|
3876
|
+
content: info
|
|
3877
|
+
}
|
|
3878
|
+
},
|
|
3879
|
+
author && {
|
|
3880
|
+
tag: "meta",
|
|
3881
|
+
attrs: {
|
|
3882
|
+
name: "author",
|
|
3883
|
+
content: author
|
|
3884
|
+
}
|
|
3885
|
+
},
|
|
3886
|
+
keywords && {
|
|
3887
|
+
tag: "meta",
|
|
3888
|
+
attrs: {
|
|
3889
|
+
name: "keywords",
|
|
3890
|
+
content: Array.isArray(keywords) ? keywords.join(", ") : keywords
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
].filter(isTruthy2);
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
];
|
|
3897
|
+
function updateServerWatcher() {
|
|
3898
|
+
if (!server)
|
|
3899
|
+
return;
|
|
3900
|
+
server.watcher.add(data.watchFiles);
|
|
3750
3901
|
}
|
|
3751
|
-
|
|
3752
|
-
return
|
|
3902
|
+
function getFrontmatter(pageNo) {
|
|
3903
|
+
return {
|
|
3904
|
+
...data.headmatter?.defaults || {},
|
|
3905
|
+
...data.slides[pageNo]?.frontmatter || {}
|
|
3906
|
+
};
|
|
3753
3907
|
}
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3908
|
+
async function transformMarkdown(code, pageNo) {
|
|
3909
|
+
const layouts = await getLayouts();
|
|
3910
|
+
const frontmatter = getFrontmatter(pageNo);
|
|
3911
|
+
let layoutName = frontmatter?.layout || (pageNo === 0 ? "cover" : "default");
|
|
3912
|
+
if (!layouts[layoutName]) {
|
|
3913
|
+
console.error(red(`
|
|
3914
|
+
Unknown layout "${bold(layoutName)}".${yellow(" Available layouts are:")}`) + Object.keys(layouts).map((i, idx) => (idx % 3 === 0 ? "\n " : "") + gray(i.padEnd(15, " "))).join(" "));
|
|
3915
|
+
console.error();
|
|
3916
|
+
layoutName = "default";
|
|
3917
|
+
}
|
|
3918
|
+
delete frontmatter.title;
|
|
3919
|
+
const imports = [
|
|
3920
|
+
`import InjectedLayout from "${toAtFS(layouts[layoutName])}"`,
|
|
3921
|
+
`import frontmatter from "${toAtFS(`${slidePrefix + (pageNo + 1)}.frontmatter`)}"`,
|
|
3922
|
+
templateImportContextUtils,
|
|
3923
|
+
"_provideFrontmatter(frontmatter)",
|
|
3924
|
+
templateInitContext,
|
|
3925
|
+
templateInjectionMarker
|
|
3926
|
+
];
|
|
3927
|
+
code = code.replace(/(<script setup.*>)/g, `$1
|
|
3928
|
+
${imports.join("\n")}
|
|
3929
|
+
`);
|
|
3930
|
+
const injectA = code.indexOf("<template>") + "<template>".length;
|
|
3931
|
+
const injectB = code.lastIndexOf("</template>");
|
|
3932
|
+
let body = code.slice(injectA, injectB).trim();
|
|
3933
|
+
if (body.startsWith("<div>") && body.endsWith("</div>"))
|
|
3934
|
+
body = body.slice(5, -6);
|
|
3935
|
+
code = `${code.slice(0, injectA)}
|
|
3936
|
+
<InjectedLayout v-bind="_frontmatterToProps(frontmatter,${pageNo})">
|
|
3937
|
+
${body}
|
|
3938
|
+
</InjectedLayout>
|
|
3939
|
+
${code.slice(injectB)}`;
|
|
3940
|
+
return code;
|
|
3770
3941
|
}
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3942
|
+
function transformVue(code) {
|
|
3943
|
+
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
|
|
3944
|
+
return code;
|
|
3945
|
+
const imports = [
|
|
3946
|
+
templateImportContextUtils,
|
|
3947
|
+
templateInitContext,
|
|
3948
|
+
templateInjectionMarker
|
|
3949
|
+
];
|
|
3950
|
+
const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
|
|
3951
|
+
if (matchScript && matchScript[2]) {
|
|
3952
|
+
return code.replace(/(<script.*>)/g, `$1
|
|
3953
|
+
${imports.join("\n")}
|
|
3954
|
+
`);
|
|
3955
|
+
} else if (matchScript && !matchScript[2]) {
|
|
3956
|
+
const matchExport = code.match(/export\s+default\s+{/);
|
|
3957
|
+
if (matchExport) {
|
|
3958
|
+
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
3959
|
+
let component = code.slice(exportIndex);
|
|
3960
|
+
component = component.slice(0, component.indexOf("</script>"));
|
|
3961
|
+
const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
|
|
3962
|
+
const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
|
|
3963
|
+
code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
|
|
3964
|
+
let injectIndex = exportIndex + provideImport.length;
|
|
3965
|
+
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
3966
|
+
const matchInject = component.match(/.*inject\s*:\s*([\[{])/);
|
|
3967
|
+
if (matchInject) {
|
|
3968
|
+
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
3969
|
+
if (matchInject[1] === "[") {
|
|
3970
|
+
let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
|
|
3971
|
+
const injectEndIndex = injects.indexOf("]");
|
|
3972
|
+
injects = injects.slice(0, injectEndIndex);
|
|
3973
|
+
injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
|
|
3974
|
+
return `${code.slice(0, injectIndex - 1)}{
|
|
3975
|
+
${injectObject}
|
|
3976
|
+
}${code.slice(injectIndex + injectEndIndex + 1)}`;
|
|
3977
|
+
} else {
|
|
3978
|
+
return `${code.slice(0, injectIndex)}
|
|
3979
|
+
${injectObject}
|
|
3980
|
+
${code.slice(injectIndex)}`;
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
return `${code.slice(0, injectIndex)}
|
|
3984
|
+
inject: { ${injectObject} },
|
|
3985
|
+
${code.slice(injectIndex)}`;
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
return `<script setup>
|
|
3989
|
+
${imports.join("\n")}
|
|
3990
|
+
</script>
|
|
3991
|
+
${code}`;
|
|
3778
3992
|
}
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
if (langToUse === "" && options.defaultLanguageForUnspecified !== void 0)
|
|
3783
|
-
langToUse = options.defaultLanguageForUnspecified;
|
|
3784
|
-
let prismLang = loadPrismLang(langToUse);
|
|
3785
|
-
if (prismLang === void 0 && options.defaultLanguageForUnknown !== void 0) {
|
|
3786
|
-
langToUse = options.defaultLanguageForUnknown;
|
|
3787
|
-
prismLang = loadPrismLang(langToUse);
|
|
3993
|
+
function transformTitles(code) {
|
|
3994
|
+
return code.replace(/<template>\s*<div>\s*<p>/, "<template>").replace(/<\/p>\s*<\/div>\s*<\/template>/, "</template>").replace(/<script\ssetup>/, `<script setup lang="ts">
|
|
3995
|
+
defineProps<{ no: number | string }>()`);
|
|
3788
3996
|
}
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
onclosetag() {
|
|
3806
|
-
openTags.pop();
|
|
3807
|
-
}
|
|
3808
|
-
});
|
|
3809
|
-
code = Prism.highlight(code, prismLang, langToUse);
|
|
3810
|
-
code = code.split(/\r?\n/g).map((line) => {
|
|
3811
|
-
const prefix = openTags.map((tag) => tag.asOpen()).join("");
|
|
3812
|
-
parser2.write(line);
|
|
3813
|
-
const postfix = openTags.reverse().map((tag) => tag.asClosed()).join("");
|
|
3814
|
-
return prefix + line + postfix;
|
|
3815
|
-
}).join("\n");
|
|
3816
|
-
parser2.end();
|
|
3817
|
-
return code;
|
|
3818
|
-
}
|
|
3819
|
-
function checkLanguageOption(options, optionName) {
|
|
3820
|
-
const language = options[optionName];
|
|
3821
|
-
if (language !== void 0 && loadPrismLang(language) === void 0)
|
|
3822
|
-
throw new Error(`Bad option ${optionName}: There is no Prism language '${language}'.`);
|
|
3823
|
-
}
|
|
3824
|
-
function markdownItPrism(markdownit, useroptions) {
|
|
3825
|
-
const options = Object.assign({}, DEFAULTS, useroptions);
|
|
3826
|
-
checkLanguageOption(options, "defaultLanguage");
|
|
3827
|
-
checkLanguageOption(options, "defaultLanguageForUnknown");
|
|
3828
|
-
checkLanguageOption(options, "defaultLanguageForUnspecified");
|
|
3829
|
-
options.defaultLanguageForUnknown = options.defaultLanguageForUnknown || options.defaultLanguage;
|
|
3830
|
-
options.defaultLanguageForUnspecified = options.defaultLanguageForUnspecified || options.defaultLanguage;
|
|
3831
|
-
options.plugins.forEach(loadPrismPlugin);
|
|
3832
|
-
options.init(Prism);
|
|
3833
|
-
markdownit.options.highlight = (text, lang) => highlight(markdownit, options, text, lang);
|
|
3834
|
-
}
|
|
3835
|
-
|
|
3836
|
-
// node/plugins/transformSnippet.ts
|
|
3837
|
-
import path from "node:path";
|
|
3838
|
-
import fs5 from "fs-extra";
|
|
3839
|
-
function dedent(text) {
|
|
3840
|
-
const lines = text.split("\n");
|
|
3841
|
-
const minIndentLength = lines.reduce((acc, line) => {
|
|
3842
|
-
for (let i = 0; i < line.length; i++) {
|
|
3843
|
-
if (line[i] !== " " && line[i] !== " ")
|
|
3844
|
-
return Math.min(i, acc);
|
|
3845
|
-
}
|
|
3846
|
-
return acc;
|
|
3847
|
-
}, Number.POSITIVE_INFINITY);
|
|
3848
|
-
if (minIndentLength < Number.POSITIVE_INFINITY)
|
|
3849
|
-
return lines.map((x) => x.slice(minIndentLength)).join("\n");
|
|
3850
|
-
return text;
|
|
3851
|
-
}
|
|
3852
|
-
function testLine(line, regexp, regionName, end = false) {
|
|
3853
|
-
const [full, tag, name] = regexp.exec(line.trim()) || [];
|
|
3854
|
-
return full && tag && name === regionName && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/);
|
|
3855
|
-
}
|
|
3856
|
-
function findRegion(lines, regionName) {
|
|
3857
|
-
const regionRegexps = [
|
|
3858
|
-
/^\/\/ ?#?((?:end)?region) ([\w*-]+)$/,
|
|
3859
|
-
// javascript, typescript, java
|
|
3860
|
-
/^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/,
|
|
3861
|
-
// css, less, scss
|
|
3862
|
-
/^#pragma ((?:end)?region) ([\w*-]+)$/,
|
|
3863
|
-
// C, C++
|
|
3864
|
-
/^<!-- #?((?:end)?region) ([\w*-]+) -->$/,
|
|
3865
|
-
// HTML, markdown
|
|
3866
|
-
/^#((?:End )Region) ([\w*-]+)$/,
|
|
3867
|
-
// Visual Basic
|
|
3868
|
-
/^::#((?:end)region) ([\w*-]+)$/,
|
|
3869
|
-
// Bat
|
|
3870
|
-
/^# ?((?:end)?region) ([\w*-]+)$/
|
|
3871
|
-
// C#, PHP, Powershell, Python, perl & misc
|
|
3872
|
-
];
|
|
3873
|
-
let regexp = null;
|
|
3874
|
-
let start = -1;
|
|
3875
|
-
for (const [lineId, line] of lines.entries()) {
|
|
3876
|
-
if (regexp === null) {
|
|
3877
|
-
for (const reg of regionRegexps) {
|
|
3878
|
-
if (testLine(line, reg, regionName)) {
|
|
3879
|
-
start = lineId + 1;
|
|
3880
|
-
regexp = reg;
|
|
3881
|
-
break;
|
|
3882
|
-
}
|
|
3997
|
+
async function getLayouts() {
|
|
3998
|
+
const now = Date.now();
|
|
3999
|
+
if (now - _layouts_cache_time < 2e3)
|
|
4000
|
+
return _layouts_cache;
|
|
4001
|
+
const layouts = {};
|
|
4002
|
+
for (const root of [...roots, clientRoot]) {
|
|
4003
|
+
const layoutPaths = await fg2("layouts/**/*.{vue,ts}", {
|
|
4004
|
+
cwd: root,
|
|
4005
|
+
absolute: true,
|
|
4006
|
+
suppressErrors: true
|
|
4007
|
+
});
|
|
4008
|
+
for (const layoutPath of layoutPaths) {
|
|
4009
|
+
const layout = basename2(layoutPath).replace(/\.\w+$/, "");
|
|
4010
|
+
if (layouts[layout])
|
|
4011
|
+
continue;
|
|
4012
|
+
layouts[layout] = layoutPath;
|
|
3883
4013
|
}
|
|
3884
|
-
} else if (testLine(line, regexp, regionName, true)) {
|
|
3885
|
-
return { start, end: lineId, regexp };
|
|
3886
4014
|
}
|
|
4015
|
+
_layouts_cache_time = now;
|
|
4016
|
+
_layouts_cache = layouts;
|
|
4017
|
+
return layouts;
|
|
3887
4018
|
}
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
lines.slice(region.start, region.end).filter((line) => !region.regexp.test(line.trim())).join("\n")
|
|
3916
|
-
);
|
|
4019
|
+
async function resolveUrl(id) {
|
|
4020
|
+
return toAtFS(await resolveImportPath(id, true));
|
|
4021
|
+
}
|
|
4022
|
+
function resolveUrlOfClient(name) {
|
|
4023
|
+
return toAtFS(join4(clientRoot, name));
|
|
4024
|
+
}
|
|
4025
|
+
async function generateUserStyles() {
|
|
4026
|
+
const imports = [
|
|
4027
|
+
`import "${resolveUrlOfClient("styles/vars.css")}"`,
|
|
4028
|
+
`import "${resolveUrlOfClient("styles/index.css")}"`,
|
|
4029
|
+
`import "${resolveUrlOfClient("styles/code.css")}"`,
|
|
4030
|
+
`import "${resolveUrlOfClient("styles/katex.css")}"`,
|
|
4031
|
+
`import "${resolveUrlOfClient("styles/transitions.css")}"`,
|
|
4032
|
+
`import "${resolveUrlOfClient("styles/monaco.css")}"`
|
|
4033
|
+
];
|
|
4034
|
+
for (const root of roots) {
|
|
4035
|
+
const styles = [
|
|
4036
|
+
join4(root, "styles", "index.ts"),
|
|
4037
|
+
join4(root, "styles", "index.js"),
|
|
4038
|
+
join4(root, "styles", "index.css"),
|
|
4039
|
+
join4(root, "styles.css"),
|
|
4040
|
+
join4(root, "style.css")
|
|
4041
|
+
];
|
|
4042
|
+
for (const style of styles) {
|
|
4043
|
+
if (fs5.existsSync(style)) {
|
|
4044
|
+
imports.push(`import "${toAtFS(style)}"`);
|
|
4045
|
+
continue;
|
|
3917
4046
|
}
|
|
3918
4047
|
}
|
|
3919
|
-
return `${firstLine}
|
|
3920
|
-
${content}
|
|
3921
|
-
\`\`\``;
|
|
3922
4048
|
}
|
|
3923
|
-
|
|
3924
|
-
}
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
]);
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
4049
|
+
if (data.features.katex)
|
|
4050
|
+
imports.push(`import "${await resolveUrl("katex/dist/katex.min.css")}"`);
|
|
4051
|
+
if (data.config.highlighter === "shiki") {
|
|
4052
|
+
imports.push(
|
|
4053
|
+
`import "${await resolveUrl("@shikijs/vitepress-twoslash/style.css")}"`,
|
|
4054
|
+
`import "${resolveUrlOfClient("styles/shiki-twoslash.css")}"`
|
|
4055
|
+
);
|
|
4056
|
+
}
|
|
4057
|
+
if (data.config.css === "unocss") {
|
|
4058
|
+
imports.unshift(
|
|
4059
|
+
`import "${await resolveUrl("@unocss/reset/tailwind.css")}"`,
|
|
4060
|
+
'import "uno:preflights.css"',
|
|
4061
|
+
'import "uno:typography.css"',
|
|
4062
|
+
'import "uno:shortcuts.css"'
|
|
4063
|
+
);
|
|
4064
|
+
imports.push('import "uno.css"');
|
|
4065
|
+
}
|
|
4066
|
+
return imports.join("\n");
|
|
4067
|
+
}
|
|
4068
|
+
async function generateMonacoTypes() {
|
|
4069
|
+
const typesRoot = join4(userRoot, "snippets");
|
|
4070
|
+
const files = await fg2(["**/*.ts", "**/*.mts", "**/*.cts"], { cwd: typesRoot });
|
|
4071
|
+
let result = [
|
|
4072
|
+
'import * as monaco from "monaco-editor"',
|
|
4073
|
+
"async function addFile(mod, path) {",
|
|
4074
|
+
" const code = (await mod).default",
|
|
4075
|
+
' monaco.languages.typescript.typescriptDefaults.addExtraLib(code, "file:///" + path)',
|
|
4076
|
+
' monaco.editor.createModel(code, "javascript", monaco.Uri.file(path))',
|
|
4077
|
+
"}"
|
|
4078
|
+
].join("\n");
|
|
4079
|
+
for (const file of files) {
|
|
4080
|
+
const url = `${toAtFS(resolve2(typesRoot, file))}?raw`;
|
|
4081
|
+
result += `addFile(import(${JSON.stringify(url)}), ${JSON.stringify(file)})
|
|
4082
|
+
`;
|
|
4083
|
+
}
|
|
4084
|
+
const deps = data.config.monacoTypesAdditionalPackages;
|
|
4085
|
+
if (data.config.monacoTypesSource === "local")
|
|
4086
|
+
deps.push(...scanMonacoModules(data.slides.map((s) => s.source.raw).join()));
|
|
4087
|
+
function mapModuleNameToModule(moduleSpecifier) {
|
|
4088
|
+
if (moduleSpecifier.startsWith("node:"))
|
|
4089
|
+
return "node";
|
|
4090
|
+
if (builtinModules.includes(moduleSpecifier))
|
|
4091
|
+
return "node";
|
|
4092
|
+
const mainPackageName = moduleSpecifier.split("/")[0];
|
|
4093
|
+
if (builtinModules.includes(mainPackageName) && !mainPackageName.startsWith("@"))
|
|
4094
|
+
return "node";
|
|
4095
|
+
const [a = "", b = ""] = moduleSpecifier.split("/");
|
|
4096
|
+
const moduleName = a.startsWith("@") ? `${a}/${b}` : a;
|
|
4097
|
+
return moduleName;
|
|
4098
|
+
}
|
|
4099
|
+
for (const specifier of deps) {
|
|
4100
|
+
if (specifier[0] === ".")
|
|
4101
|
+
continue;
|
|
4102
|
+
const moduleName = mapModuleNameToModule(specifier);
|
|
4103
|
+
result += `import(${JSON.stringify(`/@slidev-monaco-types/resolve/${moduleName}`)})
|
|
4104
|
+
`;
|
|
4105
|
+
}
|
|
4106
|
+
return result;
|
|
4107
|
+
}
|
|
4108
|
+
async function generateLayouts() {
|
|
4109
|
+
const imports = [];
|
|
4110
|
+
const layouts = objectMap(
|
|
4111
|
+
await getLayouts(),
|
|
4112
|
+
(k, v) => {
|
|
4113
|
+
imports.push(`import __layout_${k} from "${toAtFS(v)}"`);
|
|
4114
|
+
return [k, `__layout_${k}`];
|
|
3969
4115
|
}
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
4116
|
+
);
|
|
4117
|
+
return [
|
|
4118
|
+
imports.join("\n"),
|
|
4119
|
+
`export default {
|
|
4120
|
+
${Object.entries(layouts).map(([k, v]) => `"${k}": ${v}`).join(",\n")}
|
|
4121
|
+
}`
|
|
4122
|
+
].join("\n\n");
|
|
4123
|
+
}
|
|
4124
|
+
async function generateRoutes() {
|
|
4125
|
+
const imports = [];
|
|
4126
|
+
const redirects = [];
|
|
4127
|
+
const layouts = await getLayouts();
|
|
4128
|
+
imports.push(
|
|
4129
|
+
`import { markRaw } from 'vue'`,
|
|
4130
|
+
`import __layout__end from '${layouts.end}'`
|
|
4131
|
+
);
|
|
4132
|
+
let no = 1;
|
|
4133
|
+
const routes = data.slides.map((i, idx) => {
|
|
4134
|
+
imports.push(`import n${no} from '${slidePrefix}${idx + 1}.md'`);
|
|
4135
|
+
imports.push(`import { meta as f${no} } from '${slidePrefix}${idx + 1}.frontmatter'`);
|
|
4136
|
+
const route = `{ path: '${no}', name: 'page-${no}', component: n${no}, meta: f${no} }`;
|
|
4137
|
+
if (i.frontmatter?.routeAlias)
|
|
4138
|
+
redirects.push(`{ path: '${i.frontmatter?.routeAlias}', redirect: { path: '${no}' } }`);
|
|
4139
|
+
no += 1;
|
|
4140
|
+
return route;
|
|
3974
4141
|
});
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
4142
|
+
const routesStr = `export const rawRoutes = [
|
|
4143
|
+
${routes.join(",\n")}
|
|
4144
|
+
].map(markRaw)`;
|
|
4145
|
+
const redirectsStr = `export const redirects = [
|
|
4146
|
+
${redirects.join(",\n")}
|
|
4147
|
+
].map(markRaw)`;
|
|
4148
|
+
return [...imports, routesStr, redirectsStr].join("\n");
|
|
3978
4149
|
}
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
include: [/\.md$/],
|
|
3984
|
-
wrapperClasses: "",
|
|
3985
|
-
headEnabled: false,
|
|
3986
|
-
frontmatter: false,
|
|
3987
|
-
escapeCodeTagInterpolation: false,
|
|
3988
|
-
markdownItOptions: {
|
|
3989
|
-
quotes: `""''`,
|
|
3990
|
-
html: true,
|
|
3991
|
-
xhtmlOut: true,
|
|
3992
|
-
linkify: true,
|
|
3993
|
-
...mdOptions?.markdownItOptions
|
|
3994
|
-
},
|
|
3995
|
-
...mdOptions,
|
|
3996
|
-
markdownItSetup(md2) {
|
|
3997
|
-
md2.use(mila2, {
|
|
3998
|
-
attrs: {
|
|
3999
|
-
target: "_blank",
|
|
4000
|
-
rel: "noopener"
|
|
4001
|
-
}
|
|
4002
|
-
});
|
|
4003
|
-
md2.use(mif);
|
|
4004
|
-
md2.use(taskLists, { enabled: true, lineNumber: true, label: true });
|
|
4005
|
-
md2.use(math_plugin, KatexOptions);
|
|
4006
|
-
setups.forEach((i) => i(md2));
|
|
4007
|
-
mdOptions?.markdownItSetup?.(md2);
|
|
4008
|
-
},
|
|
4009
|
-
transforms: {
|
|
4010
|
-
before(code, id) {
|
|
4011
|
-
if (id === entryPath)
|
|
4012
|
-
return "";
|
|
4013
|
-
const monaco = config.monaco === true || config.monaco === mode ? transformMarkdownMonaco : truncateMancoMark;
|
|
4014
|
-
if (config.highlighter === "shiki")
|
|
4015
|
-
code = transformMagicMove(code, shiki, shikiOptions);
|
|
4016
|
-
code = transformSlotSugar(code);
|
|
4017
|
-
code = transformSnippet(code, options, id);
|
|
4018
|
-
code = transformMermaid(code);
|
|
4019
|
-
code = transformPlantUml(code, config.plantUmlServer);
|
|
4020
|
-
code = monaco(code);
|
|
4021
|
-
code = transformHighlighter(code);
|
|
4022
|
-
code = transformPageCSS(code, id);
|
|
4023
|
-
code = transformKaTex(code);
|
|
4024
|
-
return code;
|
|
4025
|
-
}
|
|
4150
|
+
function getTitle() {
|
|
4151
|
+
if (isString(data.config.title)) {
|
|
4152
|
+
const tokens = md.parseInline(data.config.title, {});
|
|
4153
|
+
return stringifyMarkdownTokens(tokens);
|
|
4026
4154
|
}
|
|
4027
|
-
|
|
4155
|
+
return data.config.title;
|
|
4156
|
+
}
|
|
4157
|
+
function generateConfigs() {
|
|
4158
|
+
const config = {
|
|
4159
|
+
...data.config,
|
|
4160
|
+
remote,
|
|
4161
|
+
title: getTitle()
|
|
4162
|
+
};
|
|
4163
|
+
if (isString(config.info))
|
|
4164
|
+
config.info = md.render(config.info);
|
|
4165
|
+
return `export default ${JSON.stringify(config)}`;
|
|
4166
|
+
}
|
|
4167
|
+
async function generateGlobalComponents(layer) {
|
|
4168
|
+
const components = roots.flatMap((root) => {
|
|
4169
|
+
if (layer === "top") {
|
|
4170
|
+
return [
|
|
4171
|
+
join4(root, "global.vue"),
|
|
4172
|
+
join4(root, "global-top.vue"),
|
|
4173
|
+
join4(root, "GlobalTop.vue")
|
|
4174
|
+
];
|
|
4175
|
+
} else {
|
|
4176
|
+
return [
|
|
4177
|
+
join4(root, "global-bottom.vue"),
|
|
4178
|
+
join4(root, "GlobalBottom.vue")
|
|
4179
|
+
];
|
|
4180
|
+
}
|
|
4181
|
+
}).filter((i) => fs5.existsSync(i));
|
|
4182
|
+
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
4183
|
+
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
4184
|
+
return `
|
|
4185
|
+
${imports}
|
|
4186
|
+
import { h } from 'vue'
|
|
4187
|
+
export default {
|
|
4188
|
+
render() {
|
|
4189
|
+
return [${render}]
|
|
4190
|
+
}
|
|
4028
4191
|
}
|
|
4029
|
-
function transformKaTex(md2) {
|
|
4030
|
-
return md2.replace(/^\$\$(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?\s*?)?\n([\s\S]+?)^\$\$/mg, (full, rangeStr = "", options = "", code) => {
|
|
4031
|
-
const ranges = rangeStr.split(/\|/g).map((i) => i.trim());
|
|
4032
|
-
code = code.trimEnd();
|
|
4033
|
-
options = options.trim() || "{}";
|
|
4034
|
-
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
4035
|
-
|
|
4036
|
-
$$
|
|
4037
|
-
${code}
|
|
4038
|
-
$$
|
|
4039
|
-
</KaTexBlockWrapper>
|
|
4040
4192
|
`;
|
|
4041
|
-
}
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
}
|
|
4059
|
-
function truncateMancoMark(md2) {
|
|
4060
|
-
return md2.replace(/{monaco.*?}/g, "");
|
|
4193
|
+
}
|
|
4194
|
+
async function generateCustomNavControls() {
|
|
4195
|
+
const components = roots.flatMap((root) => {
|
|
4196
|
+
return [
|
|
4197
|
+
join4(root, "custom-nav-controls.vue"),
|
|
4198
|
+
join4(root, "CustomNavControls.vue")
|
|
4199
|
+
];
|
|
4200
|
+
}).filter((i) => fs5.existsSync(i));
|
|
4201
|
+
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
4202
|
+
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
4203
|
+
return `
|
|
4204
|
+
${imports}
|
|
4205
|
+
import { h } from 'vue'
|
|
4206
|
+
export default {
|
|
4207
|
+
render() {
|
|
4208
|
+
return [${render}]
|
|
4209
|
+
}
|
|
4061
4210
|
}
|
|
4062
|
-
function transformSlotSugar(md2) {
|
|
4063
|
-
const lines = md2.split(/\r?\n/g);
|
|
4064
|
-
let prevSlot = false;
|
|
4065
|
-
const { isLineInsideCodeblocks } = getCodeBlocks(md2);
|
|
4066
|
-
lines.forEach((line, idx) => {
|
|
4067
|
-
if (isLineInsideCodeblocks(idx))
|
|
4068
|
-
return;
|
|
4069
|
-
const match = line.trimEnd().match(/^::\s*([\w\.\-\:]+)\s*::$/);
|
|
4070
|
-
if (match) {
|
|
4071
|
-
lines[idx] = `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
4072
4211
|
`;
|
|
4073
|
-
|
|
4212
|
+
}
|
|
4213
|
+
async function generteShikiBundle() {
|
|
4214
|
+
const options = await loadShikiSetups(clientRoot, roots);
|
|
4215
|
+
const langs = await resolveLangs(options.langs || ["javascript", "typescript", "html", "css"]);
|
|
4216
|
+
const resolvedThemeOptions = "themes" in options ? {
|
|
4217
|
+
themes: Object.fromEntries(await Promise.all(
|
|
4218
|
+
Object.entries(options.themes).map(async ([name, value]) => [name, await resolveTheme(value)])
|
|
4219
|
+
))
|
|
4220
|
+
} : {
|
|
4221
|
+
theme: await resolveTheme(options.theme || "vitesse-dark")
|
|
4222
|
+
};
|
|
4223
|
+
const themes = resolvedThemeOptions.themes ? Object.values(resolvedThemeOptions.themes) : [resolvedThemeOptions.theme];
|
|
4224
|
+
const themeOptionsNames = resolvedThemeOptions.themes ? { themes: Object.fromEntries(Object.entries(resolvedThemeOptions.themes).map(([name, value]) => [name, typeof value === "string" ? value : value.name])) } : { theme: typeof resolvedThemeOptions.theme === "string" ? resolvedThemeOptions.theme : resolvedThemeOptions.theme.name };
|
|
4225
|
+
async function normalizeGetter(p) {
|
|
4226
|
+
return Promise.resolve(typeof p === "function" ? p() : p).then((r) => r.default || r);
|
|
4074
4227
|
}
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
}
|
|
4080
|
-
var reMagicMoveBlock = /^````(?:md|markdown) magic-move(?:[ ]*?({.*?})?([^\n]*?))?\n([\s\S]+?)^````$/mg;
|
|
4081
|
-
var reCodeBlock = /^```(\w+?)(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?(.*?))?\n([\s\S]+?)^```$/mg;
|
|
4082
|
-
function transformMagicMove(md2, shiki2, shikiOptions2) {
|
|
4083
|
-
const scripts = [];
|
|
4084
|
-
let count = 0;
|
|
4085
|
-
md2 = md2.replace(
|
|
4086
|
-
reMagicMoveBlock,
|
|
4087
|
-
(full, _options = "", _attrs = "", body) => {
|
|
4088
|
-
if (!shiki2 || !shikiOptions2)
|
|
4089
|
-
throw new Error("Shiki is required for Magic Move. You may need to set `highlighter: shiki` in your Slidev config.");
|
|
4090
|
-
const matches = Array.from(body.matchAll(reCodeBlock));
|
|
4091
|
-
if (!matches.length)
|
|
4092
|
-
throw new Error("Magic Move block must contain at least one code block");
|
|
4093
|
-
const langs = new Set(matches.map((i) => i[1]));
|
|
4094
|
-
if (langs.size > 1)
|
|
4095
|
-
throw new Error(`Magic Move block must contain code blocks with the same language, got ${Array.from(langs).join(", ")}`);
|
|
4096
|
-
const lang = Array.from(langs)[0];
|
|
4097
|
-
const magicMove = createMagicMoveMachine(
|
|
4098
|
-
(code) => codeToKeyedTokens(shiki2, code, {
|
|
4099
|
-
...shikiOptions2,
|
|
4100
|
-
lang
|
|
4101
|
-
})
|
|
4102
|
-
);
|
|
4103
|
-
const steps = matches.map((i) => magicMove.commit((i[5] || "").trimEnd()));
|
|
4104
|
-
const id = `__magicMoveSteps_${getHash(body)}_${count++}`;
|
|
4105
|
-
scripts.push(`const ${id} = Object.freeze(${JSON.stringify(steps)})`);
|
|
4106
|
-
return `<ShikiMagicMove :steps='${id}' />`;
|
|
4228
|
+
async function resolveLangs(langs2) {
|
|
4229
|
+
return Array.from(new Set((await Promise.all(
|
|
4230
|
+
langs2.map(async (lang) => await normalizeGetter(lang).then((r) => Array.isArray(r) ? r : [r]))
|
|
4231
|
+
)).flat()));
|
|
4107
4232
|
}
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
md2 = `<script setup>
|
|
4111
|
-
${scripts.join("\n")}</script>
|
|
4112
|
-
|
|
4113
|
-
${md2}`;
|
|
4114
|
-
return md2;
|
|
4115
|
-
}
|
|
4116
|
-
function transformHighlighter(md2) {
|
|
4117
|
-
return md2.replace(
|
|
4118
|
-
reCodeBlock,
|
|
4119
|
-
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
4120
|
-
const ranges = rangeStr.split(/\|/g).map((i) => i.trim());
|
|
4121
|
-
code = code.trimEnd();
|
|
4122
|
-
options = options.trim() || "{}";
|
|
4123
|
-
return `
|
|
4124
|
-
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
4125
|
-
|
|
4126
|
-
\`\`\`${lang}${attrs}
|
|
4127
|
-
${code}
|
|
4128
|
-
\`\`\`
|
|
4129
|
-
|
|
4130
|
-
</CodeBlockWrapper>`;
|
|
4233
|
+
async function resolveTheme(theme) {
|
|
4234
|
+
return typeof theme === "string" ? theme : await normalizeGetter(theme);
|
|
4131
4235
|
}
|
|
4132
|
-
|
|
4236
|
+
const langsInit = await Promise.all(
|
|
4237
|
+
langs.map(async (lang) => typeof lang === "string" ? `import('${await resolveUrl(`shiki/langs/${lang}.mjs`)}')` : JSON.stringify(lang))
|
|
4238
|
+
);
|
|
4239
|
+
const themesInit = await Promise.all(themes.map(async (theme) => typeof theme === "string" ? `import('${await resolveUrl(`shiki/themes/${theme}.mjs`)}')` : JSON.stringify(theme)));
|
|
4240
|
+
const langNames = langs.flatMap((lang) => typeof lang === "string" ? lang : lang.name);
|
|
4241
|
+
const lines = [];
|
|
4242
|
+
lines.push(
|
|
4243
|
+
`import { getHighlighterCore } from "${await resolveUrl("shiki/core")}"`,
|
|
4244
|
+
`export { shikiToMonaco } from "${await resolveUrl("@shikijs/monaco")}"`,
|
|
4245
|
+
`export const languages = ${JSON.stringify(langNames)}`,
|
|
4246
|
+
`export const themes = ${JSON.stringify(themeOptionsNames.themes || themeOptionsNames.theme)}`,
|
|
4247
|
+
"export const shiki = getHighlighterCore({",
|
|
4248
|
+
` themes: [${themesInit.join(",")}],`,
|
|
4249
|
+
` langs: [${langsInit.join(",")}],`,
|
|
4250
|
+
` loadWasm: import('${await resolveUrl("shiki/wasm")}'),`,
|
|
4251
|
+
"})"
|
|
4252
|
+
);
|
|
4253
|
+
return lines.join("\n");
|
|
4254
|
+
}
|
|
4133
4255
|
}
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
});
|
|
4256
|
+
|
|
4257
|
+
// node/plugins/setupClient.ts
|
|
4258
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
4259
|
+
import { join as join5, resolve as resolve3 } from "node:path";
|
|
4260
|
+
import { slash as slash2, uniq as uniq2 } from "@antfu/utils";
|
|
4261
|
+
function createClientSetupPlugin({ themeRoots, addonRoots, userRoot, clientRoot }) {
|
|
4262
|
+
const setupEntry = slash2(resolve3(clientRoot, "setup"));
|
|
4142
4263
|
return {
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4264
|
+
name: "slidev:setup",
|
|
4265
|
+
enforce: "pre",
|
|
4266
|
+
async transform(code, id) {
|
|
4267
|
+
if (id.startsWith(setupEntry)) {
|
|
4268
|
+
let getInjections2 = function(isAwait = false, isChained = false) {
|
|
4269
|
+
return injections.join("\n").replace(/:AWAIT:/g, isAwait ? "await " : "").replace(/(,\s*)?:LAST:/g, isChained ? "$1injection_return" : "");
|
|
4270
|
+
};
|
|
4271
|
+
var getInjections = getInjections2;
|
|
4272
|
+
const name = id.slice(setupEntry.length + 1).replace(/\?.*$/, "");
|
|
4273
|
+
const imports = [];
|
|
4274
|
+
const injections = [];
|
|
4275
|
+
const setups = uniq2([
|
|
4276
|
+
...themeRoots,
|
|
4277
|
+
...addonRoots,
|
|
4278
|
+
userRoot
|
|
4279
|
+
]).map((i) => join5(i, "setup", name));
|
|
4280
|
+
setups.forEach((path2, idx) => {
|
|
4281
|
+
if (!existsSync2(path2))
|
|
4282
|
+
return;
|
|
4283
|
+
imports.push(`import __n${idx} from '${toAtFS(path2)}'`);
|
|
4284
|
+
let fn = `:AWAIT:__n${idx}`;
|
|
4285
|
+
if (/\binjection_return\b/g.test(code))
|
|
4286
|
+
fn = `injection_return = ${fn}`;
|
|
4287
|
+
if (/\binjection_arg\b/g.test(code)) {
|
|
4288
|
+
fn += "(";
|
|
4289
|
+
const matches = Array.from(code.matchAll(/\binjection_arg(_\d+)?\b/g));
|
|
4290
|
+
const dedupedMatches = Array.from(new Set(matches.map((m) => m[0])));
|
|
4291
|
+
fn += dedupedMatches.join(", ");
|
|
4292
|
+
fn += ", :LAST:)";
|
|
4293
|
+
} else {
|
|
4294
|
+
fn += "(:LAST:)";
|
|
4295
|
+
}
|
|
4296
|
+
injections.push(
|
|
4297
|
+
`// ${path2}`,
|
|
4298
|
+
fn
|
|
4299
|
+
);
|
|
4300
|
+
});
|
|
4301
|
+
code = code.replace("/* __imports__ */", imports.join("\n"));
|
|
4302
|
+
code = code.replace("/* __injections__ */", getInjections2());
|
|
4303
|
+
code = code.replace("/* __async_injections__ */", getInjections2(true));
|
|
4304
|
+
code = code.replace("/* __chained_injections__ */", getInjections2(false, true));
|
|
4305
|
+
code = code.replace("/* __chained_async_injections__ */", getInjections2(true, true));
|
|
4306
|
+
return code;
|
|
4307
|
+
}
|
|
4308
|
+
return null;
|
|
4149
4309
|
}
|
|
4150
4310
|
};
|
|
4151
4311
|
}
|
|
4152
|
-
function transformPageCSS(md2, id) {
|
|
4153
|
-
const page = id.match(/(\d+)\.md$/)?.[1];
|
|
4154
|
-
if (!page)
|
|
4155
|
-
return md2;
|
|
4156
|
-
const { isInsideCodeblocks } = getCodeBlocks(md2);
|
|
4157
|
-
const result = md2.replace(
|
|
4158
|
-
/(\n<style[^>]*?>)([\s\S]+?)(<\/style>)/g,
|
|
4159
|
-
(full, start, css, end, index) => {
|
|
4160
|
-
if (index < 0 || isInsideCodeblocks(index))
|
|
4161
|
-
return full;
|
|
4162
|
-
if (!start.includes("scoped"))
|
|
4163
|
-
start = start.replace("<style", "<style scoped");
|
|
4164
|
-
return `${start}
|
|
4165
|
-
${css}${end}`;
|
|
4166
|
-
}
|
|
4167
|
-
);
|
|
4168
|
-
return result;
|
|
4169
|
-
}
|
|
4170
|
-
function transformMermaid(md2) {
|
|
4171
|
-
return md2.replace(/^```mermaid\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", code = "") => {
|
|
4172
|
-
code = code.trim();
|
|
4173
|
-
options = options.trim() || "{}";
|
|
4174
|
-
const encoded = base64.encode(code, true);
|
|
4175
|
-
return `<Mermaid :code="'${encoded}'" v-bind="${options}" />`;
|
|
4176
|
-
});
|
|
4177
|
-
}
|
|
4178
|
-
function transformPlantUml(md2, server) {
|
|
4179
|
-
return md2.replace(/^```plantuml\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", content = "") => {
|
|
4180
|
-
const code = encode2(content.trim());
|
|
4181
|
-
options = options.trim() || "{}";
|
|
4182
|
-
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
4183
|
-
});
|
|
4184
|
-
}
|
|
4185
|
-
function escapeVueInCode(md2) {
|
|
4186
|
-
return md2.replace(/{{/g, "{{");
|
|
4187
|
-
}
|
|
4188
|
-
async function loadShikiSetups(clientRoot, roots) {
|
|
4189
|
-
const result = await loadSetups(
|
|
4190
|
-
clientRoot,
|
|
4191
|
-
roots,
|
|
4192
|
-
"shiki.ts",
|
|
4193
|
-
{
|
|
4194
|
-
/** @deprecated */
|
|
4195
|
-
async loadTheme(path2) {
|
|
4196
|
-
console.warn("[slidev] `loadTheme` in `setup/shiki.ts` is deprecated. Pass directly the theme name it's supported by Shiki. For custom themes, load it manually via `JSON.parse(fs.readFileSync(path, 'utf-8'))` and pass the raw JSON object instead.");
|
|
4197
|
-
return JSON.parse(await fs6.readFile(path2, "utf-8"));
|
|
4198
|
-
}
|
|
4199
|
-
},
|
|
4200
|
-
{},
|
|
4201
|
-
false
|
|
4202
|
-
);
|
|
4203
|
-
if ("theme" in result && "themes" in result)
|
|
4204
|
-
delete result.theme;
|
|
4205
|
-
if (result.theme && typeof result.theme !== "string" && !result.theme.name && !result.theme.tokenColors) {
|
|
4206
|
-
result.themes = result.theme;
|
|
4207
|
-
delete result.theme;
|
|
4208
|
-
}
|
|
4209
|
-
if (!result.theme && !result.themes) {
|
|
4210
|
-
result.themes = {
|
|
4211
|
-
dark: "vitesse-dark",
|
|
4212
|
-
light: "vitesse-light"
|
|
4213
|
-
};
|
|
4214
|
-
}
|
|
4215
|
-
if (result.themes)
|
|
4216
|
-
result.defaultColor = false;
|
|
4217
|
-
return result;
|
|
4218
|
-
}
|
|
4219
4312
|
|
|
4220
4313
|
// node/plugins/patchTransform.ts
|
|
4221
4314
|
import { objectEntries } from "@antfu/utils";
|
|
@@ -4239,6 +4332,72 @@ function createFixPlugins(options) {
|
|
|
4239
4332
|
];
|
|
4240
4333
|
}
|
|
4241
4334
|
|
|
4335
|
+
// node/plugins/monacoTypes.ts
|
|
4336
|
+
import fs6 from "node:fs/promises";
|
|
4337
|
+
import { dirname as dirname2, resolve as resolve4 } from "node:path";
|
|
4338
|
+
import { slash as slash3 } from "@antfu/utils";
|
|
4339
|
+
import fg3 from "fast-glob";
|
|
4340
|
+
import { findDepPkgJsonPath } from "vitefu";
|
|
4341
|
+
function createMonacoTypesLoader({ userRoot }) {
|
|
4342
|
+
const resolvedDepsMap = {};
|
|
4343
|
+
return {
|
|
4344
|
+
name: "slidev:monaco-types-loader",
|
|
4345
|
+
resolveId(id) {
|
|
4346
|
+
if (id.startsWith("/@slidev-monaco-types/"))
|
|
4347
|
+
return id;
|
|
4348
|
+
return null;
|
|
4349
|
+
},
|
|
4350
|
+
async load(id) {
|
|
4351
|
+
const matchResolve = id.match(/^\/\@slidev-monaco-types\/resolve\/(.*?)(?:\?importer=(.*))?$/);
|
|
4352
|
+
if (matchResolve) {
|
|
4353
|
+
const [_, pkg, importer = userRoot] = matchResolve;
|
|
4354
|
+
const resolvedDeps = resolvedDepsMap[importer] ??= /* @__PURE__ */ new Set();
|
|
4355
|
+
if (resolvedDeps.has(pkg))
|
|
4356
|
+
return "";
|
|
4357
|
+
resolvedDeps.add(pkg);
|
|
4358
|
+
const pkgJsonPath = await findDepPkgJsonPath(pkg, importer);
|
|
4359
|
+
if (!pkgJsonPath)
|
|
4360
|
+
throw new Error(`Package "${pkg}" not found in "${importer}"`);
|
|
4361
|
+
const root = dirname2(pkgJsonPath);
|
|
4362
|
+
const pkgJson = JSON.parse(await fs6.readFile(pkgJsonPath, "utf-8"));
|
|
4363
|
+
const deps = pkgJson.dependencies ?? {};
|
|
4364
|
+
return [
|
|
4365
|
+
`import "/@slidev-monaco-types/load/${slash3(root)}&name=${pkgJson.name}"`,
|
|
4366
|
+
...Object.keys(deps).map((dep) => `import "/@slidev-monaco-types/resolve/${dep}?importer=${slash3(root)}"`)
|
|
4367
|
+
].join("\n");
|
|
4368
|
+
}
|
|
4369
|
+
const matchLoad = id.match(/^\/\@slidev-monaco-types\/load(\/.*?)&name=(.*)$/);
|
|
4370
|
+
if (matchLoad) {
|
|
4371
|
+
const [_, root, name] = matchLoad;
|
|
4372
|
+
const files = await fg3(
|
|
4373
|
+
[
|
|
4374
|
+
"**/*.d.ts",
|
|
4375
|
+
"**/*.d.mts",
|
|
4376
|
+
"**/*.d.cts",
|
|
4377
|
+
"package.json"
|
|
4378
|
+
],
|
|
4379
|
+
{
|
|
4380
|
+
cwd: root,
|
|
4381
|
+
followSymbolicLinks: true
|
|
4382
|
+
}
|
|
4383
|
+
);
|
|
4384
|
+
if (!files.length)
|
|
4385
|
+
return "";
|
|
4386
|
+
return [
|
|
4387
|
+
"import * as monaco from 'monaco-editor'",
|
|
4388
|
+
"async function addFile(mod, subPath) {",
|
|
4389
|
+
" const code = (await mod).default",
|
|
4390
|
+
` const path = ${JSON.stringify(`/node_modules/${name}/`)} + subPath`,
|
|
4391
|
+
' monaco.languages.typescript.typescriptDefaults.addExtraLib(code, "file://" + path)',
|
|
4392
|
+
' monaco.editor.createModel(code, "javascript", monaco.Uri.file(path))',
|
|
4393
|
+
"}",
|
|
4394
|
+
...files.map((file) => `addFile(import(${JSON.stringify(`${toAtFS(resolve4(root, file))}?raw`)}), ${JSON.stringify(file)})`)
|
|
4395
|
+
].join("\n");
|
|
4396
|
+
}
|
|
4397
|
+
}
|
|
4398
|
+
};
|
|
4399
|
+
}
|
|
4400
|
+
|
|
4242
4401
|
// node/plugins/preset.ts
|
|
4243
4402
|
var customElements = /* @__PURE__ */ new Set([
|
|
4244
4403
|
// katex
|
|
@@ -4302,7 +4461,7 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
4302
4461
|
const VueJsxPlugin = VueJsx(vuejsxOptions);
|
|
4303
4462
|
const MarkdownPlugin = await createMarkdownPlugin(options, pluginOptions);
|
|
4304
4463
|
const drawingData = await loadDrawings(options);
|
|
4305
|
-
const publicRoots = [...themeRoots, ...addonRoots].map((i) =>
|
|
4464
|
+
const publicRoots = [...themeRoots, ...addonRoots].map((i) => join6(i, "public")).filter(existsSync3);
|
|
4306
4465
|
const plugins = [
|
|
4307
4466
|
MarkdownPlugin,
|
|
4308
4467
|
VueJsxPlugin,
|
|
@@ -4311,11 +4470,11 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
4311
4470
|
Components({
|
|
4312
4471
|
extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
|
|
4313
4472
|
dirs: [
|
|
4314
|
-
|
|
4315
|
-
...roots.map((i) =>
|
|
4473
|
+
join6(options.clientRoot, "builtin"),
|
|
4474
|
+
...roots.map((i) => join6(i, "components")),
|
|
4316
4475
|
"src/components",
|
|
4317
4476
|
"components",
|
|
4318
|
-
|
|
4477
|
+
join6(process2.cwd(), "components")
|
|
4319
4478
|
],
|
|
4320
4479
|
include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
|
|
4321
4480
|
exclude: [],
|
|
@@ -4346,7 +4505,7 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
4346
4505
|
...remoteAssetsOptions
|
|
4347
4506
|
})) : null,
|
|
4348
4507
|
ServerRef({
|
|
4349
|
-
debug:
|
|
4508
|
+
debug: process2.env.NODE_ENV === "development",
|
|
4350
4509
|
state: {
|
|
4351
4510
|
sync: false,
|
|
4352
4511
|
nav: {
|
|
@@ -4366,7 +4525,7 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
4366
4525
|
}),
|
|
4367
4526
|
createConfigPlugin(options),
|
|
4368
4527
|
createClientSetupPlugin(options),
|
|
4369
|
-
createMonacoTypesLoader(),
|
|
4528
|
+
createMonacoTypesLoader(options),
|
|
4370
4529
|
createFixPlugins(options),
|
|
4371
4530
|
publicRoots.length ? import("vite-plugin-static-copy").then((r) => r.viteStaticCopy({
|
|
4372
4531
|
silent: true,
|