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