vitepress-allyouneed 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/LICENSE +25 -0
- package/README.md +157 -0
- package/dist/index.cjs +1489 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +95 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +1441 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown-it.cjs +800 -0
- package/dist/markdown-it.cjs.map +1 -0
- package/dist/markdown-it.d.cts +34 -0
- package/dist/markdown-it.d.ts +34 -0
- package/dist/markdown-it.js +763 -0
- package/dist/markdown-it.js.map +1 -0
- package/dist/types-CapUIPbW.d.cts +262 -0
- package/dist/types-CapUIPbW.d.ts +262 -0
- package/dist/vite.cjs +783 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +30 -0
- package/dist/vite.d.ts +30 -0
- package/dist/vite.js +748 -0
- package/dist/vite.js.map +1 -0
- package/dist/vitepress.cjs +1468 -0
- package/dist/vitepress.cjs.map +1 -0
- package/dist/vitepress.d.cts +36 -0
- package/dist/vitepress.d.ts +36 -0
- package/dist/vitepress.js +1431 -0
- package/dist/vitepress.js.map +1 -0
- package/package.json +98 -0
- package/style.css +159 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1489 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
allYouNeedMarkdownIt: () => allYouNeedMarkdownIt,
|
|
34
|
+
createEmptyIndex: () => createEmptyIndex,
|
|
35
|
+
default: () => markdown_it_default,
|
|
36
|
+
defaultSlugify: () => defaultSlugify,
|
|
37
|
+
defineConfigWithAllYouNeed: () => defineConfigWithAllYouNeed,
|
|
38
|
+
extractCustomId: () => extractCustomId,
|
|
39
|
+
removeFile: () => removeFile,
|
|
40
|
+
resolveAsset: () => resolveAsset,
|
|
41
|
+
resolveOptions: () => resolveOptions,
|
|
42
|
+
resolveWikilink: () => resolveWikilink,
|
|
43
|
+
scanVault: () => scanVault,
|
|
44
|
+
updateFile: () => updateFile,
|
|
45
|
+
viteAllYouNeed: () => viteAllYouNeed
|
|
46
|
+
});
|
|
47
|
+
module.exports = __toCommonJS(src_exports);
|
|
48
|
+
|
|
49
|
+
// src/core/slugify.ts
|
|
50
|
+
var import_shared = require("@mdit-vue/shared");
|
|
51
|
+
function defaultSlugify(text) {
|
|
52
|
+
return (0, import_shared.slugify)(text);
|
|
53
|
+
}
|
|
54
|
+
var CUSTOM_ID_RE = /\s*\{#([^}\s]+)\}\s*$/;
|
|
55
|
+
function extractCustomId(headingText) {
|
|
56
|
+
const m = headingText.match(CUSTOM_ID_RE);
|
|
57
|
+
if (!m) return { text: headingText, customId: void 0 };
|
|
58
|
+
return {
|
|
59
|
+
text: headingText.replace(CUSTOM_ID_RE, ""),
|
|
60
|
+
customId: m[1]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/core/config-bridge.ts
|
|
65
|
+
var DEFAULT_ASSET_EXTENSIONS = [
|
|
66
|
+
// 位图
|
|
67
|
+
"bmp",
|
|
68
|
+
"gif",
|
|
69
|
+
"jpeg",
|
|
70
|
+
"jpg",
|
|
71
|
+
"png",
|
|
72
|
+
"svg",
|
|
73
|
+
"webp",
|
|
74
|
+
"avif",
|
|
75
|
+
"ico",
|
|
76
|
+
// 视频
|
|
77
|
+
"mp4",
|
|
78
|
+
"webm",
|
|
79
|
+
"mov",
|
|
80
|
+
"m4v",
|
|
81
|
+
// 音频
|
|
82
|
+
"mp3",
|
|
83
|
+
"wav",
|
|
84
|
+
"ogg",
|
|
85
|
+
"m4a",
|
|
86
|
+
"flac",
|
|
87
|
+
// 文档
|
|
88
|
+
"pdf",
|
|
89
|
+
// Obsidian 专属
|
|
90
|
+
"canvas",
|
|
91
|
+
"excalidraw"
|
|
92
|
+
];
|
|
93
|
+
var DEFAULT_IMAGE_EXTENSIONS = [
|
|
94
|
+
"bmp",
|
|
95
|
+
"gif",
|
|
96
|
+
"jpeg",
|
|
97
|
+
"jpg",
|
|
98
|
+
"png",
|
|
99
|
+
"svg",
|
|
100
|
+
"webp",
|
|
101
|
+
"avif",
|
|
102
|
+
"ico"
|
|
103
|
+
];
|
|
104
|
+
function resolveOptions(user = {}, ctx = {}) {
|
|
105
|
+
const srcDir = user.srcDir ?? ctx.srcDir ?? process.cwd();
|
|
106
|
+
let base = user.base ?? ctx.base ?? "/";
|
|
107
|
+
if (!base.startsWith("/")) base = "/" + base;
|
|
108
|
+
if (!base.endsWith("/")) base = base + "/";
|
|
109
|
+
const cleanUrls = user.cleanUrls ?? ctx.cleanUrls ?? false;
|
|
110
|
+
const slugify = user.slugify ?? ctx.externalSlugify ?? defaultSlugify;
|
|
111
|
+
const wikilinksUser = user.wikilinks ?? {};
|
|
112
|
+
const embedsUser = user.embeds ?? {};
|
|
113
|
+
const scanUser = user.scan ?? {};
|
|
114
|
+
const assetsUser = user.assets ?? {};
|
|
115
|
+
const modulesUser = user.modules ?? {};
|
|
116
|
+
const wikilinksHtmlAttrs = wikilinksUser.htmlAttributes ?? {};
|
|
117
|
+
const embedsHtmlAttrs = embedsUser.htmlAttributes ?? {};
|
|
118
|
+
return {
|
|
119
|
+
srcDir,
|
|
120
|
+
base,
|
|
121
|
+
cleanUrls,
|
|
122
|
+
caseSensitive: user.caseSensitive ?? false,
|
|
123
|
+
deadLink: user.deadLink ?? "warn",
|
|
124
|
+
onConflict: user.onConflict ?? "shortest",
|
|
125
|
+
onAliasConflict: user.onAliasConflict ?? "first",
|
|
126
|
+
scan: {
|
|
127
|
+
include: scanUser.include ?? ["**/*.md", "**/*.markdown"],
|
|
128
|
+
exclude: scanUser.exclude ?? [],
|
|
129
|
+
followSymlinks: scanUser.followSymlinks ?? false,
|
|
130
|
+
respectGitignore: scanUser.respectGitignore ?? true,
|
|
131
|
+
assetExtensions: scanUser.assetExtensions ?? DEFAULT_ASSET_EXTENSIONS
|
|
132
|
+
},
|
|
133
|
+
assets: {
|
|
134
|
+
mode: assetsUser.mode ?? "auto",
|
|
135
|
+
preserveAssetPaths: assetsUser.preserveAssetPaths ?? false,
|
|
136
|
+
outputDir: assetsUser.outputDir ?? "_assets"
|
|
137
|
+
},
|
|
138
|
+
wikilinks: {
|
|
139
|
+
postProcessLinkTarget: wikilinksUser.postProcessLinkTarget ?? ((t) => t.trim()),
|
|
140
|
+
postProcessLinkLabel: wikilinksUser.postProcessLinkLabel ?? ((l) => l.trim()),
|
|
141
|
+
allowLinkLabelFormatting: wikilinksUser.allowLinkLabelFormatting ?? false,
|
|
142
|
+
linkText: wikilinksUser.linkText ?? "basename",
|
|
143
|
+
htmlAttributes: wikilinksHtmlAttrs
|
|
144
|
+
},
|
|
145
|
+
embeds: {
|
|
146
|
+
imageFileExt: embedsUser.imageFileExt ?? DEFAULT_IMAGE_EXTENSIONS,
|
|
147
|
+
defaultAltText: embedsUser.defaultAltText ?? false,
|
|
148
|
+
postProcessImageTarget: embedsUser.postProcessImageTarget ?? ((t) => t.trim()),
|
|
149
|
+
postProcessAltText: embedsUser.postProcessAltText ?? ((a) => a.trim()),
|
|
150
|
+
uriSuffix: embedsUser.uriSuffix ?? "",
|
|
151
|
+
transclusionMaxDepth: embedsUser.transclusionMaxDepth ?? 8,
|
|
152
|
+
htmlAttributes: embedsHtmlAttrs
|
|
153
|
+
},
|
|
154
|
+
modules: {
|
|
155
|
+
wikilinks: modulesUser.wikilinks ?? true,
|
|
156
|
+
embeds: modulesUser.embeds ?? true
|
|
157
|
+
},
|
|
158
|
+
slugify
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/core/vault/index.ts
|
|
163
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
164
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
165
|
+
|
|
166
|
+
// src/utils/path.ts
|
|
167
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
168
|
+
function toPosix(p) {
|
|
169
|
+
return p.replace(/\\/g, "/");
|
|
170
|
+
}
|
|
171
|
+
function relative(from, to) {
|
|
172
|
+
return toPosix(import_node_path.default.relative(from, to));
|
|
173
|
+
}
|
|
174
|
+
function stripMarkdownExt(target) {
|
|
175
|
+
return target.replace(/\.(md|markdown)$/i, "");
|
|
176
|
+
}
|
|
177
|
+
function basename(p, stripExt = false) {
|
|
178
|
+
const idx = p.lastIndexOf("/");
|
|
179
|
+
const file = idx === -1 ? p : p.slice(idx + 1);
|
|
180
|
+
if (!stripExt) return file;
|
|
181
|
+
const dot = file.lastIndexOf(".");
|
|
182
|
+
return dot <= 0 ? file : file.slice(0, dot);
|
|
183
|
+
}
|
|
184
|
+
function extname(p) {
|
|
185
|
+
const file = basename(p);
|
|
186
|
+
const dot = file.lastIndexOf(".");
|
|
187
|
+
if (dot <= 0) return "";
|
|
188
|
+
return file.slice(dot + 1).toLowerCase();
|
|
189
|
+
}
|
|
190
|
+
function splitPath(p) {
|
|
191
|
+
return toPosix(p).split("/").filter(Boolean);
|
|
192
|
+
}
|
|
193
|
+
function pathDepth(relPath) {
|
|
194
|
+
return splitPath(relPath).length;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/utils/url.ts
|
|
198
|
+
function encodePath(s) {
|
|
199
|
+
return encodeURI(s);
|
|
200
|
+
}
|
|
201
|
+
function buildUrl(base, pathSegments, anchor) {
|
|
202
|
+
let normBase = base || "/";
|
|
203
|
+
if (!normBase.startsWith("/")) normBase = "/" + normBase;
|
|
204
|
+
if (!normBase.endsWith("/")) normBase = normBase + "/";
|
|
205
|
+
const joined = pathSegments.map((s) => s.replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
|
|
206
|
+
let url = normBase + joined;
|
|
207
|
+
url = url.replace(/\/{2,}/g, "/");
|
|
208
|
+
url = encodePath(url);
|
|
209
|
+
if (anchor) {
|
|
210
|
+
url += "#" + encodeURIComponent(anchor).replace(/%2F/g, "/");
|
|
211
|
+
}
|
|
212
|
+
return url;
|
|
213
|
+
}
|
|
214
|
+
function applyCleanUrls(path, cleanUrls) {
|
|
215
|
+
if (cleanUrls) return path;
|
|
216
|
+
if (/\.html$/i.test(path)) return path;
|
|
217
|
+
if (path.endsWith("/")) return path + "index.html";
|
|
218
|
+
return path + ".html";
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/core/vault/scan.ts
|
|
222
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
223
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
224
|
+
function walk(srcDir, isIgnored, followSymlinks) {
|
|
225
|
+
const out = [];
|
|
226
|
+
const seenInodes = /* @__PURE__ */ new Set();
|
|
227
|
+
function visit(dir) {
|
|
228
|
+
let entries;
|
|
229
|
+
try {
|
|
230
|
+
entries = import_node_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
231
|
+
} catch {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
for (const ent of entries) {
|
|
235
|
+
const full = import_node_path2.default.join(dir, ent.name);
|
|
236
|
+
const posix = toPosix(full);
|
|
237
|
+
if (isIgnored(posix)) continue;
|
|
238
|
+
let isDir = ent.isDirectory();
|
|
239
|
+
let isFile = ent.isFile();
|
|
240
|
+
if (ent.isSymbolicLink()) {
|
|
241
|
+
if (!followSymlinks) continue;
|
|
242
|
+
try {
|
|
243
|
+
const stat = import_node_fs.default.statSync(full);
|
|
244
|
+
isDir = stat.isDirectory();
|
|
245
|
+
isFile = stat.isFile();
|
|
246
|
+
} catch {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (isDir) {
|
|
251
|
+
if (followSymlinks) {
|
|
252
|
+
try {
|
|
253
|
+
const stat = import_node_fs.default.statSync(full);
|
|
254
|
+
const key = `${stat.dev}:${stat.ino}`;
|
|
255
|
+
if (seenInodes.has(key)) continue;
|
|
256
|
+
seenInodes.add(key);
|
|
257
|
+
} catch {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
visit(full);
|
|
262
|
+
} else if (isFile) {
|
|
263
|
+
try {
|
|
264
|
+
const stat = import_node_fs.default.statSync(full);
|
|
265
|
+
out.push({
|
|
266
|
+
absolutePath: posix,
|
|
267
|
+
size: stat.size,
|
|
268
|
+
mtime: stat.mtimeMs,
|
|
269
|
+
extension: extname(posix)
|
|
270
|
+
});
|
|
271
|
+
} catch {
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
visit(srcDir);
|
|
277
|
+
return out;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/core/vault/ignore.ts
|
|
281
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
282
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
283
|
+
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
284
|
+
var HARD_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
285
|
+
"node_modules",
|
|
286
|
+
".git",
|
|
287
|
+
".svn",
|
|
288
|
+
".hg",
|
|
289
|
+
".obsidian",
|
|
290
|
+
".trash",
|
|
291
|
+
".vitepress",
|
|
292
|
+
".next",
|
|
293
|
+
".nuxt",
|
|
294
|
+
".cache",
|
|
295
|
+
".idea",
|
|
296
|
+
".vscode",
|
|
297
|
+
"dist",
|
|
298
|
+
"build"
|
|
299
|
+
]);
|
|
300
|
+
function buildIgnorer(srcDir, userExclude, respectGitignore) {
|
|
301
|
+
const patterns = [...userExclude];
|
|
302
|
+
if (respectGitignore) {
|
|
303
|
+
const gitignore = import_node_path3.default.join(srcDir, ".gitignore");
|
|
304
|
+
try {
|
|
305
|
+
const content = import_node_fs2.default.readFileSync(gitignore, "utf8");
|
|
306
|
+
for (const line of content.split(/\r?\n/)) {
|
|
307
|
+
const trimmed = line.trim();
|
|
308
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
309
|
+
patterns.push(trimmed.endsWith("/") ? trimmed + "**" : trimmed);
|
|
310
|
+
}
|
|
311
|
+
} catch {
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const matchers = patterns.map(
|
|
315
|
+
(p) => (0, import_picomatch.default)(p, { dot: true, nocase: false })
|
|
316
|
+
);
|
|
317
|
+
return (absPath) => {
|
|
318
|
+
const rel = toPosix(relative(srcDir, absPath));
|
|
319
|
+
if (!rel || rel.startsWith("..")) return true;
|
|
320
|
+
for (const seg of rel.split("/")) {
|
|
321
|
+
if (HARD_IGNORE_DIRS.has(seg)) return true;
|
|
322
|
+
}
|
|
323
|
+
for (const m of matchers) {
|
|
324
|
+
if (m(rel)) return true;
|
|
325
|
+
}
|
|
326
|
+
return false;
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/core/vault/frontmatter.ts
|
|
331
|
+
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
332
|
+
function parseFrontmatter(raw) {
|
|
333
|
+
try {
|
|
334
|
+
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
335
|
+
return { data: data ?? {}, content };
|
|
336
|
+
} catch (err) {
|
|
337
|
+
return {
|
|
338
|
+
data: {},
|
|
339
|
+
content: raw,
|
|
340
|
+
error: err instanceof Error ? err.message : String(err)
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function normalizeAliases(raw) {
|
|
345
|
+
if (raw == null) return [];
|
|
346
|
+
if (typeof raw === "string") return raw.trim() ? [raw.trim()] : [];
|
|
347
|
+
if (Array.isArray(raw)) {
|
|
348
|
+
return raw.filter((v) => typeof v === "string").map((s) => s.trim()).filter(Boolean);
|
|
349
|
+
}
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
function normalizeTags(raw) {
|
|
353
|
+
if (raw == null) return [];
|
|
354
|
+
if (typeof raw === "string") {
|
|
355
|
+
return raw.split(/[,\s]+/).map((s) => s.trim().replace(/^#/, "")).filter(Boolean);
|
|
356
|
+
}
|
|
357
|
+
if (Array.isArray(raw)) {
|
|
358
|
+
return raw.filter((v) => typeof v === "string").map((s) => s.trim().replace(/^#/, "")).filter(Boolean);
|
|
359
|
+
}
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/core/vault/headings.ts
|
|
364
|
+
var HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/;
|
|
365
|
+
var FENCE_RE = /^(`{3,}|~{3,})/;
|
|
366
|
+
function collectHeadings(content, slugify) {
|
|
367
|
+
const lines = content.split(/\r?\n/);
|
|
368
|
+
const out = [];
|
|
369
|
+
let inFence = false;
|
|
370
|
+
let fenceMarker = "";
|
|
371
|
+
for (let i = 0; i < lines.length; i++) {
|
|
372
|
+
const line = lines[i];
|
|
373
|
+
const fenceMatch = line.match(FENCE_RE);
|
|
374
|
+
if (fenceMatch) {
|
|
375
|
+
if (!inFence) {
|
|
376
|
+
inFence = true;
|
|
377
|
+
fenceMarker = fenceMatch[1];
|
|
378
|
+
} else if (line.startsWith(fenceMarker)) {
|
|
379
|
+
inFence = false;
|
|
380
|
+
fenceMarker = "";
|
|
381
|
+
}
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
if (inFence) continue;
|
|
385
|
+
const m = line.match(HEADING_RE);
|
|
386
|
+
if (!m) continue;
|
|
387
|
+
const level = m[1].length;
|
|
388
|
+
const rawText = m[2];
|
|
389
|
+
const { text, customId } = extractCustomId(rawText);
|
|
390
|
+
const slug = customId ?? slugify(text);
|
|
391
|
+
out.push({ level, text, slug, line: i });
|
|
392
|
+
}
|
|
393
|
+
return out;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/core/vault/index.ts
|
|
397
|
+
var MD_EXTENSIONS = /* @__PURE__ */ new Set(["md", "markdown"]);
|
|
398
|
+
function createEmptyIndex(srcDir = "", base = "/", cleanUrls = false) {
|
|
399
|
+
return {
|
|
400
|
+
files: /* @__PURE__ */ new Map(),
|
|
401
|
+
assets: /* @__PURE__ */ new Map(),
|
|
402
|
+
byBasename: /* @__PURE__ */ new Map(),
|
|
403
|
+
byBasenameLower: /* @__PURE__ */ new Map(),
|
|
404
|
+
byAlias: /* @__PURE__ */ new Map(),
|
|
405
|
+
byRelativePath: /* @__PURE__ */ new Map(),
|
|
406
|
+
byUrl: /* @__PURE__ */ new Map(),
|
|
407
|
+
assetsByBasename: /* @__PURE__ */ new Map(),
|
|
408
|
+
assetsByBasenameLower: /* @__PURE__ */ new Map(),
|
|
409
|
+
assetsByRelativePath: /* @__PURE__ */ new Map(),
|
|
410
|
+
tags: /* @__PURE__ */ new Map(),
|
|
411
|
+
backlinks: /* @__PURE__ */ new Map(),
|
|
412
|
+
headings: /* @__PURE__ */ new Map(),
|
|
413
|
+
srcDir,
|
|
414
|
+
base,
|
|
415
|
+
cleanUrls,
|
|
416
|
+
scannedAt: Date.now(),
|
|
417
|
+
warnings: []
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function scanVault(options) {
|
|
421
|
+
const srcDir = toPosix(import_node_path4.default.resolve(options.srcDir));
|
|
422
|
+
const index = createEmptyIndex(srcDir, options.base, options.cleanUrls);
|
|
423
|
+
const isIgnored = buildIgnorer(
|
|
424
|
+
srcDir,
|
|
425
|
+
options.scan.exclude,
|
|
426
|
+
options.scan.respectGitignore
|
|
427
|
+
);
|
|
428
|
+
const assetExtSet = new Set(
|
|
429
|
+
options.scan.assetExtensions.map((e) => e.toLowerCase())
|
|
430
|
+
);
|
|
431
|
+
const entries = walk(srcDir, isIgnored, options.scan.followSymlinks);
|
|
432
|
+
for (const ent of entries) {
|
|
433
|
+
const ext = ent.extension;
|
|
434
|
+
if (MD_EXTENSIONS.has(ext)) {
|
|
435
|
+
ingestMarkdown(index, ent.absolutePath, ent.size, ent.mtime, options);
|
|
436
|
+
} else if (assetExtSet.has(ext)) {
|
|
437
|
+
ingestAsset(index, ent.absolutePath, ent.size, ent.mtime, ext);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
index.scannedAt = Date.now();
|
|
441
|
+
return index;
|
|
442
|
+
}
|
|
443
|
+
function ingestMarkdown(index, absPath, size, mtime, options) {
|
|
444
|
+
let raw;
|
|
445
|
+
try {
|
|
446
|
+
raw = import_node_fs3.default.readFileSync(absPath, "utf8");
|
|
447
|
+
} catch (err) {
|
|
448
|
+
index.warnings.push({
|
|
449
|
+
kind: "unreadable-file",
|
|
450
|
+
message: `\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6: ${absPath} (${err instanceof Error ? err.message : String(err)})`,
|
|
451
|
+
affected: [absPath]
|
|
452
|
+
});
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const { data, content, error } = parseFrontmatter(raw);
|
|
456
|
+
if (error) {
|
|
457
|
+
index.warnings.push({
|
|
458
|
+
kind: "invalid-frontmatter",
|
|
459
|
+
message: `frontmatter \u89E3\u6790\u5931\u8D25 (${absPath}): ${error}`,
|
|
460
|
+
affected: [absPath]
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
const aliases = normalizeAliases(data.aliases);
|
|
464
|
+
const tags = normalizeTags(data.tags);
|
|
465
|
+
const headings = collectHeadings(content, options.slugify);
|
|
466
|
+
const rel = relative(index.srcDir, absPath);
|
|
467
|
+
const base = basename(absPath, true);
|
|
468
|
+
const ext = extname(absPath);
|
|
469
|
+
const url = computeUrl(rel, options);
|
|
470
|
+
const entry = {
|
|
471
|
+
absolutePath: absPath,
|
|
472
|
+
relativePath: rel,
|
|
473
|
+
basename: base,
|
|
474
|
+
extension: ext,
|
|
475
|
+
url,
|
|
476
|
+
frontmatter: data,
|
|
477
|
+
aliases,
|
|
478
|
+
tags,
|
|
479
|
+
headings,
|
|
480
|
+
mtime,
|
|
481
|
+
size,
|
|
482
|
+
content
|
|
483
|
+
};
|
|
484
|
+
registerFileEntry(index, entry, options);
|
|
485
|
+
}
|
|
486
|
+
function ingestAsset(index, absPath, size, mtime, ext) {
|
|
487
|
+
const rel = relative(index.srcDir, absPath);
|
|
488
|
+
const base = basename(absPath);
|
|
489
|
+
const entry = {
|
|
490
|
+
absolutePath: absPath,
|
|
491
|
+
relativePath: rel,
|
|
492
|
+
basename: base,
|
|
493
|
+
extension: ext,
|
|
494
|
+
mtime,
|
|
495
|
+
size,
|
|
496
|
+
referencedBy: /* @__PURE__ */ new Set()
|
|
497
|
+
};
|
|
498
|
+
index.assets.set(absPath, entry);
|
|
499
|
+
index.assetsByRelativePath.set(rel, entry);
|
|
500
|
+
pushToArrayMap(index.assetsByBasename, base, entry);
|
|
501
|
+
pushToArrayMap(index.assetsByBasenameLower, base.toLowerCase(), entry);
|
|
502
|
+
}
|
|
503
|
+
function registerFileEntry(index, entry, options) {
|
|
504
|
+
index.files.set(entry.absolutePath, entry);
|
|
505
|
+
index.byRelativePath.set(entry.relativePath, entry);
|
|
506
|
+
const existingAtUrl = index.byUrl.get(entry.url);
|
|
507
|
+
if (existingAtUrl && existingAtUrl.absolutePath !== entry.absolutePath) {
|
|
508
|
+
index.warnings.push({
|
|
509
|
+
kind: "unknown",
|
|
510
|
+
message: `URL \u51B2\u7A81:\u6587\u4EF6 "${entry.relativePath}" \u548C "${existingAtUrl.relativePath}" \u90FD\u8DEF\u7531\u5230 "${entry.url}"\u3002VitePress \u4F1A\u8BA9\u5176\u4E2D\u4E00\u4E2A 404\u3002\u5EFA\u8BAE\u5728 .vitepress/config \u52A0 srcExclude: ['${entry.relativePath}'](\u6216\u53E6\u4E00\u4E2A)\u3002`,
|
|
511
|
+
affected: [existingAtUrl.absolutePath, entry.absolutePath]
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
index.byUrl.set(entry.url, entry);
|
|
515
|
+
index.headings.set(entry.absolutePath, entry.headings);
|
|
516
|
+
pushToArrayMap(index.byBasename, entry.basename, entry);
|
|
517
|
+
pushToArrayMap(index.byBasenameLower, entry.basename.toLowerCase(), entry);
|
|
518
|
+
for (const alias of entry.aliases) {
|
|
519
|
+
const key = options.caseSensitive ? alias : alias.toLowerCase();
|
|
520
|
+
if (index.byAlias.has(key)) {
|
|
521
|
+
index.warnings.push({
|
|
522
|
+
kind: "duplicate-alias",
|
|
523
|
+
message: `alias "${alias}" \u540C\u65F6\u88AB\u591A\u4E2A\u6587\u4EF6\u58F0\u660E,\u6309 onAliasConflict='${options.onAliasConflict}' \u5904\u7406`,
|
|
524
|
+
affected: [index.byAlias.get(key).absolutePath, entry.absolutePath]
|
|
525
|
+
});
|
|
526
|
+
if (options.onAliasConflict === "first") continue;
|
|
527
|
+
}
|
|
528
|
+
index.byAlias.set(key, entry);
|
|
529
|
+
}
|
|
530
|
+
for (const tag of entry.tags) {
|
|
531
|
+
pushToArrayMap(index.tags, tag, entry);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function computeUrl(rel, options) {
|
|
535
|
+
const noExt = rel.replace(/\.(md|markdown)$/i, "");
|
|
536
|
+
const isIndex = /(^|\/)(index|README)$/i.test(noExt);
|
|
537
|
+
const pathPart = isIndex ? noExt.replace(/(^|\/)(index|README)$/i, "$1") : noExt;
|
|
538
|
+
const segments = pathPart.split("/").filter(Boolean);
|
|
539
|
+
if (segments.length === 0) {
|
|
540
|
+
return options.base;
|
|
541
|
+
}
|
|
542
|
+
const last = segments[segments.length - 1];
|
|
543
|
+
if (!isIndex) {
|
|
544
|
+
segments[segments.length - 1] = applyCleanUrls(last, options.cleanUrls);
|
|
545
|
+
} else if (!options.cleanUrls) {
|
|
546
|
+
segments.push("index.html");
|
|
547
|
+
}
|
|
548
|
+
return buildUrl(options.base, segments);
|
|
549
|
+
}
|
|
550
|
+
function pushToArrayMap(m, k, v) {
|
|
551
|
+
const arr = m.get(k);
|
|
552
|
+
if (arr) arr.push(v);
|
|
553
|
+
else m.set(k, [v]);
|
|
554
|
+
}
|
|
555
|
+
function updateFile(index, absPath, options) {
|
|
556
|
+
const posix = toPosix(absPath);
|
|
557
|
+
removeFile(index, posix, options);
|
|
558
|
+
let stat;
|
|
559
|
+
try {
|
|
560
|
+
stat = import_node_fs3.default.statSync(posix);
|
|
561
|
+
} catch {
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
const ext = extname(posix);
|
|
565
|
+
if (MD_EXTENSIONS.has(ext)) {
|
|
566
|
+
ingestMarkdown(index, posix, stat.size, stat.mtimeMs, options);
|
|
567
|
+
} else if (new Set(options.scan.assetExtensions.map((e) => e.toLowerCase())).has(ext)) {
|
|
568
|
+
ingestAsset(index, posix, stat.size, stat.mtimeMs, ext);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
function removeFile(index, absPath, options) {
|
|
572
|
+
const posix = toPosix(absPath);
|
|
573
|
+
const file = index.files.get(posix);
|
|
574
|
+
if (file) {
|
|
575
|
+
index.files.delete(posix);
|
|
576
|
+
index.byRelativePath.delete(file.relativePath);
|
|
577
|
+
index.byUrl.delete(file.url);
|
|
578
|
+
index.headings.delete(posix);
|
|
579
|
+
removeFromArrayMap(index.byBasename, file.basename, file);
|
|
580
|
+
removeFromArrayMap(
|
|
581
|
+
index.byBasenameLower,
|
|
582
|
+
file.basename.toLowerCase(),
|
|
583
|
+
file
|
|
584
|
+
);
|
|
585
|
+
for (const alias of file.aliases) {
|
|
586
|
+
const key = options.caseSensitive ? alias : alias.toLowerCase();
|
|
587
|
+
if (index.byAlias.get(key) === file) index.byAlias.delete(key);
|
|
588
|
+
}
|
|
589
|
+
for (const tag of file.tags) {
|
|
590
|
+
removeFromArrayMap(index.tags, tag, file);
|
|
591
|
+
}
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
const asset = index.assets.get(posix);
|
|
595
|
+
if (asset) {
|
|
596
|
+
index.assets.delete(posix);
|
|
597
|
+
index.assetsByRelativePath.delete(asset.relativePath);
|
|
598
|
+
removeFromArrayMap(index.assetsByBasename, asset.basename, asset);
|
|
599
|
+
removeFromArrayMap(
|
|
600
|
+
index.assetsByBasenameLower,
|
|
601
|
+
asset.basename.toLowerCase(),
|
|
602
|
+
asset
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
function removeFromArrayMap(m, k, v) {
|
|
607
|
+
const arr = m.get(k);
|
|
608
|
+
if (!arr) return;
|
|
609
|
+
const idx = arr.indexOf(v);
|
|
610
|
+
if (idx >= 0) arr.splice(idx, 1);
|
|
611
|
+
if (arr.length === 0) m.delete(k);
|
|
612
|
+
}
|
|
613
|
+
function sortByShortestPath(items) {
|
|
614
|
+
return [...items].sort((a, b) => {
|
|
615
|
+
const da = pathDepth(a.relativePath);
|
|
616
|
+
const db = pathDepth(b.relativePath);
|
|
617
|
+
if (da !== db) return da - db;
|
|
618
|
+
return a.relativePath.localeCompare(b.relativePath);
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/core/resolver.ts
|
|
623
|
+
function resolveWikilink(rawTarget, index, options, kind = "page") {
|
|
624
|
+
let target = toPosix(rawTarget).trim();
|
|
625
|
+
const hashIdx = target.indexOf("#");
|
|
626
|
+
let headingPart = "";
|
|
627
|
+
if (hashIdx >= 0) {
|
|
628
|
+
headingPart = target.slice(hashIdx + 1).trim();
|
|
629
|
+
target = target.slice(0, hashIdx).trim();
|
|
630
|
+
}
|
|
631
|
+
target = stripMarkdownExt(target);
|
|
632
|
+
const entry = lookupEntry(target, index, options);
|
|
633
|
+
if (!entry) {
|
|
634
|
+
return {
|
|
635
|
+
url: buildDeadUrl(rawTarget, options),
|
|
636
|
+
defaultLabel: defaultLabel(target, headingPart, void 0, options),
|
|
637
|
+
isDead: true,
|
|
638
|
+
hasUnmatchedAnchor: false,
|
|
639
|
+
kind
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
let url = entry.url;
|
|
643
|
+
let hasUnmatchedAnchor = false;
|
|
644
|
+
if (headingPart) {
|
|
645
|
+
const heading = entry.headings.find(
|
|
646
|
+
(h) => h.text === headingPart || h.slug === headingPart || h.slug === options.slugify(headingPart)
|
|
647
|
+
);
|
|
648
|
+
if (heading) {
|
|
649
|
+
url = entry.url + "#" + heading.slug;
|
|
650
|
+
} else {
|
|
651
|
+
hasUnmatchedAnchor = true;
|
|
652
|
+
url = entry.url + "#" + encodeURIComponent(headingPart);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return {
|
|
656
|
+
url,
|
|
657
|
+
defaultLabel: defaultLabel(target, headingPart, entry, options),
|
|
658
|
+
isDead: false,
|
|
659
|
+
hasUnmatchedAnchor,
|
|
660
|
+
target: entry,
|
|
661
|
+
kind
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
function lookupEntry(target, index, options) {
|
|
665
|
+
if (!target) return void 0;
|
|
666
|
+
if (target.includes("/")) {
|
|
667
|
+
const variants = [
|
|
668
|
+
target,
|
|
669
|
+
target + ".md",
|
|
670
|
+
target + ".markdown",
|
|
671
|
+
target + "/index.md",
|
|
672
|
+
target + "/index.markdown"
|
|
673
|
+
];
|
|
674
|
+
for (const v of variants) {
|
|
675
|
+
const e = index.byRelativePath.get(v);
|
|
676
|
+
if (e) return e;
|
|
677
|
+
}
|
|
678
|
+
return void 0;
|
|
679
|
+
}
|
|
680
|
+
const aliasKey = options.caseSensitive ? target : target.toLowerCase();
|
|
681
|
+
const aliased = index.byAlias.get(aliasKey);
|
|
682
|
+
if (aliased) return aliased;
|
|
683
|
+
const bnMap = options.caseSensitive ? index.byBasename : index.byBasenameLower;
|
|
684
|
+
const bnKey = options.caseSensitive ? target : target.toLowerCase();
|
|
685
|
+
const candidates = bnMap.get(bnKey);
|
|
686
|
+
if (!candidates || candidates.length === 0) return void 0;
|
|
687
|
+
if (candidates.length === 1) return candidates[0];
|
|
688
|
+
switch (options.onConflict) {
|
|
689
|
+
case "shortest": {
|
|
690
|
+
const sorted = sortByShortestPath(candidates);
|
|
691
|
+
return sorted[0];
|
|
692
|
+
}
|
|
693
|
+
case "first":
|
|
694
|
+
return candidates[0];
|
|
695
|
+
case "error":
|
|
696
|
+
return void 0;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
function buildDeadUrl(rawTarget, options) {
|
|
700
|
+
const safe = encodeURIComponent(stripMarkdownExt(rawTarget).split("#")[0]);
|
|
701
|
+
return options.base + safe;
|
|
702
|
+
}
|
|
703
|
+
function defaultLabel(target, headingPart, entry, options) {
|
|
704
|
+
const lt = options.wikilinks.linkText;
|
|
705
|
+
let base;
|
|
706
|
+
if (typeof lt === "function") {
|
|
707
|
+
if (entry) {
|
|
708
|
+
base = lt(entry, target);
|
|
709
|
+
} else {
|
|
710
|
+
base = basename(target);
|
|
711
|
+
}
|
|
712
|
+
} else if (lt === "fullPath") {
|
|
713
|
+
base = entry ? entry.relativePath.replace(/\.(md|markdown)$/i, "") : target;
|
|
714
|
+
} else {
|
|
715
|
+
base = entry ? entry.basename : basename(target);
|
|
716
|
+
}
|
|
717
|
+
if (headingPart) {
|
|
718
|
+
return `${base} > ${headingPart}`;
|
|
719
|
+
}
|
|
720
|
+
return base;
|
|
721
|
+
}
|
|
722
|
+
function resolveAsset(rawTarget, index, options) {
|
|
723
|
+
const target = toPosix(rawTarget).trim();
|
|
724
|
+
if (target.includes("/")) {
|
|
725
|
+
return {
|
|
726
|
+
asset: index.assetsByRelativePath.get(target),
|
|
727
|
+
rawBasename: basename(target)
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
const bn = options.caseSensitive ? target : target.toLowerCase();
|
|
731
|
+
const map = options.caseSensitive ? index.assetsByBasename : index.assetsByBasenameLower;
|
|
732
|
+
const candidates = map.get(bn);
|
|
733
|
+
if (!candidates || candidates.length === 0) {
|
|
734
|
+
return { asset: void 0, rawBasename: target };
|
|
735
|
+
}
|
|
736
|
+
if (candidates.length === 1) {
|
|
737
|
+
return { asset: candidates[0], rawBasename: target };
|
|
738
|
+
}
|
|
739
|
+
switch (options.onConflict) {
|
|
740
|
+
case "shortest": {
|
|
741
|
+
const sorted = sortByShortestPath(candidates);
|
|
742
|
+
return { asset: sorted[0], rawBasename: target };
|
|
743
|
+
}
|
|
744
|
+
case "first":
|
|
745
|
+
return { asset: candidates[0], rawBasename: target };
|
|
746
|
+
case "error":
|
|
747
|
+
return { asset: void 0, rawBasename: target };
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/modules/wikilinks/render.ts
|
|
752
|
+
function renderPageLink(state, result, label, env) {
|
|
753
|
+
const open = state.push("link_open", "a", 1);
|
|
754
|
+
const classes = ["wikilink"];
|
|
755
|
+
if (result.hasUnmatchedAnchor) classes.push("wikilink--unmatched-anchor");
|
|
756
|
+
const baseAttrs = {
|
|
757
|
+
href: result.url,
|
|
758
|
+
class: classes.join(" "),
|
|
759
|
+
"data-wikilink-target": result.target ? result.target.relativePath : ""
|
|
760
|
+
};
|
|
761
|
+
const extra = resolveExtraAttrs(env.options.wikilinks.htmlAttributes, {
|
|
762
|
+
originalHref: result.url,
|
|
763
|
+
label,
|
|
764
|
+
target: result.target,
|
|
765
|
+
isDead: result.isDead,
|
|
766
|
+
hasUnmatchedAnchor: result.hasUnmatchedAnchor
|
|
767
|
+
});
|
|
768
|
+
applyAttrs(open, baseAttrs, extra);
|
|
769
|
+
emitLabel(state, label, env);
|
|
770
|
+
state.push("link_close", "a", -1);
|
|
771
|
+
return true;
|
|
772
|
+
}
|
|
773
|
+
function renderDeadLink(state, url, label, rawTarget, env) {
|
|
774
|
+
const open = state.push("link_open", "a", 1);
|
|
775
|
+
const baseAttrs = {
|
|
776
|
+
href: url,
|
|
777
|
+
class: "wikilink wikilink--dead",
|
|
778
|
+
"data-wikilink-target": rawTarget,
|
|
779
|
+
title: `\u6B7B\u94FE:\u627E\u4E0D\u5230 [[${rawTarget}]]`
|
|
780
|
+
};
|
|
781
|
+
const extra = resolveExtraAttrs(env.options.wikilinks.htmlAttributes, {
|
|
782
|
+
originalHref: url,
|
|
783
|
+
label,
|
|
784
|
+
target: void 0,
|
|
785
|
+
isDead: true,
|
|
786
|
+
hasUnmatchedAnchor: false
|
|
787
|
+
});
|
|
788
|
+
applyAttrs(open, baseAttrs, extra);
|
|
789
|
+
emitLabel(state, label, env);
|
|
790
|
+
state.push("link_close", "a", -1);
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
793
|
+
function emitLabel(state, label, env) {
|
|
794
|
+
if (env.options.wikilinks.allowLinkLabelFormatting) {
|
|
795
|
+
const depth = env._labelDepth ?? 0;
|
|
796
|
+
if (depth < 3) {
|
|
797
|
+
;
|
|
798
|
+
env._labelDepth = depth + 1;
|
|
799
|
+
const md = state.md;
|
|
800
|
+
const html = md.renderInline(label, env);
|
|
801
|
+
const token = state.push("html_inline", "", 0);
|
|
802
|
+
token.content = html;
|
|
803
|
+
env._labelDepth = depth;
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
const t = state.push("text", "", 0);
|
|
808
|
+
t.content = label;
|
|
809
|
+
}
|
|
810
|
+
function resolveExtraAttrs(htmlAttrs, ctx) {
|
|
811
|
+
if (typeof htmlAttrs === "function") return htmlAttrs(ctx);
|
|
812
|
+
return htmlAttrs ?? {};
|
|
813
|
+
}
|
|
814
|
+
function applyAttrs(token, base, extra) {
|
|
815
|
+
const merged = { ...base };
|
|
816
|
+
for (const [k, v] of Object.entries(extra)) {
|
|
817
|
+
if (k === "class" && merged.class) {
|
|
818
|
+
merged.class = merged.class + " " + v;
|
|
819
|
+
} else {
|
|
820
|
+
merged[k] = v;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
for (const [k, v] of Object.entries(merged)) {
|
|
824
|
+
token.attrSet(k, v);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// src/utils/escape.ts
|
|
829
|
+
var HTML_ESCAPE_MAP = {
|
|
830
|
+
"&": "&",
|
|
831
|
+
"<": "<",
|
|
832
|
+
">": ">",
|
|
833
|
+
'"': """,
|
|
834
|
+
"'": "'"
|
|
835
|
+
};
|
|
836
|
+
var HTML_ESCAPE_RE = /[&<>"']/g;
|
|
837
|
+
function escapeHtml(s) {
|
|
838
|
+
return s.replace(HTML_ESCAPE_RE, (c) => HTML_ESCAPE_MAP[c]);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// src/core/asset-pipeline/build-emit.ts
|
|
842
|
+
var ASSET_PLACEHOLDER_PREFIX = "/__ayn_asset__/";
|
|
843
|
+
function buildPlaceholderUrl(asset, options) {
|
|
844
|
+
const id = encodeURI(asset.relativePath);
|
|
845
|
+
return options.base + ASSET_PLACEHOLDER_PREFIX.slice(1) + id;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// src/modules/embeds/image.ts
|
|
849
|
+
function renderImageHtml(rawTarget, aliasParts, env) {
|
|
850
|
+
const { index, options } = env;
|
|
851
|
+
const { altText, dim } = parseAltAndDim(aliasParts);
|
|
852
|
+
const processedTarget = options.embeds.postProcessImageTarget(rawTarget);
|
|
853
|
+
const { asset } = resolveAsset(processedTarget, index, options);
|
|
854
|
+
let src;
|
|
855
|
+
if (asset) {
|
|
856
|
+
asset.referencedBy.add(env.currentPath ?? "<unknown>");
|
|
857
|
+
env.referencedAssets?.add(asset);
|
|
858
|
+
src = buildPlaceholderUrl(asset, options) + options.embeds.uriSuffix;
|
|
859
|
+
} else {
|
|
860
|
+
src = options.base + encodeURIComponent(basename(processedTarget)) + options.embeds.uriSuffix;
|
|
861
|
+
}
|
|
862
|
+
const finalAlt = determineAlt(altText, processedTarget, options);
|
|
863
|
+
const attrs = {
|
|
864
|
+
src,
|
|
865
|
+
alt: finalAlt ?? ""
|
|
866
|
+
};
|
|
867
|
+
if (dim.width !== void 0) attrs.width = String(dim.width);
|
|
868
|
+
if (dim.height !== void 0) attrs.height = String(dim.height);
|
|
869
|
+
const extra = resolveExtra(options.embeds.htmlAttributes, {
|
|
870
|
+
originalHref: src,
|
|
871
|
+
altText: finalAlt,
|
|
872
|
+
dimensions: dim.raw,
|
|
873
|
+
embedType: "image"
|
|
874
|
+
});
|
|
875
|
+
for (const [k, v] of Object.entries(extra)) {
|
|
876
|
+
if (k === "class" && attrs.class) {
|
|
877
|
+
attrs.class = attrs.class + " " + v;
|
|
878
|
+
} else {
|
|
879
|
+
attrs[k] = v;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
return "<img " + Object.entries(attrs).map(([k, v]) => `${escapeAttrName(k)}="${escapeHtml(v)}"`).join(" ") + " />";
|
|
883
|
+
}
|
|
884
|
+
function handleImageEmbed(state, rawTarget, aliasParts, env) {
|
|
885
|
+
const html = renderImageHtml(rawTarget, aliasParts, env);
|
|
886
|
+
const token = state.push("html_inline", "", 0);
|
|
887
|
+
token.content = html;
|
|
888
|
+
return true;
|
|
889
|
+
}
|
|
890
|
+
function parseAltAndDim(parts) {
|
|
891
|
+
if (parts.length === 0) return { altText: "", dim: { raw: "" } };
|
|
892
|
+
const last = parts[parts.length - 1];
|
|
893
|
+
const parsedLast = tryParseDimension(last);
|
|
894
|
+
if (parsedLast) {
|
|
895
|
+
const alt = parts.slice(0, -1).join("|").trim();
|
|
896
|
+
return { altText: alt, dim: { ...parsedLast, raw: last } };
|
|
897
|
+
}
|
|
898
|
+
return { altText: parts.join("|").trim(), dim: { raw: "" } };
|
|
899
|
+
}
|
|
900
|
+
function tryParseDimension(s) {
|
|
901
|
+
const trimmed = s.trim().toLowerCase();
|
|
902
|
+
if (!trimmed) return void 0;
|
|
903
|
+
if (trimmed.includes("x")) {
|
|
904
|
+
const [w, h] = trimmed.split("x");
|
|
905
|
+
const wOk = w === "" || /^\d+$/.test(w);
|
|
906
|
+
const hOk = h === "" || /^\d+$/.test(h);
|
|
907
|
+
if (!wOk || !hOk) return void 0;
|
|
908
|
+
if (w === "" && h === "") return void 0;
|
|
909
|
+
return {
|
|
910
|
+
width: w === "" ? void 0 : Number(w),
|
|
911
|
+
height: h === "" ? void 0 : Number(h)
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
if (/^\d+$/.test(trimmed)) {
|
|
915
|
+
return { width: Number(trimmed) };
|
|
916
|
+
}
|
|
917
|
+
return void 0;
|
|
918
|
+
}
|
|
919
|
+
function determineAlt(rawAlt, target, options) {
|
|
920
|
+
if (rawAlt && rawAlt !== "") {
|
|
921
|
+
return options.embeds.postProcessAltText(rawAlt);
|
|
922
|
+
}
|
|
923
|
+
const def = options.embeds.defaultAltText;
|
|
924
|
+
if (def === false) return void 0;
|
|
925
|
+
if (def === true) {
|
|
926
|
+
const bn = basename(target);
|
|
927
|
+
const dot = bn.lastIndexOf(".");
|
|
928
|
+
const noExt = dot > 0 ? bn.slice(0, dot) : bn;
|
|
929
|
+
return options.embeds.postProcessAltText(noExt);
|
|
930
|
+
}
|
|
931
|
+
if (typeof def === "string") {
|
|
932
|
+
return def === "" ? "" : options.embeds.postProcessAltText(def);
|
|
933
|
+
}
|
|
934
|
+
return options.embeds.postProcessAltText(basename(target));
|
|
935
|
+
}
|
|
936
|
+
function resolveExtra(attrs, ctx) {
|
|
937
|
+
if (typeof attrs === "function") return attrs(ctx);
|
|
938
|
+
return attrs ?? {};
|
|
939
|
+
}
|
|
940
|
+
function escapeAttrName(k) {
|
|
941
|
+
return k.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// src/modules/embeds/transclusion.ts
|
|
945
|
+
function renderTransclusionHtml(md, rawTarget, aliasParts, env) {
|
|
946
|
+
const { index, options } = env;
|
|
947
|
+
const result = resolveWikilink(rawTarget, index, options, "transclusion");
|
|
948
|
+
if (result.isDead || !result.target) {
|
|
949
|
+
return `<div class="transclusion transclusion--dead" data-target="${escapeHtml(
|
|
950
|
+
rawTarget
|
|
951
|
+
)}">\u26A0\uFE0F \u627E\u4E0D\u5230\u7B14\u8BB0 <code>${escapeHtml(rawTarget)}</code></div>`;
|
|
952
|
+
}
|
|
953
|
+
const target = result.target;
|
|
954
|
+
const arr = index.backlinks.get(target.absolutePath) ?? [];
|
|
955
|
+
if (env.currentPath) {
|
|
956
|
+
arr.push({
|
|
957
|
+
fromPath: env.currentPath,
|
|
958
|
+
fromUrl: index.files.get(env.currentPath)?.url ?? "",
|
|
959
|
+
context: "",
|
|
960
|
+
isEmbed: true,
|
|
961
|
+
line: -1
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
index.backlinks.set(target.absolutePath, arr);
|
|
965
|
+
const stack = env.transclusionStack ?? [];
|
|
966
|
+
if (stack.includes(target.absolutePath)) {
|
|
967
|
+
return `<div class="transclusion transclusion--cycle" data-target="${escapeHtml(
|
|
968
|
+
rawTarget
|
|
969
|
+
)}">\u26A0\uFE0F \u5FAA\u73AF\u5F15\u7528:<code>${escapeHtml(
|
|
970
|
+
rawTarget
|
|
971
|
+
)}</code> \u5DF2\u5728 transclusion \u94FE\u4E0A</div>`;
|
|
972
|
+
}
|
|
973
|
+
const depth = env.transclusionDepth ?? 0;
|
|
974
|
+
if (depth >= options.embeds.transclusionMaxDepth) {
|
|
975
|
+
return `<div class="transclusion transclusion--too-deep" data-target="${escapeHtml(
|
|
976
|
+
rawTarget
|
|
977
|
+
)}">\u26A0\uFE0F transclusion \u5D4C\u5957\u8FC7\u6DF1(> ${options.embeds.transclusionMaxDepth})</div>`;
|
|
978
|
+
}
|
|
979
|
+
const headingPart = extractHeading(rawTarget);
|
|
980
|
+
const fragment = headingPart ? sliceByHeading(target, headingPart, options.slugify) : target.content;
|
|
981
|
+
if (fragment == null) {
|
|
982
|
+
return `<div class="transclusion transclusion--unmatched-anchor" data-target="${escapeHtml(
|
|
983
|
+
rawTarget
|
|
984
|
+
)}">\u26A0\uFE0F \u627E\u4E0D\u5230\u7AE0\u8282 <code>#${escapeHtml(
|
|
985
|
+
headingPart
|
|
986
|
+
)}</code></div>`;
|
|
987
|
+
}
|
|
988
|
+
const cacheKey = `${target.absolutePath}::${headingPart ?? ""}`;
|
|
989
|
+
const cache = getCache(env);
|
|
990
|
+
let inner;
|
|
991
|
+
const cached = cache.get(cacheKey);
|
|
992
|
+
if (cached) {
|
|
993
|
+
inner = cached.html;
|
|
994
|
+
} else {
|
|
995
|
+
const childEnv = {
|
|
996
|
+
index: env.index,
|
|
997
|
+
options: env.options,
|
|
998
|
+
currentPath: target.absolutePath,
|
|
999
|
+
transclusionStack: [...stack, target.absolutePath],
|
|
1000
|
+
transclusionDepth: depth + 1,
|
|
1001
|
+
// 跨递归共享:asset 引用集合(build 时要 emit 所有被引用 asset)
|
|
1002
|
+
referencedAssets: env.referencedAssets
|
|
1003
|
+
};
|
|
1004
|
+
childEnv._transclusionCache = env._transclusionCache;
|
|
1005
|
+
inner = md.render(fragment, childEnv);
|
|
1006
|
+
cache.set(cacheKey, { html: inner });
|
|
1007
|
+
}
|
|
1008
|
+
const sourceUrl = headingPart ? `${target.url}#${escapeHtml(options.slugify(headingPart))}` : target.url;
|
|
1009
|
+
const aliasData = aliasParts.length ? ` data-caption="${escapeHtml(aliasParts.join("|"))}"` : "";
|
|
1010
|
+
return `<div class="transclusion" data-source="${escapeHtml(
|
|
1011
|
+
target.relativePath
|
|
1012
|
+
)}" data-source-url="${escapeHtml(sourceUrl)}"${aliasData}>${inner}</div>`;
|
|
1013
|
+
}
|
|
1014
|
+
function handleTransclusion(state, rawTarget, aliasParts, env) {
|
|
1015
|
+
if (env.options.deadLink !== "silent") {
|
|
1016
|
+
console.warn(
|
|
1017
|
+
`vitepress-allyouneed: ![[${rawTarget}]] \u5728\u6BB5\u843D\u4E2D\u65E0\u6CD5 transclude(\u4F1A\u4EA7\u751F\u4E0D\u5408\u6CD5 HTML),\u5DF2\u964D\u7EA7\u4E3A\u94FE\u63A5\u3002\u8BF7\u5355\u72EC\u653E\u4E00\u884C\u3002`
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
const { index, options } = env;
|
|
1021
|
+
const result = resolveWikilink(rawTarget, index, options, "page");
|
|
1022
|
+
const url = result.url;
|
|
1023
|
+
const label = aliasParts.length ? aliasParts.join("|").trim() : result.defaultLabel;
|
|
1024
|
+
const html = `<a class="wikilink wikilink--inline-transclusion-degraded" href="${escapeHtml(url)}" data-wikilink-target="${escapeHtml(rawTarget)}" title="\u884C\u5185 transclusion \u5DF2\u964D\u7EA7,\u89C1\u63A7\u5236\u53F0">${escapeHtml(label)}</a>`;
|
|
1025
|
+
const token = state.push("html_inline", "", 0);
|
|
1026
|
+
token.content = html;
|
|
1027
|
+
return true;
|
|
1028
|
+
}
|
|
1029
|
+
function extractHeading(raw) {
|
|
1030
|
+
const hashIdx = raw.indexOf("#");
|
|
1031
|
+
if (hashIdx < 0) return "";
|
|
1032
|
+
return raw.slice(hashIdx + 1).trim();
|
|
1033
|
+
}
|
|
1034
|
+
function sliceByHeading(target, headingPart, slugify) {
|
|
1035
|
+
const matched = target.headings.find(
|
|
1036
|
+
(h) => h.text === headingPart || h.slug === headingPart || h.slug === slugify(headingPart)
|
|
1037
|
+
);
|
|
1038
|
+
if (!matched) return void 0;
|
|
1039
|
+
const lines = target.content.split(/\r?\n/);
|
|
1040
|
+
const startLine = matched.line + 1;
|
|
1041
|
+
let endLine = lines.length;
|
|
1042
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
1043
|
+
const l = lines[i];
|
|
1044
|
+
const m = l.match(/^(#{1,6})\s+/);
|
|
1045
|
+
if (m && m[1].length <= matched.level) {
|
|
1046
|
+
endLine = i;
|
|
1047
|
+
break;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return lines.slice(startLine, endLine).join("\n").trim();
|
|
1051
|
+
}
|
|
1052
|
+
function getCache(env) {
|
|
1053
|
+
const e = env;
|
|
1054
|
+
if (!e._transclusionCache) e._transclusionCache = /* @__PURE__ */ new Map();
|
|
1055
|
+
return e._transclusionCache;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// src/modules/wikilinks/rule.ts
|
|
1059
|
+
function makeWikilinkRule(scope) {
|
|
1060
|
+
return function wikilinkRule(state, silent) {
|
|
1061
|
+
const src = state.src;
|
|
1062
|
+
const start = state.pos;
|
|
1063
|
+
const max = state.posMax;
|
|
1064
|
+
let isEmbed = false;
|
|
1065
|
+
let inner;
|
|
1066
|
+
if (src.charCodeAt(start) === 33 && src.charCodeAt(start + 1) === 91 && src.charCodeAt(start + 2) === 91) {
|
|
1067
|
+
if (scope === "wikilinks-only") return false;
|
|
1068
|
+
isEmbed = true;
|
|
1069
|
+
} else if (src.charCodeAt(start) === 91 && src.charCodeAt(start + 1) === 91) {
|
|
1070
|
+
if (scope === "embeds-only") return false;
|
|
1071
|
+
} else {
|
|
1072
|
+
return false;
|
|
1073
|
+
}
|
|
1074
|
+
const innerStart = start + (isEmbed ? 3 : 2);
|
|
1075
|
+
const closeIdx = src.indexOf("]]", innerStart);
|
|
1076
|
+
if (closeIdx < 0 || closeIdx >= max) return false;
|
|
1077
|
+
inner = src.slice(innerStart, closeIdx);
|
|
1078
|
+
if (inner.includes("\n")) return false;
|
|
1079
|
+
if (!inner.trim()) return false;
|
|
1080
|
+
if (silent) return true;
|
|
1081
|
+
const env = state.env;
|
|
1082
|
+
if (!env || !env.index || !env.options) {
|
|
1083
|
+
return false;
|
|
1084
|
+
}
|
|
1085
|
+
state.pos = closeIdx + 2;
|
|
1086
|
+
const parts = inner.split("|").map((p) => p.trim());
|
|
1087
|
+
const rawTarget = parts[0];
|
|
1088
|
+
const aliasParts = parts.slice(1);
|
|
1089
|
+
if (isEmbed) {
|
|
1090
|
+
const ext = extractExt(rawTarget);
|
|
1091
|
+
const isImage = ext && env.options.embeds.imageFileExt.includes(ext.toLowerCase());
|
|
1092
|
+
if (isImage) {
|
|
1093
|
+
return handleImageEmbed(state, rawTarget, aliasParts, env);
|
|
1094
|
+
}
|
|
1095
|
+
return handleTransclusion(state, rawTarget, aliasParts, env);
|
|
1096
|
+
}
|
|
1097
|
+
return emitPageLink(state, rawTarget, aliasParts, env);
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
function extractExt(target) {
|
|
1101
|
+
const cleaned = target.split("#")[0];
|
|
1102
|
+
const dot = cleaned.lastIndexOf(".");
|
|
1103
|
+
if (dot <= 0) return "";
|
|
1104
|
+
return cleaned.slice(dot + 1).toLowerCase();
|
|
1105
|
+
}
|
|
1106
|
+
function emitPageLink(state, rawTarget, aliasParts, env) {
|
|
1107
|
+
const { index, options } = env;
|
|
1108
|
+
const userAlias = aliasParts.length > 0 ? aliasParts.join("|").trim() : "";
|
|
1109
|
+
const processed = options.wikilinks.postProcessLinkTarget(rawTarget);
|
|
1110
|
+
const result = resolveWikilink(processed, index, options, "page");
|
|
1111
|
+
const label = userAlias ? options.wikilinks.postProcessLinkLabel(userAlias) : result.defaultLabel;
|
|
1112
|
+
registerBacklink(env, result.target?.absolutePath, false);
|
|
1113
|
+
if (result.isDead) {
|
|
1114
|
+
handleDeadLink(env, rawTarget);
|
|
1115
|
+
return renderDeadLink(state, result.url, label, rawTarget, env);
|
|
1116
|
+
}
|
|
1117
|
+
return renderPageLink(state, result, label, env);
|
|
1118
|
+
}
|
|
1119
|
+
function registerBacklink(env, targetPath, isEmbed) {
|
|
1120
|
+
if (!targetPath || !env.currentPath) return;
|
|
1121
|
+
const arr = env.index.backlinks.get(targetPath) ?? [];
|
|
1122
|
+
arr.push({
|
|
1123
|
+
fromPath: env.currentPath,
|
|
1124
|
+
fromUrl: env.index.files.get(env.currentPath)?.url ?? "",
|
|
1125
|
+
context: "",
|
|
1126
|
+
isEmbed,
|
|
1127
|
+
line: -1
|
|
1128
|
+
});
|
|
1129
|
+
env.index.backlinks.set(targetPath, arr);
|
|
1130
|
+
}
|
|
1131
|
+
function handleDeadLink(env, rawTarget) {
|
|
1132
|
+
const { options } = env;
|
|
1133
|
+
const msg = `vitepress-allyouneed: \u6B7B\u94FE [[${rawTarget}]]${env.currentPath ? ` (in ${env.currentPath})` : ""}`;
|
|
1134
|
+
if (options.deadLink === "silent") return;
|
|
1135
|
+
if (options.deadLink === "warn") {
|
|
1136
|
+
console.warn(msg);
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
env.index.warnings.push({
|
|
1140
|
+
kind: "unknown",
|
|
1141
|
+
message: msg,
|
|
1142
|
+
affected: env.currentPath ? [env.currentPath] : []
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// src/modules/wikilinks/index.ts
|
|
1147
|
+
function registerWikilinks(md, scope) {
|
|
1148
|
+
md.inline.ruler.before(
|
|
1149
|
+
"link",
|
|
1150
|
+
"allyouneed_wikilinks",
|
|
1151
|
+
makeWikilinkRule(scope)
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
// src/modules/embeds/block-rule.ts
|
|
1156
|
+
var LINE_RE = /^!\[\[([^\n\]]+)\]\]\s*$/;
|
|
1157
|
+
function registerEmbedBlockRule(md) {
|
|
1158
|
+
md.block.ruler.before(
|
|
1159
|
+
"paragraph",
|
|
1160
|
+
"allyouneed_embed_block",
|
|
1161
|
+
makeRule(md),
|
|
1162
|
+
{ alt: ["paragraph"] }
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
function makeRule(md) {
|
|
1166
|
+
return function embedBlockRule(state, startLine, _endLine, silent) {
|
|
1167
|
+
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
1168
|
+
const max = state.eMarks[startLine];
|
|
1169
|
+
const lineText = state.src.slice(start, max);
|
|
1170
|
+
const m = lineText.match(LINE_RE);
|
|
1171
|
+
if (!m) return false;
|
|
1172
|
+
if (silent) return true;
|
|
1173
|
+
const env = state.env;
|
|
1174
|
+
if (!env || !env.index || !env.options) return false;
|
|
1175
|
+
const inner = m[1];
|
|
1176
|
+
const parts = inner.split("|").map((p) => p.trim());
|
|
1177
|
+
const rawTarget = parts[0];
|
|
1178
|
+
const aliasParts = parts.slice(1);
|
|
1179
|
+
const ext = extractExt2(rawTarget);
|
|
1180
|
+
const isImage = !!ext && env.options.embeds.imageFileExt.includes(ext.toLowerCase());
|
|
1181
|
+
let html;
|
|
1182
|
+
if (isImage) {
|
|
1183
|
+
html = renderImageHtml(rawTarget, aliasParts, env);
|
|
1184
|
+
} else {
|
|
1185
|
+
html = renderTransclusionHtml(md, rawTarget, aliasParts, env);
|
|
1186
|
+
}
|
|
1187
|
+
const token = state.push("html_block", "", 0);
|
|
1188
|
+
token.content = html + "\n";
|
|
1189
|
+
token.map = [startLine, startLine + 1];
|
|
1190
|
+
state.line = startLine + 1;
|
|
1191
|
+
return true;
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
function extractExt2(target) {
|
|
1195
|
+
const cleaned = target.split("#")[0];
|
|
1196
|
+
const dot = cleaned.lastIndexOf(".");
|
|
1197
|
+
if (dot <= 0) return "";
|
|
1198
|
+
return cleaned.slice(dot + 1).toLowerCase();
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
// src/modules/embeds/index.ts
|
|
1202
|
+
function registerEmbedsOnly(md) {
|
|
1203
|
+
md.inline.ruler.before(
|
|
1204
|
+
"link",
|
|
1205
|
+
"allyouneed_embeds",
|
|
1206
|
+
makeWikilinkRule("embeds-only")
|
|
1207
|
+
);
|
|
1208
|
+
registerEmbedBlockRule(md);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// src/markdown-it.ts
|
|
1212
|
+
function allYouNeedMarkdownIt(md, options) {
|
|
1213
|
+
const resolved = options && isResolved(options) ? options : resolveOptions(options);
|
|
1214
|
+
const { wikilinks: wlOn, embeds: emOn } = resolved.modules;
|
|
1215
|
+
if (wlOn && emOn) {
|
|
1216
|
+
registerWikilinks(md, "both");
|
|
1217
|
+
registerEmbedBlockRule(md);
|
|
1218
|
+
} else if (wlOn) {
|
|
1219
|
+
registerWikilinks(md, "wikilinks-only");
|
|
1220
|
+
} else if (emOn) {
|
|
1221
|
+
registerEmbedsOnly(md);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function isResolved(o) {
|
|
1225
|
+
return typeof o.slugify === "function" && typeof o.srcDir === "string" && typeof o.modules === "object" && o.modules !== null;
|
|
1226
|
+
}
|
|
1227
|
+
var markdown_it_default = allYouNeedMarkdownIt;
|
|
1228
|
+
|
|
1229
|
+
// src/vite.ts
|
|
1230
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
1231
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
1232
|
+
|
|
1233
|
+
// src/core/asset-pipeline/dev-middleware.ts
|
|
1234
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
1235
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
1236
|
+
function createDevMiddleware(index, options) {
|
|
1237
|
+
return (req, res, next) => {
|
|
1238
|
+
if (!req.url) return next();
|
|
1239
|
+
const cleanPath = req.url.split("?")[0].split("#")[0];
|
|
1240
|
+
let inSiteUrl = cleanPath;
|
|
1241
|
+
if (options.base !== "/" && cleanPath.startsWith(options.base)) {
|
|
1242
|
+
inSiteUrl = "/" + cleanPath.slice(options.base.length);
|
|
1243
|
+
}
|
|
1244
|
+
let decoded;
|
|
1245
|
+
try {
|
|
1246
|
+
decoded = decodeURIComponent(inSiteUrl);
|
|
1247
|
+
} catch {
|
|
1248
|
+
return next();
|
|
1249
|
+
}
|
|
1250
|
+
if (!/\.[a-zA-Z0-9]+$/.test(decoded)) return next();
|
|
1251
|
+
const relCandidate = decoded.replace(/^\/+/, "");
|
|
1252
|
+
let asset = index.assetsByRelativePath.get(relCandidate);
|
|
1253
|
+
if (!asset) {
|
|
1254
|
+
const bn = basename(decoded);
|
|
1255
|
+
const map = options.caseSensitive ? index.assetsByBasename : index.assetsByBasenameLower;
|
|
1256
|
+
const key = options.caseSensitive ? bn : bn.toLowerCase();
|
|
1257
|
+
const candidates = map.get(key);
|
|
1258
|
+
if (candidates && candidates.length > 0) asset = candidates[0];
|
|
1259
|
+
}
|
|
1260
|
+
if (!asset) return next();
|
|
1261
|
+
let stat;
|
|
1262
|
+
try {
|
|
1263
|
+
stat = import_node_fs4.default.statSync(asset.absolutePath);
|
|
1264
|
+
} catch {
|
|
1265
|
+
return next();
|
|
1266
|
+
}
|
|
1267
|
+
res.statusCode = 200;
|
|
1268
|
+
res.setHeader("Content-Type", guessMime(asset.extension));
|
|
1269
|
+
res.setHeader("Content-Length", String(stat.size));
|
|
1270
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
1271
|
+
import_node_fs4.default.createReadStream(asset.absolutePath).on("error", () => next()).pipe(res);
|
|
1272
|
+
};
|
|
1273
|
+
}
|
|
1274
|
+
var MIME = {
|
|
1275
|
+
png: "image/png",
|
|
1276
|
+
jpg: "image/jpeg",
|
|
1277
|
+
jpeg: "image/jpeg",
|
|
1278
|
+
gif: "image/gif",
|
|
1279
|
+
webp: "image/webp",
|
|
1280
|
+
svg: "image/svg+xml",
|
|
1281
|
+
bmp: "image/bmp",
|
|
1282
|
+
avif: "image/avif",
|
|
1283
|
+
ico: "image/x-icon",
|
|
1284
|
+
mp4: "video/mp4",
|
|
1285
|
+
webm: "video/webm",
|
|
1286
|
+
mov: "video/quicktime",
|
|
1287
|
+
m4v: "video/x-m4v",
|
|
1288
|
+
mp3: "audio/mpeg",
|
|
1289
|
+
wav: "audio/wav",
|
|
1290
|
+
ogg: "audio/ogg",
|
|
1291
|
+
m4a: "audio/mp4",
|
|
1292
|
+
flac: "audio/flac",
|
|
1293
|
+
pdf: "application/pdf",
|
|
1294
|
+
canvas: "application/json",
|
|
1295
|
+
excalidraw: "application/json"
|
|
1296
|
+
};
|
|
1297
|
+
function guessMime(ext) {
|
|
1298
|
+
return MIME[ext.toLowerCase()] ?? "application/octet-stream";
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// src/vite.ts
|
|
1302
|
+
function stripQueryAndHash(id) {
|
|
1303
|
+
return id.split("?")[0].split("#")[0];
|
|
1304
|
+
}
|
|
1305
|
+
function viteAllYouNeed(userOptions = {}) {
|
|
1306
|
+
let resolved;
|
|
1307
|
+
let index;
|
|
1308
|
+
let viteConfig;
|
|
1309
|
+
const plugin = {
|
|
1310
|
+
name: "vitepress-allyouneed",
|
|
1311
|
+
/**
|
|
1312
|
+
* 在 Vite 配置定型前扩 server.fs.allow,让我们的 vault srcDir 可被 Vite
|
|
1313
|
+
* 服务(即便 srcDir 不在项目根下)。
|
|
1314
|
+
*/
|
|
1315
|
+
config(_userViteConfig, _envCtx) {
|
|
1316
|
+
const srcDirOpt = userOptions.srcDir;
|
|
1317
|
+
if (!srcDirOpt) return void 0;
|
|
1318
|
+
const abs = toPosix(import_node_path6.default.resolve(srcDirOpt));
|
|
1319
|
+
return {
|
|
1320
|
+
server: {
|
|
1321
|
+
fs: {
|
|
1322
|
+
allow: [abs]
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
},
|
|
1327
|
+
configResolved(cfg) {
|
|
1328
|
+
viteConfig = cfg;
|
|
1329
|
+
resolved = resolveOptions(userOptions, {
|
|
1330
|
+
srcDir: userOptions.srcDir ?? cfg.root,
|
|
1331
|
+
base: userOptions.base ?? cfg.base,
|
|
1332
|
+
cleanUrls: userOptions.cleanUrls
|
|
1333
|
+
});
|
|
1334
|
+
try {
|
|
1335
|
+
index = scanVault(resolved);
|
|
1336
|
+
if (index.warnings.length > 0) {
|
|
1337
|
+
const top = index.warnings.slice(0, 10);
|
|
1338
|
+
for (const w of top) {
|
|
1339
|
+
cfg.logger.warn(`[vitepress-allyouneed] ${w.message}`);
|
|
1340
|
+
}
|
|
1341
|
+
if (index.warnings.length > top.length) {
|
|
1342
|
+
cfg.logger.warn(
|
|
1343
|
+
`[vitepress-allyouneed] (...\u8FD8\u6709 ${index.warnings.length - top.length} \u6761\u544A\u8B66)`
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
} catch (err) {
|
|
1348
|
+
cfg.logger.error(
|
|
1349
|
+
`[vitepress-allyouneed] vault \u626B\u63CF\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`
|
|
1350
|
+
);
|
|
1351
|
+
index = void 0;
|
|
1352
|
+
}
|
|
1353
|
+
},
|
|
1354
|
+
configureServer(server) {
|
|
1355
|
+
if (!index) return;
|
|
1356
|
+
const mw = createDevMiddleware(index, resolved);
|
|
1357
|
+
return () => {
|
|
1358
|
+
server.middlewares.use(mw);
|
|
1359
|
+
};
|
|
1360
|
+
},
|
|
1361
|
+
handleHotUpdate(ctx) {
|
|
1362
|
+
if (!index) return;
|
|
1363
|
+
try {
|
|
1364
|
+
const stat = import_node_fs5.default.statSync(ctx.file);
|
|
1365
|
+
if (stat.isFile()) {
|
|
1366
|
+
updateFile(index, ctx.file, resolved);
|
|
1367
|
+
} else if (!import_node_fs5.default.existsSync(ctx.file)) {
|
|
1368
|
+
removeFile(index, ctx.file, resolved);
|
|
1369
|
+
}
|
|
1370
|
+
} catch {
|
|
1371
|
+
removeFile(index, ctx.file, resolved);
|
|
1372
|
+
}
|
|
1373
|
+
},
|
|
1374
|
+
/**
|
|
1375
|
+
* 拦截占位符 URL,**返回真实绝对文件路径**(POSIX 风格)。
|
|
1376
|
+
*
|
|
1377
|
+
* Vite 拿到文件路径会:
|
|
1378
|
+
* - dev:按文件系统服务,id 经 transform 后变成 `export default '<url>'`
|
|
1379
|
+
* - build:emit asset、Rollup 自动加 hash,导出最终 URL
|
|
1380
|
+
*/
|
|
1381
|
+
resolveId(id) {
|
|
1382
|
+
if (!index) return null;
|
|
1383
|
+
const stripped = stripQueryAndHash(id);
|
|
1384
|
+
const ph = ASSET_PLACEHOLDER_PREFIX;
|
|
1385
|
+
const phIdx = stripped.indexOf(ph);
|
|
1386
|
+
if (phIdx < 0) return null;
|
|
1387
|
+
const encoded = stripped.slice(phIdx + ph.length);
|
|
1388
|
+
let relPath;
|
|
1389
|
+
try {
|
|
1390
|
+
relPath = decodeURI(encoded);
|
|
1391
|
+
} catch {
|
|
1392
|
+
return null;
|
|
1393
|
+
}
|
|
1394
|
+
const asset = index.assetsByRelativePath.get(relPath);
|
|
1395
|
+
if (!asset) return null;
|
|
1396
|
+
const query = id.slice(stripped.length);
|
|
1397
|
+
return asset.absolutePath + query;
|
|
1398
|
+
},
|
|
1399
|
+
/**
|
|
1400
|
+
* 给 vitepress.ts wrapper 用。
|
|
1401
|
+
*/
|
|
1402
|
+
__getOptions() {
|
|
1403
|
+
return resolved;
|
|
1404
|
+
},
|
|
1405
|
+
__getIndex() {
|
|
1406
|
+
return index;
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
void viteConfig;
|
|
1410
|
+
return plugin;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
// src/vitepress.ts
|
|
1414
|
+
function defineConfigWithAllYouNeed(config, pluginOptions = {}) {
|
|
1415
|
+
const vpExclude = Array.isArray(config.srcExclude) ? config.srcExclude : [];
|
|
1416
|
+
const mergedOptions = {
|
|
1417
|
+
...pluginOptions,
|
|
1418
|
+
srcDir: pluginOptions.srcDir ?? config.srcDir,
|
|
1419
|
+
base: pluginOptions.base ?? config.base,
|
|
1420
|
+
cleanUrls: pluginOptions.cleanUrls ?? config.cleanUrls,
|
|
1421
|
+
scan: {
|
|
1422
|
+
...pluginOptions.scan,
|
|
1423
|
+
exclude: [
|
|
1424
|
+
...pluginOptions.scan?.exclude ?? [],
|
|
1425
|
+
...vpExclude
|
|
1426
|
+
]
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
const vitePlugin = viteAllYouNeed(mergedOptions);
|
|
1430
|
+
const existingVite = typeof config.vite === "object" && config.vite !== null ? config.vite : {};
|
|
1431
|
+
const existingPlugins = Array.isArray(existingVite.plugins) ? existingVite.plugins : [];
|
|
1432
|
+
const newVite = {
|
|
1433
|
+
...existingVite,
|
|
1434
|
+
plugins: [...existingPlugins, vitePlugin]
|
|
1435
|
+
};
|
|
1436
|
+
const existingMarkdown = config.markdown ?? {};
|
|
1437
|
+
const existingConfig = existingMarkdown.config;
|
|
1438
|
+
const newMarkdownConfig = (md) => {
|
|
1439
|
+
markdown_it_default(md, mergedOptions);
|
|
1440
|
+
md.core.ruler.before(
|
|
1441
|
+
"normalize",
|
|
1442
|
+
"allyouneed_env_inject",
|
|
1443
|
+
makeEnvInjector(vitePlugin)
|
|
1444
|
+
);
|
|
1445
|
+
if (typeof existingConfig === "function") {
|
|
1446
|
+
existingConfig(md);
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
return {
|
|
1450
|
+
...config,
|
|
1451
|
+
vite: newVite,
|
|
1452
|
+
markdown: {
|
|
1453
|
+
...existingMarkdown,
|
|
1454
|
+
config: newMarkdownConfig
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
function makeEnvInjector(vitePlugin) {
|
|
1459
|
+
return (state) => {
|
|
1460
|
+
const env = state.env;
|
|
1461
|
+
if (!env) return;
|
|
1462
|
+
if (env.index && env.options) return;
|
|
1463
|
+
const index = vitePlugin.__getIndex();
|
|
1464
|
+
const options = vitePlugin.__getOptions();
|
|
1465
|
+
if (!index || !options) return;
|
|
1466
|
+
env.index = index;
|
|
1467
|
+
env.options = options;
|
|
1468
|
+
if (!env.currentPath) {
|
|
1469
|
+
env.currentPath = typeof env.realPath === "string" ? env.realPath : typeof env.path === "string" ? env.path : void 0;
|
|
1470
|
+
}
|
|
1471
|
+
if (!env.referencedAssets) env.referencedAssets = /* @__PURE__ */ new Set();
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1475
|
+
0 && (module.exports = {
|
|
1476
|
+
allYouNeedMarkdownIt,
|
|
1477
|
+
createEmptyIndex,
|
|
1478
|
+
defaultSlugify,
|
|
1479
|
+
defineConfigWithAllYouNeed,
|
|
1480
|
+
extractCustomId,
|
|
1481
|
+
removeFile,
|
|
1482
|
+
resolveAsset,
|
|
1483
|
+
resolveOptions,
|
|
1484
|
+
resolveWikilink,
|
|
1485
|
+
scanVault,
|
|
1486
|
+
updateFile,
|
|
1487
|
+
viteAllYouNeed
|
|
1488
|
+
});
|
|
1489
|
+
//# sourceMappingURL=index.cjs.map
|