@sugarat/theme 0.1.39 → 0.1.40
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/README.md +2 -1
- package/node.d.ts +32 -8
- package/node.js +290 -205
- package/package.json +3 -2
- package/src/components/BlogArticleAnalyze.vue +1 -1
- package/src/components/BlogFriendLink.vue +2 -2
- package/src/components/BlogHomeOverview.vue +1 -1
- package/src/components/BlogHotArticle.vue +1 -1
- package/src/components/BlogItem.vue +1 -1
- package/src/components/BlogRecommendArticle.vue +2 -2
- package/src/components/BlogSearch.vue +1 -1
- package/src/components/UserWorks.vue +1 -1
- package/src/composables/config/index.ts +24 -2
- package/src/node.ts +35 -366
- package/src/styles/index.scss +1 -1
- package/src/utils/{index.ts → client/index.ts} +1 -1
- package/src/utils/node/genFeed.ts +53 -0
- package/src/utils/node/index.ts +118 -0
- package/src/utils/node/mdPlugins.ts +95 -0
- package/src/utils/node/theme.ts +138 -0
- package/src/utils/node/vitePlugins.ts +98 -0
package/README.md
CHANGED
|
@@ -50,4 +50,5 @@ pnpm serve
|
|
|
50
50
|
* [element-plus](https://github.com/element-plus/element-plus)
|
|
51
51
|
* [charles7c.github.io](https://github.com/Charles7c/charles7c.github.io)
|
|
52
52
|
* [vitepress-blog-zaun](https://github.com/clark-cui/vitepress-blog-zaun)
|
|
53
|
-
* [surmon](https://surmon.me/)
|
|
53
|
+
* [surmon](https://surmon.me/)
|
|
54
|
+
* [vuejs/blog](https://github.com/vuejs/blog/tree/main)
|
package/node.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DefaultTheme, UserConfig } from 'vitepress';
|
|
2
2
|
import { ElButton } from 'element-plus';
|
|
3
|
+
import { FeedOptions } from 'feed';
|
|
3
4
|
export { tabsMarkdownPlugin } from 'vitepress-plugin-tabs';
|
|
4
5
|
|
|
5
6
|
declare namespace BlogPopover {
|
|
@@ -108,7 +109,7 @@ declare namespace Theme {
|
|
|
108
109
|
empty?: string | boolean;
|
|
109
110
|
/**
|
|
110
111
|
* 设置推荐文章的展示风格
|
|
111
|
-
* @default '
|
|
112
|
+
* @default 'sidebar'
|
|
112
113
|
*/
|
|
113
114
|
style?: 'card' | 'sidebar';
|
|
114
115
|
}
|
|
@@ -246,7 +247,7 @@ declare namespace Theme {
|
|
|
246
247
|
works?: UserWorks;
|
|
247
248
|
/**
|
|
248
249
|
* https://mermaid.js.org/config/setup/modules/mermaidAPI.html#mermaidapi-configuration-defaults for options
|
|
249
|
-
* @default
|
|
250
|
+
* @default true
|
|
250
251
|
*/
|
|
251
252
|
mermaid?: any;
|
|
252
253
|
/**
|
|
@@ -254,7 +255,28 @@ declare namespace Theme {
|
|
|
254
255
|
* @default 8 => 'UTC+8'
|
|
255
256
|
* */
|
|
256
257
|
timeZone?: number;
|
|
258
|
+
/**
|
|
259
|
+
* 启用RSS配置
|
|
260
|
+
*/
|
|
261
|
+
RSS?: RSSOptions;
|
|
257
262
|
}
|
|
263
|
+
type RSSOptions = FeedOptions & {
|
|
264
|
+
baseUrl: string;
|
|
265
|
+
/**
|
|
266
|
+
* 线上访问的RSS地址
|
|
267
|
+
*/
|
|
268
|
+
url: string;
|
|
269
|
+
/**
|
|
270
|
+
* 输出的RSS文件名
|
|
271
|
+
* @default 'feed.rss'
|
|
272
|
+
*/
|
|
273
|
+
filename?: string;
|
|
274
|
+
/**
|
|
275
|
+
* 是否展示RSS的图标
|
|
276
|
+
* @default true
|
|
277
|
+
*/
|
|
278
|
+
showIcon?: boolean;
|
|
279
|
+
};
|
|
258
280
|
interface Config extends DefaultTheme.Config {
|
|
259
281
|
blog?: BlogConfig;
|
|
260
282
|
}
|
|
@@ -267,12 +289,14 @@ declare namespace Theme {
|
|
|
267
289
|
}
|
|
268
290
|
}
|
|
269
291
|
|
|
292
|
+
/**
|
|
293
|
+
* 获取主题的配置
|
|
294
|
+
* @param cfg 主题配置
|
|
295
|
+
*/
|
|
270
296
|
declare function getThemeConfig(cfg?: Partial<Theme.BlogConfig>): any;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
declare function getGitTimestamp(file: string): Promise<unknown>;
|
|
275
|
-
declare function assignMermaid(config: any): void;
|
|
297
|
+
/**
|
|
298
|
+
* defineConfig Helper
|
|
299
|
+
*/
|
|
276
300
|
declare function defineConfig(config: UserConfig<Theme.Config>): any;
|
|
277
301
|
|
|
278
|
-
export {
|
|
302
|
+
export { defineConfig, getThemeConfig };
|
package/node.js
CHANGED
|
@@ -26,23 +26,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
26
26
|
// src/node.ts
|
|
27
27
|
var node_exports = {};
|
|
28
28
|
__export(node_exports, {
|
|
29
|
-
assignMermaid: () => assignMermaid,
|
|
30
|
-
clearMatterContent: () => clearMatterContent,
|
|
31
29
|
defineConfig: () => defineConfig,
|
|
32
|
-
getDefaultTitle: () => getDefaultTitle,
|
|
33
|
-
getFileBirthTime: () => getFileBirthTime,
|
|
34
|
-
getGitTimestamp: () => getGitTimestamp,
|
|
35
30
|
getThemeConfig: () => getThemeConfig,
|
|
36
31
|
tabsMarkdownPlugin: () => tabsPlugin
|
|
37
32
|
});
|
|
38
33
|
module.exports = __toCommonJS(node_exports);
|
|
39
|
-
var import_fast_glob = __toESM(require("fast-glob"));
|
|
40
|
-
var import_gray_matter = __toESM(require("gray-matter"));
|
|
41
|
-
var import_fs = __toESM(require("fs"));
|
|
42
|
-
var import_child_process = require("child_process");
|
|
43
|
-
var import_path = __toESM(require("path"));
|
|
44
34
|
|
|
45
|
-
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-
|
|
35
|
+
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.4_vue@3.3.4/node_modules/vitepress-plugin-tabs/dist/index.js
|
|
46
36
|
var tabsMarker = "=tabs";
|
|
47
37
|
var tabsMarkerLen = tabsMarker.length;
|
|
48
38
|
var ruleBlockTabs = (state, startLine, endLine, silent) => {
|
|
@@ -206,7 +196,10 @@ var tabsPlugin = (md) => {
|
|
|
206
196
|
};
|
|
207
197
|
};
|
|
208
198
|
|
|
209
|
-
// src/utils/index.ts
|
|
199
|
+
// src/utils/node/index.ts
|
|
200
|
+
var import_child_process = require("child_process");
|
|
201
|
+
|
|
202
|
+
// src/utils/client/index.ts
|
|
210
203
|
function formatDate(d, fmt = "yyyy-MM-dd hh:mm:ss") {
|
|
211
204
|
if (!(d instanceof Date)) {
|
|
212
205
|
d = new Date(d);
|
|
@@ -236,159 +229,7 @@ function formatDate(d, fmt = "yyyy-MM-dd hh:mm:ss") {
|
|
|
236
229
|
return fmt;
|
|
237
230
|
}
|
|
238
231
|
|
|
239
|
-
// src/node.ts
|
|
240
|
-
var checkKeys = ["themeConfig"];
|
|
241
|
-
function getThemeConfig(cfg) {
|
|
242
|
-
const srcDir = cfg?.srcDir || process.argv.slice(2)?.[1] || ".";
|
|
243
|
-
const files = import_fast_glob.default.sync(`${srcDir}/**/*.md`, { ignore: ["node_modules"] });
|
|
244
|
-
const data = files.map((v) => {
|
|
245
|
-
let route = v.replace(".md", "");
|
|
246
|
-
if (route.startsWith("./")) {
|
|
247
|
-
route = route.replace(
|
|
248
|
-
new RegExp(
|
|
249
|
-
`^\\.\\/${import_path.default.join(srcDir, "/").replace(new RegExp(`\\${import_path.default.sep}`, "g"), "/")}`
|
|
250
|
-
),
|
|
251
|
-
""
|
|
252
|
-
);
|
|
253
|
-
} else {
|
|
254
|
-
route = route.replace(
|
|
255
|
-
new RegExp(
|
|
256
|
-
`^${import_path.default.join(srcDir, "/").replace(new RegExp(`\\${import_path.default.sep}`, "g"), "/")}`
|
|
257
|
-
),
|
|
258
|
-
""
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
const fileContent = import_fs.default.readFileSync(v, "utf-8");
|
|
262
|
-
const meta = {
|
|
263
|
-
...(0, import_gray_matter.default)(fileContent).data
|
|
264
|
-
};
|
|
265
|
-
if (!meta.title) {
|
|
266
|
-
meta.title = getDefaultTitle(fileContent);
|
|
267
|
-
}
|
|
268
|
-
if (!meta.date) {
|
|
269
|
-
meta.date = getFileBirthTime(v);
|
|
270
|
-
} else {
|
|
271
|
-
const timeZone = cfg?.timeZone ?? 8;
|
|
272
|
-
meta.date = formatDate(
|
|
273
|
-
new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
meta.categories = typeof meta.categories === "string" ? [meta.categories] : meta.categories;
|
|
277
|
-
meta.tags = typeof meta.tags === "string" ? [meta.tags] : meta.tags;
|
|
278
|
-
meta.tag = [meta.tag || []].flat().concat([
|
|
279
|
-
.../* @__PURE__ */ new Set([...meta.categories || [], ...meta.tags || []])
|
|
280
|
-
]);
|
|
281
|
-
const wordCount = 100;
|
|
282
|
-
meta.description = meta.description || getTextSummary(fileContent, wordCount);
|
|
283
|
-
meta.cover = meta.cover ?? (fileContent.match(/[!]\[.*?\]\((https:\/\/.+)\)/)?.[1] || "");
|
|
284
|
-
if (meta.publish === false) {
|
|
285
|
-
meta.hidden = true;
|
|
286
|
-
meta.recommend = false;
|
|
287
|
-
}
|
|
288
|
-
return {
|
|
289
|
-
route: `/${route}`,
|
|
290
|
-
meta
|
|
291
|
-
};
|
|
292
|
-
}).filter((v) => v.meta.layout !== "home");
|
|
293
|
-
const extraConfig = {};
|
|
294
|
-
if (cfg?.search === "pagefind" || cfg?.search instanceof Object && cfg.search.mode === "pagefind") {
|
|
295
|
-
checkKeys.push("vite");
|
|
296
|
-
let resolveConfig;
|
|
297
|
-
extraConfig.vite = {
|
|
298
|
-
plugins: [
|
|
299
|
-
{
|
|
300
|
-
name: "@sugarar/theme-plugin-pagefind",
|
|
301
|
-
enforce: "pre",
|
|
302
|
-
configResolved(config) {
|
|
303
|
-
if (resolveConfig) {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
resolveConfig = config;
|
|
307
|
-
const vitepressConfig = config.vitepress;
|
|
308
|
-
if (!vitepressConfig) {
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
const selfBuildEnd = vitepressConfig.buildEnd;
|
|
312
|
-
vitepressConfig.buildEnd = (siteConfig) => {
|
|
313
|
-
selfBuildEnd?.(siteConfig);
|
|
314
|
-
const ignore = [
|
|
315
|
-
"div.aside",
|
|
316
|
-
"a.header-anchor"
|
|
317
|
-
];
|
|
318
|
-
const { log } = console;
|
|
319
|
-
log();
|
|
320
|
-
log("=== pagefind: https://pagefind.app/ ===");
|
|
321
|
-
let command = `npx pagefind --source ${import_path.default.join(
|
|
322
|
-
process.argv.slice(2)?.[1] || ".",
|
|
323
|
-
".vitepress/dist"
|
|
324
|
-
)}`;
|
|
325
|
-
if (ignore.length) {
|
|
326
|
-
command += ` --exclude-selectors "${ignore.join(", ")}"`;
|
|
327
|
-
}
|
|
328
|
-
log(command);
|
|
329
|
-
log();
|
|
330
|
-
(0, import_child_process.execSync)(command, {
|
|
331
|
-
stdio: "inherit"
|
|
332
|
-
});
|
|
333
|
-
};
|
|
334
|
-
},
|
|
335
|
-
transform(code, id) {
|
|
336
|
-
if (id.endsWith("theme-default/Layout.vue")) {
|
|
337
|
-
return code.replace(
|
|
338
|
-
"<VPContent>",
|
|
339
|
-
"<VPContent data-pagefind-body>"
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
return code;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
]
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
const markdownPlugin = [];
|
|
349
|
-
if (cfg?.tabs) {
|
|
350
|
-
markdownPlugin.push(tabsPlugin);
|
|
351
|
-
}
|
|
352
|
-
if (cfg) {
|
|
353
|
-
cfg.mermaid = cfg?.mermaid ?? true;
|
|
354
|
-
}
|
|
355
|
-
if (cfg?.mermaid !== false) {
|
|
356
|
-
const { MermaidMarkdown } = require("vitepress-plugin-mermaid");
|
|
357
|
-
markdownPlugin.push(MermaidMarkdown);
|
|
358
|
-
}
|
|
359
|
-
if (markdownPlugin.length) {
|
|
360
|
-
extraConfig.markdown = {
|
|
361
|
-
config(...rest) {
|
|
362
|
-
markdownPlugin.forEach((plugin) => {
|
|
363
|
-
plugin?.(...rest);
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
return {
|
|
369
|
-
themeConfig: {
|
|
370
|
-
blog: {
|
|
371
|
-
pagesData: data,
|
|
372
|
-
...cfg
|
|
373
|
-
},
|
|
374
|
-
...cfg?.blog !== false && cfg?.recommend !== false ? {
|
|
375
|
-
sidebar: [
|
|
376
|
-
{
|
|
377
|
-
text: "",
|
|
378
|
-
items: []
|
|
379
|
-
}
|
|
380
|
-
]
|
|
381
|
-
} : void 0
|
|
382
|
-
},
|
|
383
|
-
...extraConfig
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
function getDefaultTitle(content) {
|
|
387
|
-
const title = clearMatterContent(content).split("\n")?.find((str) => {
|
|
388
|
-
return str.startsWith("# ");
|
|
389
|
-
})?.slice(2).replace(/^\s+|\s+$/g, "") || "";
|
|
390
|
-
return title;
|
|
391
|
-
}
|
|
232
|
+
// src/utils/node/index.ts
|
|
392
233
|
function clearMatterContent(content) {
|
|
393
234
|
let first___;
|
|
394
235
|
let second___;
|
|
@@ -408,6 +249,12 @@ function clearMatterContent(content) {
|
|
|
408
249
|
}, []);
|
|
409
250
|
return lines.slice(second___ || 0).join("\n");
|
|
410
251
|
}
|
|
252
|
+
function getDefaultTitle(content) {
|
|
253
|
+
const title = clearMatterContent(content).split("\n")?.find((str) => {
|
|
254
|
+
return str.startsWith("# ");
|
|
255
|
+
})?.slice(2).replace(/^\s+|\s+$/g, "") || "";
|
|
256
|
+
return title;
|
|
257
|
+
}
|
|
411
258
|
function getFileBirthTime(url) {
|
|
412
259
|
let date = new Date();
|
|
413
260
|
try {
|
|
@@ -420,22 +267,49 @@ function getFileBirthTime(url) {
|
|
|
420
267
|
}
|
|
421
268
|
return formatDate(date);
|
|
422
269
|
}
|
|
423
|
-
function getGitTimestamp(file) {
|
|
424
|
-
return new Promise((resolve, reject) => {
|
|
425
|
-
const child = (0, import_child_process.spawn)("git", ["log", "-1", '--pretty="%ci"', file]);
|
|
426
|
-
let output = "";
|
|
427
|
-
child.stdout.on("data", (d) => {
|
|
428
|
-
output += String(d);
|
|
429
|
-
});
|
|
430
|
-
child.on("close", () => {
|
|
431
|
-
resolve(+new Date(output));
|
|
432
|
-
});
|
|
433
|
-
child.on("error", reject);
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
270
|
function getTextSummary(text, count = 100) {
|
|
437
271
|
return clearMatterContent(text).match(/^# ([\s\S]+)/m)?.[1]?.replace(/#/g, "")?.replace(/!\[.*?\]\(.*?\)/g, "")?.replace(/\[(.*?)\]\(.*?\)/g, "$1")?.replace(/\*\*(.*?)\*\*/g, "$1")?.split("\n")?.filter((v) => !!v)?.slice(1)?.join("\n")?.replace(/>(.*)/, "")?.slice(0, count);
|
|
438
272
|
}
|
|
273
|
+
function aliasObjectToArray(obj) {
|
|
274
|
+
return Object.entries(obj).map(([find, replacement]) => ({
|
|
275
|
+
find,
|
|
276
|
+
replacement
|
|
277
|
+
}));
|
|
278
|
+
}
|
|
279
|
+
var EXTERNAL_URL_RE = /^[a-z]+:/i;
|
|
280
|
+
function joinPath(base, path4) {
|
|
281
|
+
return `${base}${path4}`.replace(/\/+/g, "/");
|
|
282
|
+
}
|
|
283
|
+
function withBase(base, path4) {
|
|
284
|
+
return EXTERNAL_URL_RE.test(path4) || path4.startsWith(".") ? path4 : joinPath(base, path4);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// src/utils/node/mdPlugins.ts
|
|
288
|
+
function getMarkdownPlugins(cfg) {
|
|
289
|
+
const markdownPlugin = [];
|
|
290
|
+
if (cfg?.tabs) {
|
|
291
|
+
markdownPlugin.push(tabsPlugin);
|
|
292
|
+
}
|
|
293
|
+
if (cfg) {
|
|
294
|
+
cfg.mermaid = cfg?.mermaid ?? true;
|
|
295
|
+
if (cfg?.mermaid !== false) {
|
|
296
|
+
const { MermaidMarkdown } = require("vitepress-plugin-mermaid");
|
|
297
|
+
markdownPlugin.push(MermaidMarkdown);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return markdownPlugin;
|
|
301
|
+
}
|
|
302
|
+
function registerMdPlugins(vpCfg, plugins) {
|
|
303
|
+
if (plugins.length) {
|
|
304
|
+
vpCfg.markdown = {
|
|
305
|
+
config(...rest) {
|
|
306
|
+
plugins.forEach((plugin) => {
|
|
307
|
+
plugin?.(...rest);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
439
313
|
function assignMermaid(config) {
|
|
440
314
|
if (!config?.mermaid)
|
|
441
315
|
return;
|
|
@@ -458,50 +332,261 @@ function assignMermaid(config) {
|
|
|
458
332
|
{ find: /^dayjs\/(.*).js/, replacement: "dayjs/esm/$1" }
|
|
459
333
|
];
|
|
460
334
|
}
|
|
461
|
-
function
|
|
462
|
-
return Object.entries(obj).map(([find, replacement]) => ({
|
|
463
|
-
find,
|
|
464
|
-
replacement
|
|
465
|
-
}));
|
|
466
|
-
}
|
|
467
|
-
function defineConfig(config) {
|
|
468
|
-
if (config.themeConfig?.themeConfig) {
|
|
469
|
-
config.extends = checkKeys.reduce((pre, key) => {
|
|
470
|
-
pre[key] = config.themeConfig[key];
|
|
471
|
-
delete config.themeConfig[key];
|
|
472
|
-
return pre;
|
|
473
|
-
}, {});
|
|
474
|
-
setTimeout(() => {
|
|
475
|
-
console.warn("==\u2193 \u4E3B\u9898\u914D\u7F6E\u65B9\u5F0F\u8FC7\u671F\uFF0C\u8BF7\u5C3D\u5FEB\u53C2\u7167\u6587\u6863\u66F4\u65B0 \u2193==");
|
|
476
|
-
console.warn("https://theme.sugarat.top/config/global.html");
|
|
477
|
-
}, 1200);
|
|
478
|
-
}
|
|
335
|
+
function wrapperCfgWithMermaid(config) {
|
|
479
336
|
const extendThemeConfig = config.extends?.themeConfig?.blog || {};
|
|
480
337
|
const resultConfig = extendThemeConfig.mermaid === false ? config : {
|
|
481
338
|
...config,
|
|
482
339
|
mermaid: extendThemeConfig.mermaid === true ? {} : extendThemeConfig.mermaid
|
|
483
340
|
};
|
|
484
341
|
assignMermaid(resultConfig);
|
|
485
|
-
|
|
486
|
-
|
|
342
|
+
return resultConfig;
|
|
343
|
+
}
|
|
344
|
+
function supportRunExtendsPlugin(config) {
|
|
345
|
+
if (!config.markdown)
|
|
346
|
+
config.markdown = {};
|
|
487
347
|
if (config.extends?.markdown?.config) {
|
|
488
348
|
const markdownExtendsConfigOriginal = config.extends?.markdown?.config;
|
|
489
|
-
const selfMarkdownConfig =
|
|
490
|
-
|
|
349
|
+
const selfMarkdownConfig = config.markdown?.config;
|
|
350
|
+
config.markdown.config = (...rest) => {
|
|
491
351
|
selfMarkdownConfig?.(...rest);
|
|
492
352
|
markdownExtendsConfigOriginal?.(...rest);
|
|
493
353
|
};
|
|
494
354
|
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/utils/node/theme.ts
|
|
358
|
+
var import_fast_glob = __toESM(require("fast-glob"));
|
|
359
|
+
var import_gray_matter = __toESM(require("gray-matter"));
|
|
360
|
+
var import_fs = __toESM(require("fs"));
|
|
361
|
+
var import_path = __toESM(require("path"));
|
|
362
|
+
function patchDefaultThemeSideBar(cfg) {
|
|
363
|
+
return cfg?.blog !== false && cfg?.recommend !== false ? {
|
|
364
|
+
sidebar: [
|
|
365
|
+
{
|
|
366
|
+
text: "",
|
|
367
|
+
items: []
|
|
368
|
+
}
|
|
369
|
+
]
|
|
370
|
+
} : void 0;
|
|
371
|
+
}
|
|
372
|
+
function getArticles(cfg) {
|
|
373
|
+
const srcDir = cfg?.srcDir || process.argv.slice(2)?.[1] || ".";
|
|
374
|
+
const files = import_fast_glob.default.sync(`${srcDir}/**/*.md`, { ignore: ["node_modules"] });
|
|
375
|
+
const data = files.map((v) => {
|
|
376
|
+
let route = v.replace(".md", "");
|
|
377
|
+
if (route.startsWith("./")) {
|
|
378
|
+
route = route.replace(
|
|
379
|
+
new RegExp(
|
|
380
|
+
`^\\.\\/${import_path.default.join(srcDir, "/").replace(new RegExp(`\\${import_path.default.sep}`, "g"), "/")}`
|
|
381
|
+
),
|
|
382
|
+
""
|
|
383
|
+
);
|
|
384
|
+
} else {
|
|
385
|
+
route = route.replace(
|
|
386
|
+
new RegExp(
|
|
387
|
+
`^${import_path.default.join(srcDir, "/").replace(new RegExp(`\\${import_path.default.sep}`, "g"), "/")}`
|
|
388
|
+
),
|
|
389
|
+
""
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
const fileContent = import_fs.default.readFileSync(v, "utf-8");
|
|
393
|
+
const meta = {
|
|
394
|
+
...(0, import_gray_matter.default)(fileContent).data
|
|
395
|
+
};
|
|
396
|
+
if (!meta.title) {
|
|
397
|
+
meta.title = getDefaultTitle(fileContent);
|
|
398
|
+
}
|
|
399
|
+
if (!meta.date) {
|
|
400
|
+
meta.date = getFileBirthTime(v);
|
|
401
|
+
} else {
|
|
402
|
+
const timeZone = cfg?.timeZone ?? 8;
|
|
403
|
+
meta.date = formatDate(
|
|
404
|
+
new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
meta.categories = typeof meta.categories === "string" ? [meta.categories] : meta.categories;
|
|
408
|
+
meta.tags = typeof meta.tags === "string" ? [meta.tags] : meta.tags;
|
|
409
|
+
meta.tag = [meta.tag || []].flat().concat([
|
|
410
|
+
.../* @__PURE__ */ new Set([...meta.categories || [], ...meta.tags || []])
|
|
411
|
+
]);
|
|
412
|
+
const wordCount = 100;
|
|
413
|
+
meta.description = meta.description || getTextSummary(fileContent, wordCount);
|
|
414
|
+
meta.cover = meta.cover ?? (fileContent.match(/[!]\[.*?\]\((https:\/\/.+)\)/)?.[1] || "");
|
|
415
|
+
if (meta.publish === false) {
|
|
416
|
+
meta.hidden = true;
|
|
417
|
+
meta.recommend = false;
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
route: `/${route}`,
|
|
421
|
+
meta
|
|
422
|
+
};
|
|
423
|
+
}).filter((v) => v.meta.layout !== "home");
|
|
424
|
+
return data;
|
|
425
|
+
}
|
|
426
|
+
function patchVPThemeConfig(cfg, vpThemeConfig = {}) {
|
|
427
|
+
const RSS = cfg?.RSS;
|
|
428
|
+
if (RSS && RSS.showIcon !== false) {
|
|
429
|
+
vpThemeConfig.socialLinks = [
|
|
430
|
+
{
|
|
431
|
+
icon: {
|
|
432
|
+
svg: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><path d="M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48s48 21.49 48 48s-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634c-5.214-80.05-69.243-143.92-149.123-149.123c-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425c110.546 5.974 198.997 94.536 204.964 204.964c.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038c-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432c167.83 6.025 302.21 141.191 308.205 308.205c.232 6.449-4.978 11.787-11.432 11.787z" fill="currentColor"></path></svg>'
|
|
433
|
+
},
|
|
434
|
+
link: RSS.url
|
|
435
|
+
}
|
|
436
|
+
];
|
|
437
|
+
}
|
|
438
|
+
vpThemeConfig.sidebar = patchDefaultThemeSideBar(cfg)?.sidebar;
|
|
439
|
+
return vpThemeConfig;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// src/utils/node/vitePlugins.ts
|
|
443
|
+
var import_path3 = __toESM(require("path"));
|
|
444
|
+
var import_child_process2 = require("child_process");
|
|
445
|
+
|
|
446
|
+
// src/utils/node/genFeed.ts
|
|
447
|
+
var import_path2 = __toESM(require("path"));
|
|
448
|
+
var import_fs2 = require("fs");
|
|
449
|
+
var import_feed = require("feed");
|
|
450
|
+
function genFeed(config) {
|
|
451
|
+
const blogCfg = config.userConfig.themeConfig.blog;
|
|
452
|
+
const posts = blogCfg.pagesData;
|
|
453
|
+
const { RSS, authorList = [] } = blogCfg;
|
|
454
|
+
if (!RSS)
|
|
455
|
+
return;
|
|
456
|
+
console.log();
|
|
457
|
+
console.log("=== feed: https://github.com/jpmonette/feed ===");
|
|
458
|
+
const { base } = config.userConfig;
|
|
459
|
+
const { baseUrl, filename } = RSS;
|
|
460
|
+
const feed = new import_feed.Feed(RSS);
|
|
461
|
+
posts.sort(
|
|
462
|
+
(a, b) => +new Date(b.meta.date) - +new Date(a.meta.date)
|
|
463
|
+
);
|
|
464
|
+
for (const { route, meta } of posts) {
|
|
465
|
+
const { title, description, date, hidden } = meta;
|
|
466
|
+
if (hidden)
|
|
467
|
+
continue;
|
|
468
|
+
const author = meta.author ?? blogCfg.author;
|
|
469
|
+
const link = `${baseUrl}${withBase(base || "", route)}.html`;
|
|
470
|
+
const authorLink = authorList.find((v) => v.nickname === author)?.url;
|
|
471
|
+
feed.addItem({
|
|
472
|
+
title,
|
|
473
|
+
id: link,
|
|
474
|
+
link,
|
|
475
|
+
description,
|
|
476
|
+
author: [
|
|
477
|
+
{
|
|
478
|
+
name: author,
|
|
479
|
+
link: authorLink
|
|
480
|
+
}
|
|
481
|
+
],
|
|
482
|
+
date: new Date(date)
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
const RSSFile = import_path2.default.join(config.outDir, filename || "feed.rss");
|
|
486
|
+
(0, import_fs2.writeFileSync)(RSSFile, feed.rss2());
|
|
487
|
+
console.log("\u{1F389} RSS generated", filename || "feed.rss");
|
|
488
|
+
console.log();
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// src/utils/node/vitePlugins.ts
|
|
492
|
+
function getVitePlugins(cfg) {
|
|
493
|
+
const plugins = [];
|
|
494
|
+
const buildEndFn = [];
|
|
495
|
+
plugins.push(inlineBuildEndPlugin(buildEndFn));
|
|
496
|
+
if (cfg?.search === "pagefind" || cfg?.search instanceof Object && cfg.search.mode === "pagefind") {
|
|
497
|
+
plugins.push(inlinePagefindPlugin(buildEndFn));
|
|
498
|
+
}
|
|
499
|
+
buildEndFn.push(genFeed);
|
|
500
|
+
return plugins;
|
|
501
|
+
}
|
|
502
|
+
function registerVitePlugins(vpCfg, plugins) {
|
|
503
|
+
vpCfg.vite = {
|
|
504
|
+
plugins
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
function inlinePagefindPlugin(buildEndFn) {
|
|
508
|
+
buildEndFn.push(() => {
|
|
509
|
+
const ignore = [
|
|
510
|
+
"div.aside",
|
|
511
|
+
"a.header-anchor"
|
|
512
|
+
];
|
|
513
|
+
const { log } = console;
|
|
514
|
+
log();
|
|
515
|
+
log("=== pagefind: https://pagefind.app/ ===");
|
|
516
|
+
let command = `npx pagefind --source ${import_path3.default.join(
|
|
517
|
+
process.argv.slice(2)?.[1] || ".",
|
|
518
|
+
".vitepress/dist"
|
|
519
|
+
)}`;
|
|
520
|
+
if (ignore.length) {
|
|
521
|
+
command += ` --exclude-selectors "${ignore.join(", ")}"`;
|
|
522
|
+
}
|
|
523
|
+
log(command);
|
|
524
|
+
log();
|
|
525
|
+
(0, import_child_process2.execSync)(command, {
|
|
526
|
+
stdio: "inherit"
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
return {
|
|
530
|
+
name: "@sugarar/theme-plugin-pagefind",
|
|
531
|
+
enforce: "pre",
|
|
532
|
+
transform(code, id) {
|
|
533
|
+
if (id.endsWith("theme-default/Layout.vue")) {
|
|
534
|
+
return code.replace("<VPContent>", "<VPContent data-pagefind-body>");
|
|
535
|
+
}
|
|
536
|
+
return code;
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
function inlineBuildEndPlugin(buildEndFn) {
|
|
541
|
+
let rewrite = false;
|
|
542
|
+
return {
|
|
543
|
+
name: "@sugarar/theme-plugin-build-end",
|
|
544
|
+
enforce: "pre",
|
|
545
|
+
configResolved(config) {
|
|
546
|
+
if (rewrite) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const vitepressConfig = config.vitepress;
|
|
550
|
+
if (!vitepressConfig) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
rewrite = true;
|
|
554
|
+
const selfBuildEnd = vitepressConfig.buildEnd;
|
|
555
|
+
vitepressConfig.buildEnd = (siteCfg) => {
|
|
556
|
+
selfBuildEnd?.(siteCfg);
|
|
557
|
+
buildEndFn.filter((fn) => typeof fn === "function").forEach((fn) => fn(siteCfg));
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// src/node.ts
|
|
564
|
+
function getThemeConfig(cfg) {
|
|
565
|
+
const pagesData = getArticles(cfg);
|
|
566
|
+
const extraVPConfig = {};
|
|
567
|
+
const vitePlugins = getVitePlugins(cfg);
|
|
568
|
+
registerVitePlugins(extraVPConfig, vitePlugins);
|
|
569
|
+
const markdownPlugin = getMarkdownPlugins(cfg);
|
|
570
|
+
registerMdPlugins(extraVPConfig, markdownPlugin);
|
|
571
|
+
return {
|
|
572
|
+
themeConfig: {
|
|
573
|
+
blog: {
|
|
574
|
+
pagesData,
|
|
575
|
+
...cfg
|
|
576
|
+
},
|
|
577
|
+
...patchVPThemeConfig(cfg)
|
|
578
|
+
},
|
|
579
|
+
...extraVPConfig
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
function defineConfig(config) {
|
|
583
|
+
const resultConfig = wrapperCfgWithMermaid(config);
|
|
584
|
+
supportRunExtendsPlugin(resultConfig);
|
|
495
585
|
return resultConfig;
|
|
496
586
|
}
|
|
497
587
|
// Annotate the CommonJS export names for ESM import in node:
|
|
498
588
|
0 && (module.exports = {
|
|
499
|
-
assignMermaid,
|
|
500
|
-
clearMatterContent,
|
|
501
589
|
defineConfig,
|
|
502
|
-
getDefaultTitle,
|
|
503
|
-
getFileBirthTime,
|
|
504
|
-
getGitTimestamp,
|
|
505
590
|
getThemeConfig,
|
|
506
591
|
tabsMarkdownPlugin
|
|
507
592
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@vue/shared": "^3.2.45",
|
|
39
39
|
"@vueuse/core": "^9.6.0",
|
|
40
40
|
"fast-glob": "^3.2.12",
|
|
41
|
+
"feed": "^4.2.2",
|
|
41
42
|
"gray-matter": "^4.0.3",
|
|
42
43
|
"highlight.js": "^11.7.0",
|
|
43
44
|
"mermaid": "^10.2.4",
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"sass": "^1.56.1",
|
|
51
52
|
"tsup": " ^6.5.0",
|
|
52
53
|
"typescript": "^4.8.2",
|
|
53
|
-
"vitepress": "1.0.0-
|
|
54
|
+
"vitepress": "1.0.0-rc.4",
|
|
54
55
|
"vitepress-plugin-tabs": "^0.2.0",
|
|
55
56
|
"vue": "^3.3.4"
|
|
56
57
|
},
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
CollectionTag
|
|
57
57
|
} from '@element-plus/icons-vue'
|
|
58
58
|
import { useBlogConfig, useCurrentArticle } from '../composables/config/blog'
|
|
59
|
-
import countWord, { formatShowDate } from '../utils/
|
|
59
|
+
import countWord, { formatShowDate } from '../utils/client'
|
|
60
60
|
import { Theme } from '../composables/config'
|
|
61
61
|
import BlogDocCover from './BlogDocCover.vue'
|
|
62
62
|
|
|
@@ -24,7 +24,7 @@ import { ElAvatar } from 'element-plus'
|
|
|
24
24
|
import { useDark } from '@vueuse/core'
|
|
25
25
|
import { computed } from 'vue'
|
|
26
26
|
import { useBlogConfig } from '../composables/config/blog'
|
|
27
|
-
import { getImageUrl } from '../utils'
|
|
27
|
+
import { getImageUrl } from '../utils/client'
|
|
28
28
|
|
|
29
29
|
const isDark = useDark({
|
|
30
30
|
storageKey: 'vitepress-theme-appearance'
|
|
@@ -114,4 +114,4 @@ const friendList = computed(() => {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
</style>
|
|
117
|
+
</style>
|