@sugarat/theme 0.2.1 → 0.2.2

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/node.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { DefaultTheme, UserConfig } from 'vitepress';
2
2
  import { ElButton } from 'element-plus';
3
- import { FeedOptions } from 'feed';
3
+ import { RSSOptions } from 'vitepress-plugin-rss';
4
4
  export { tabsMarkdownPlugin } from 'vitepress-plugin-tabs';
5
5
 
6
+ type RSSPluginOptions = RSSOptions;
6
7
  declare namespace BlogPopover {
7
8
  interface Title {
8
9
  type: 'title';
@@ -273,40 +274,7 @@ declare namespace Theme {
273
274
  */
274
275
  footer?: Footer;
275
276
  }
276
- type RSSOptions = Omit<FeedOptions, 'id'> & {
277
- id?: string;
278
- /**
279
- * 你的站点地址
280
- * @example 'https://sugarat.top'
281
- */
282
- baseUrl: string;
283
- /**
284
- * 线上访问的RSS地址
285
- * @default
286
- * @example https://sugarat.top/feed.rss
287
- * ```ts
288
- * `${baseUrl + VPConfig.site.base + (filename || 'feed.rss'}`
289
- * ```
290
- */
291
- url?: string;
292
- /**
293
- * 输出的RSS文件名
294
- * @default 'feed.rss'
295
- */
296
- filename?: string;
297
- /**
298
- * RSS的图标展示
299
- * @default true
300
- */
301
- icon?: boolean;
302
- /**
303
- * 限制输出文件包含的文章数量
304
- * @default 0
305
- * @description (0 不限制;> 1 会按照日期排序对输出内容进行调整)
306
- */
307
- limit?: number;
308
- ariaLabel?: string;
309
- };
277
+ type RSSOptions = RSSPluginOptions;
310
278
  interface Footer {
311
279
  /**
312
280
  * 自定义补充信息
package/node.js CHANGED
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
18
18
  return to;
19
19
  };
20
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.
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
@@ -206,12 +210,19 @@ function formatDate(d, fmt = "yyyy-MM-dd hh:mm:ss") {
206
210
  }
207
211
  const o = {
208
212
  "M+": d.getMonth() + 1,
213
+ // 月份
209
214
  "d+": d.getDate(),
215
+ // 日
210
216
  "h+": d.getHours(),
217
+ // 小时
211
218
  "m+": d.getMinutes(),
219
+ // 分
212
220
  "s+": d.getSeconds(),
221
+ // 秒
213
222
  "q+": Math.floor((d.getMonth() + 3) / 3),
223
+ // 季度
214
224
  "S": d.getMilliseconds()
225
+ // 毫秒
215
226
  };
216
227
  if (/(y+)/.test(fmt)) {
217
228
  fmt = fmt.replace(
@@ -256,7 +267,7 @@ function getDefaultTitle(content) {
256
267
  return title;
257
268
  }
258
269
  function getFileBirthTime(url) {
259
- let date = new Date();
270
+ let date = /* @__PURE__ */ new Date();
260
271
  try {
261
272
  const infoStr = (0, import_node_child_process.spawnSync)("git", ["log", "-1", '--pretty="%ci"', url]).stdout?.toString().replace(/["']/g, "").trim();
262
273
  if (infoStr) {
@@ -276,18 +287,11 @@ function aliasObjectToArray(obj) {
276
287
  replacement
277
288
  }));
278
289
  }
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
290
 
287
291
  // src/utils/node/mdPlugins.ts
288
292
  function getMarkdownPlugins(cfg) {
289
293
  const markdownPlugin = [];
290
- if (cfg?.tabs) {
294
+ if (cfg?.tabs !== false) {
291
295
  markdownPlugin.push(tabsPlugin);
292
296
  }
293
297
  if (cfg) {
@@ -310,15 +314,7 @@ function registerMdPlugins(vpCfg, plugins) {
310
314
  };
311
315
  }
312
316
  }
313
- function assignMermaid(config) {
314
- if (!config?.mermaid)
315
- return;
316
- if (!config.vite)
317
- config.vite = {};
318
- if (!config.vite.plugins)
319
- config.vite.plugins = [];
320
- const { MermaidPlugin } = require("vitepress-plugin-mermaid");
321
- config.vite.plugins.push(MermaidPlugin(config.mermaid));
317
+ function patchMermaidPluginCfg(config) {
322
318
  if (!config.vite.resolve)
323
319
  config.vite.resolve = {};
324
320
  if (!config.vite.resolve.alias)
@@ -332,31 +328,12 @@ function assignMermaid(config) {
332
328
  { find: /^dayjs\/(.*).js/, replacement: "dayjs/esm/$1" }
333
329
  ];
334
330
  }
335
- function wrapperCfgWithMermaid(config) {
336
- const extendThemeConfig = config.extends?.themeConfig?.blog || {};
337
- const resultConfig = extendThemeConfig.mermaid === false ? config : {
338
- ...config,
339
- mermaid: extendThemeConfig.mermaid === true ? {} : extendThemeConfig.mermaid
340
- };
341
- assignMermaid(resultConfig);
342
- return resultConfig;
343
- }
344
- function supportRunExtendsPlugin(config) {
345
- if (!config.markdown)
346
- config.markdown = {};
347
- if (config.extends?.markdown?.config) {
348
- const markdownExtendsConfigOriginal = config.extends?.markdown?.config;
349
- const selfMarkdownConfig = config.markdown?.config;
350
- config.markdown.config = (...rest) => {
351
- selfMarkdownConfig?.(...rest);
352
- markdownExtendsConfigOriginal?.(...rest);
353
- };
354
- }
355
- const inlineConfig = config.extends;
356
- if (inlineConfig.themeConfig?.blog?.RSS && inlineConfig.themeConfig?.blog?.RSS?.icon !== false && inlineConfig.themeConfig?.socialLinks?.length && !inlineConfig.themeConfig?.socialLinks?.[0].link) {
357
- const { RSS } = inlineConfig.themeConfig?.blog;
358
- inlineConfig.themeConfig.socialLinks[0].link = `${RSS.baseUrl}${(config.base || "/") + (RSS.filename || "feed.rss")}`;
331
+ function patchOptimizeDeps(config) {
332
+ if (!config.vite.optimizeDeps) {
333
+ config.vite.optimizeDeps = {};
359
334
  }
335
+ config.vite.optimizeDeps.exclude = ["vitepress-plugin-tabs", "@sugarat/theme"];
336
+ config.vite.optimizeDeps.include = ["element-plus"];
360
337
  }
361
338
 
362
339
  // src/utils/node/theme.ts
@@ -412,7 +389,7 @@ function getArticles(cfg) {
412
389
  } else {
413
390
  const timeZone = cfg?.timeZone ?? 8;
414
391
  meta.date = formatDate(
415
- new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
392
+ /* @__PURE__ */ new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
416
393
  );
417
394
  }
418
395
  meta.categories = typeof meta.categories === "string" ? [meta.categories] : meta.categories;
@@ -434,105 +411,17 @@ function getArticles(cfg) {
434
411
  }).filter((v) => v.meta.layout !== "home");
435
412
  return data;
436
413
  }
437
- var svgIcon = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><title>RSS</title><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>';
438
414
  function patchVPThemeConfig(cfg, vpThemeConfig = {}) {
439
- const RSS = cfg?.RSS;
440
- if (RSS && RSS.icon !== false) {
441
- vpThemeConfig.socialLinks = [
442
- {
443
- icon: {
444
- svg: svgIcon
445
- },
446
- link: RSS?.url,
447
- ariaLabel: RSS?.ariaLabel || "RSS"
448
- }
449
- ];
450
- }
451
415
  vpThemeConfig.sidebar = patchDefaultThemeSideBar(cfg)?.sidebar;
452
416
  return vpThemeConfig;
453
417
  }
454
418
 
455
419
  // src/utils/node/vitePlugins.ts
456
- var import_node_path3 = __toESM(require("path"));
420
+ var import_node_path2 = __toESM(require("path"));
457
421
  var import_node_child_process2 = require("child_process");
458
422
  var import_node_process2 = __toESM(require("process"));
459
423
  var import_vitepress_plugin_pagefind = require("vitepress-plugin-pagefind");
460
-
461
- // src/utils/node/genFeed.ts
462
- var import_node_path2 = __toESM(require("path"));
463
- var import_node_fs2 = __toESM(require("fs"));
464
- var import_feed = require("feed");
465
- async function genFeed(config) {
466
- const blogCfg = config.userConfig.themeConfig.blog;
467
- let posts = blogCfg.pagesData;
468
- const { RSS, authorList = [] } = blogCfg;
469
- if (!RSS)
470
- return;
471
- const { createMarkdownRenderer } = await import("vitepress");
472
- const mdRender = await createMarkdownRenderer(
473
- config.srcDir,
474
- config.markdown,
475
- config.site.base,
476
- config.logger
477
- );
478
- console.log();
479
- console.log("=== feed: https://github.com/jpmonette/feed ===");
480
- const { base } = config.userConfig;
481
- const { baseUrl, filename } = RSS;
482
- const feed = new import_feed.Feed({
483
- id: baseUrl,
484
- link: baseUrl,
485
- ...RSS
486
- });
487
- posts.sort(
488
- (a, b) => +new Date(b.meta.date) - +new Date(a.meta.date)
489
- );
490
- posts = posts.filter((v) => v.meta.layout !== "home").filter((v) => v.meta.hidden !== true);
491
- if (void 0 !== RSS?.limit && RSS?.limit > 0) {
492
- posts.splice(RSS.limit);
493
- }
494
- for (const { route, meta } of posts) {
495
- const { title, description, date } = meta;
496
- const author = meta.author ?? blogCfg.author;
497
- let link = `${baseUrl}${withBase(
498
- base || "",
499
- route.replace(/(^|\/)index$/, "$1")
500
- )}`;
501
- link = link.endsWith("/") ? link : `${link}${config?.cleanUrls ? "" : ".html"}`;
502
- const authorLink = authorList.find((v) => v.nickname === author)?.url;
503
- let html;
504
- const filepath = pageMap.get(route);
505
- if (filepath) {
506
- const fileContent = import_node_fs2.default.readFileSync(filepath, "utf-8");
507
- html = mdRender.render(fileContent);
508
- }
509
- feed.addItem({
510
- title,
511
- id: link,
512
- link,
513
- description,
514
- content: html,
515
- author: [
516
- {
517
- name: author,
518
- link: authorLink
519
- }
520
- ],
521
- date: new Date(date)
522
- });
523
- }
524
- const RSSFilename = filename || "feed.rss";
525
- const RSSFile = import_node_path2.default.join(config.outDir, RSSFilename);
526
- (0, import_node_fs2.writeFileSync)(RSSFile, feed.rss2());
527
- console.log("\u{1F389} RSS generated", RSSFilename);
528
- console.log("rss filepath:", RSSFile);
529
- console.log("rss url:", `${baseUrl}${config.site.base + RSSFilename}`);
530
- console.log("include", posts.length, "posts");
531
- console.log();
532
- console.log();
533
- }
534
-
535
- // src/utils/node/vitePlugins.ts
424
+ var import_vitepress_plugin_rss = require("vitepress-plugin-rss");
536
425
  function getVitePlugins(cfg) {
537
426
  const plugins = [];
538
427
  const buildEndFn = [];
@@ -543,7 +432,13 @@ function getVitePlugins(cfg) {
543
432
  (0, import_vitepress_plugin_pagefind.pagefindPlugin)({ ...ops, customSearchQuery: import_vitepress_plugin_pagefind.chineseSearchOptimize })
544
433
  );
545
434
  }
546
- buildEndFn.push(genFeed);
435
+ if (cfg?.mermaid !== false) {
436
+ const { MermaidPlugin } = require("vitepress-plugin-mermaid");
437
+ plugins.push(MermaidPlugin(cfg?.mermaid === true ? {} : cfg?.mermaid ?? {}));
438
+ }
439
+ if (cfg?.RSS) {
440
+ plugins.push((0, import_vitepress_plugin_rss.RssPlugin)(cfg.RSS));
441
+ }
547
442
  return plugins;
548
443
  }
549
444
  function registerVitePlugins(vpCfg, plugins) {
@@ -582,21 +477,22 @@ function getThemeConfig(cfg) {
582
477
  registerVitePlugins(extraVPConfig, vitePlugins);
583
478
  const markdownPlugin = getMarkdownPlugins(cfg);
584
479
  registerMdPlugins(extraVPConfig, markdownPlugin);
480
+ patchMermaidPluginCfg(extraVPConfig);
481
+ patchOptimizeDeps(extraVPConfig);
585
482
  return {
586
483
  themeConfig: {
587
484
  blog: {
588
485
  pagesData,
589
486
  ...cfg
590
487
  },
488
+ // 补充一些额外的配置用于继承
591
489
  ...patchVPThemeConfig(cfg)
592
490
  },
593
491
  ...extraVPConfig
594
492
  };
595
493
  }
596
494
  function defineConfig(config) {
597
- const resultConfig = wrapperCfgWithMermaid(config);
598
- supportRunExtendsPlugin(resultConfig);
599
- return resultConfig;
495
+ return config;
600
496
  }
601
497
  // Annotate the CommonJS export names for ESM import in node:
602
498
  0 && (module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sugarat/theme",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
5
5
  "author": "sugar",
6
6
  "license": "MIT",
@@ -38,32 +38,29 @@
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",
42
41
  "gray-matter": "^4.0.3",
43
- "highlight.js": "^11.7.0",
44
42
  "mermaid": "^10.2.4",
45
43
  "vitepress-plugin-mermaid": "^2.0.13",
46
44
  "vitepress-plugin-pagefind": "0.2.10",
47
- "vue-command-palette": "^0.1.4"
45
+ "vitepress-plugin-rss": "0.1.2",
46
+ "vitepress-plugin-tabs": "0.2.0"
48
47
  },
49
48
  "devDependencies": {
50
49
  "@element-plus/icons-vue": "^2.1.0",
51
50
  "element-plus": "^2.3.4",
52
51
  "pagefind": "1.0.3",
53
52
  "sass": "^1.56.1",
54
- "tsup": " ^6.5.0",
55
53
  "typescript": "^4.8.2",
56
54
  "vitepress": "1.0.0-rc.17",
57
- "vitepress-plugin-tabs": "^0.2.0",
58
55
  "vue": "^3.3.4"
59
56
  },
60
57
  "scripts": {
61
58
  "dev": "npm run build:node && npm run dev:docs",
62
59
  "dev:docs": "vitepress dev docs",
63
- "dev:node": "npx tsup src/node.ts --dts --out-dir=./ --watch --external vitepress",
60
+ "dev:node": "npx tsup",
64
61
  "build": "npm run build:node && npm run build:docs",
65
62
  "build:docs": "vitepress build docs",
66
- "build:node": "npx tsup src/node.ts --dts --out-dir=./ --external vitepress",
63
+ "build:node": "npx tsup",
67
64
  "serve": "vitepress serve docs"
68
65
  }
69
66
  }
@@ -1,7 +1,9 @@
1
1
  /* eslint-disable ts/no-namespace */
2
2
  import type { ElButton } from 'element-plus'
3
3
  import type { DefaultTheme } from 'vitepress'
4
- import type { FeedOptions } from 'feed'
4
+ import type { RSSOptions } from 'vitepress-plugin-rss'
5
+
6
+ type RSSPluginOptions = RSSOptions
5
7
 
6
8
  // TODO: 重构 lint 问题
7
9
  export declare namespace BlogPopover {
@@ -304,40 +306,7 @@ export namespace Theme {
304
306
  footer?: Footer
305
307
  }
306
308
 
307
- export type RSSOptions = Omit<FeedOptions, 'id'> & {
308
- id?: string
309
- /**
310
- * 你的站点地址
311
- * @example 'https://sugarat.top'
312
- */
313
- baseUrl: string
314
- /**
315
- * 线上访问的RSS地址
316
- * @default
317
- * @example https://sugarat.top/feed.rss
318
- * ```ts
319
- * `${baseUrl + VPConfig.site.base + (filename || 'feed.rss'}`
320
- * ```
321
- */
322
- url?: string
323
- /**
324
- * 输出的RSS文件名
325
- * @default 'feed.rss'
326
- */
327
- filename?: string
328
- /**
329
- * RSS的图标展示
330
- * @default true
331
- */
332
- icon?: boolean
333
- /**
334
- * 限制输出文件包含的文章数量
335
- * @default 0
336
- * @description (0 不限制;> 1 会按照日期排序对输出内容进行调整)
337
- */
338
- limit?: number
339
- ariaLabel?: string
340
- }
309
+ export type RSSOptions = RSSPluginOptions
341
310
 
342
311
  export interface Footer {
343
312
  /**
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import 'element-plus/theme-chalk/dark/css-vars.css'
7
7
 
8
8
  import type { Theme } from 'vitepress'
9
9
  import DefaultTheme from 'vitepress/theme'
10
+ import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'
10
11
  import BlogApp from './components/BlogApp.vue'
11
12
  import { withConfigProvider } from './composables/config/blog'
12
13
 
@@ -21,6 +22,7 @@ export const BlogTheme: Theme = {
21
22
  ...DefaultTheme,
22
23
  Layout: withConfigProvider(BlogApp),
23
24
  enhanceApp(ctx) {
25
+ enhanceAppWithTabs(ctx.app)
24
26
  DefaultTheme.enhanceApp(ctx)
25
27
  ctx.app.component('TimelinePage', TimelinePage)
26
28
  ctx.app.component('UserWorksPage', UserWorksPage)
package/src/node.ts CHANGED
@@ -1,12 +1,10 @@
1
- /* eslint-disable global-require */
2
- /* eslint-disable prefer-rest-params */
3
1
  import type { UserConfig } from 'vitepress'
4
2
  import type { Theme } from './composables/config/index'
5
3
  import {
6
4
  getMarkdownPlugins,
5
+ patchMermaidPluginCfg,
6
+ patchOptimizeDeps,
7
7
  registerMdPlugins,
8
- supportRunExtendsPlugin,
9
- wrapperCfgWithMermaid
10
8
  } from './utils/node/mdPlugins'
11
9
  import { getArticles, patchVPThemeConfig } from './utils/node/theme'
12
10
  import { getVitePlugins, registerVitePlugins } from './utils/node/vitePlugins'
@@ -30,6 +28,9 @@ export function getThemeConfig(cfg?: Partial<Theme.BlogConfig>) {
30
28
  // 注册markdown插件
31
29
  registerMdPlugins(extraVPConfig, markdownPlugin)
32
30
 
31
+ // patch extraVPConfig
32
+ patchMermaidPluginCfg(extraVPConfig)
33
+ patchOptimizeDeps(extraVPConfig)
33
34
  return {
34
35
  themeConfig: {
35
36
  blog: {
@@ -47,9 +48,7 @@ export function getThemeConfig(cfg?: Partial<Theme.BlogConfig>) {
47
48
  * defineConfig Helper
48
49
  */
49
50
  export function defineConfig(config: UserConfig<Theme.Config>): any {
50
- const resultConfig = wrapperCfgWithMermaid(config)
51
- supportRunExtendsPlugin(resultConfig)
52
- return resultConfig
51
+ return config
53
52
  }
54
53
 
55
54
  // 重新导包 tabsMarkdownPlugin 导出CJS格式支持
@@ -6,8 +6,8 @@ import { aliasObjectToArray } from './index'
6
6
 
7
7
  export function getMarkdownPlugins(cfg?: Partial<Theme.BlogConfig>) {
8
8
  const markdownPlugin: any[] = []
9
- // tabs支持
10
- if (cfg?.tabs) {
9
+ // tabs支持,默认开启
10
+ if (cfg?.tabs !== false) {
11
11
  markdownPlugin.push(tabsMarkdownPlugin)
12
12
  }
13
13
 
@@ -62,8 +62,31 @@ export function assignMermaid(config: any) {
62
62
  ]
63
63
  }
64
64
 
65
+ export function patchMermaidPluginCfg(config: any) {
66
+ if (!config.vite.resolve)
67
+ config.vite.resolve = {}
68
+ if (!config.vite.resolve.alias)
69
+ config.vite.resolve.alias = {}
70
+
71
+ config.vite.resolve.alias = [
72
+ ...aliasObjectToArray({
73
+ ...config.vite.resolve.alias,
74
+ 'cytoscape/dist/cytoscape.umd.js': 'cytoscape/dist/cytoscape.esm.js',
75
+ 'mermaid': 'mermaid/dist/mermaid.esm.mjs'
76
+ }),
77
+ { find: /^dayjs\/(.*).js/, replacement: 'dayjs/esm/$1' }
78
+ ]
79
+ }
80
+
81
+ export function patchOptimizeDeps(config: any) {
82
+ if (!config.vite.optimizeDeps) {
83
+ config.vite.optimizeDeps = {}
84
+ }
85
+ config.vite.optimizeDeps.exclude = ['vitepress-plugin-tabs', '@sugarat/theme']
86
+ config.vite.optimizeDeps.include = ['element-plus']
87
+ }
88
+
65
89
  export function wrapperCfgWithMermaid(config: UserConfig<Theme.Config>): any {
66
- // eslint-disable-next-line ts/ban-ts-comment
67
90
  // @ts-expect-error
68
91
  const extendThemeConfig = (config.extends?.themeConfig?.blog
69
92
  || {}) as Theme.BlogConfig
@@ -99,19 +122,4 @@ export function supportRunExtendsPlugin(config: UserConfig<Theme.Config>) {
99
122
  markdownExtendsConfigOriginal?.(...rest)
100
123
  }
101
124
  }
102
-
103
- // 特殊处理RSS,自动生成url(未来统一维护到 RSS插件里,待下一版主题架构升级)
104
- const inlineConfig = config.extends as UserConfig<Theme.Config>
105
-
106
- if (
107
- inlineConfig.themeConfig?.blog?.RSS
108
- && inlineConfig.themeConfig?.blog?.RSS?.icon !== false
109
- && inlineConfig.themeConfig?.socialLinks?.length
110
- && !inlineConfig.themeConfig?.socialLinks?.[0].link
111
- ) {
112
- const { RSS } = inlineConfig.themeConfig?.blog
113
- inlineConfig.themeConfig.socialLinks[0].link = `${RSS.baseUrl}${
114
- (config.base || '/') + (RSS.filename || 'feed.rss')
115
- }`
116
- }
117
125
  }
@@ -126,26 +126,10 @@ export function patchVPConfig(vpConfig: any, cfg?: Partial<Theme.BlogConfig>) {
126
126
  // TODO: 待确定场景
127
127
  }
128
128
 
129
- const svgIcon = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><title>RSS</title><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>'
130
-
131
129
  export function patchVPThemeConfig(
132
130
  cfg?: Partial<Theme.BlogConfig>,
133
131
  vpThemeConfig: any = {}
134
132
  ) {
135
- // 添加 RSS icon
136
- const RSS = cfg?.RSS
137
- if (RSS && RSS.icon !== false) {
138
- vpThemeConfig.socialLinks = [
139
- {
140
- icon: {
141
- svg: svgIcon
142
- },
143
- link: RSS?.url,
144
- ariaLabel: RSS?.ariaLabel || 'RSS'
145
- }
146
- ]
147
- }
148
-
149
133
  // 用于自定义sidebar卡片slot
150
134
  vpThemeConfig.sidebar = patchDefaultThemeSideBar(cfg)?.sidebar
151
135
 
@@ -6,8 +6,8 @@ import {
6
6
  chineseSearchOptimize,
7
7
  pagefindPlugin
8
8
  } from 'vitepress-plugin-pagefind'
9
+ import { RssPlugin } from 'vitepress-plugin-rss'
9
10
  import type { Theme } from '../../composables/config/index'
10
- import { genFeed } from './genFeed'
11
11
 
12
12
  export function getVitePlugins(cfg?: Partial<Theme.BlogConfig>) {
13
13
  const plugins: any[] = []
@@ -24,6 +24,17 @@ export function getVitePlugins(cfg?: Partial<Theme.BlogConfig>) {
24
24
  pagefindPlugin({ ...ops, customSearchQuery: chineseSearchOptimize })
25
25
  )
26
26
  }
27
+
28
+ // 内置支持Mermaid
29
+ if (cfg?.mermaid !== false) {
30
+ const { MermaidPlugin } = require('vitepress-plugin-mermaid')
31
+ plugins.push(MermaidPlugin(cfg?.mermaid === true ? {} : (cfg?.mermaid ?? {})))
32
+ }
33
+
34
+ // 内置支持RSS
35
+ if (cfg?.RSS) {
36
+ plugins.push(RssPlugin(cfg.RSS))
37
+ }
27
38
  // 未来移除使用
28
39
  // if (cfg && cfg.search !== undefined) {
29
40
  // console.log(
@@ -31,7 +42,6 @@ export function getVitePlugins(cfg?: Partial<Theme.BlogConfig>) {
31
42
  // )
32
43
  // }
33
44
 
34
- buildEndFn.push(genFeed)
35
45
  return plugins
36
46
  }
37
47
 
@@ -1,95 +0,0 @@
1
- /* eslint-disable no-console */
2
- import path from 'node:path'
3
- import fs, { writeFileSync } from 'node:fs'
4
- import { Feed } from 'feed'
5
- import type { SiteConfig } from 'vitepress'
6
- import type { Theme } from '../../composables/config/index'
7
- import { pageMap } from './theme'
8
- import { withBase } from './index'
9
-
10
- export async function genFeed(config: SiteConfig) {
11
- const blogCfg: Theme.BlogConfig = config.userConfig.themeConfig.blog
12
- let posts: Theme.PageData[] = blogCfg.pagesData
13
- const { RSS, authorList = [] } = blogCfg
14
- if (!RSS)
15
- return
16
- const { createMarkdownRenderer } = await import('vitepress')
17
-
18
- const mdRender = await createMarkdownRenderer(
19
- config.srcDir,
20
- config.markdown,
21
- config.site.base,
22
- config.logger
23
- )
24
- console.log()
25
- console.log('=== feed: https://github.com/jpmonette/feed ===')
26
- const { base } = config.userConfig
27
-
28
- const { baseUrl, filename } = RSS
29
- const feed = new Feed({
30
- id: baseUrl,
31
- link: baseUrl,
32
- ...RSS
33
- })
34
-
35
- posts.sort(
36
- (a, b) =>
37
- +new Date(b.meta.date as string) - +new Date(a.meta.date as string)
38
- )
39
-
40
- posts = posts
41
- // 过滤掉 layout:home
42
- .filter(v => v.meta.layout !== 'home')
43
- // 过滤掉不展示的
44
- .filter(v => v.meta.hidden !== true)
45
-
46
- if (undefined !== RSS?.limit && RSS?.limit > 0) {
47
- posts.splice(RSS.limit)
48
- }
49
-
50
- for (const { route, meta } of posts) {
51
- const { title, description, date } = meta
52
-
53
- const author = meta.author ?? blogCfg.author
54
- let link = `${baseUrl}${withBase(
55
- base || '',
56
- // 移除末尾的index
57
- route.replace(/(^|\/)index$/, '$1')
58
- )}`
59
- // 补全后缀
60
- link = link.endsWith('/')
61
- ? link
62
- : `${link}${config?.cleanUrls ? '' : '.html'}`
63
- const authorLink = authorList.find(v => v.nickname === author)?.url
64
- let html
65
- const filepath = pageMap.get(route)
66
- if (filepath) {
67
- const fileContent = fs.readFileSync(filepath, 'utf-8')
68
- html = mdRender.render(fileContent)
69
- }
70
-
71
- feed.addItem({
72
- title,
73
- id: link,
74
- link,
75
- description,
76
- content: html,
77
- author: [
78
- {
79
- name: author,
80
- link: authorLink
81
- }
82
- ],
83
- date: new Date(date)
84
- })
85
- }
86
- const RSSFilename = filename || 'feed.rss'
87
- const RSSFile = path.join(config.outDir, RSSFilename)
88
- writeFileSync(RSSFile, feed.rss2())
89
- console.log('🎉 RSS generated', RSSFilename)
90
- console.log('rss filepath:', RSSFile)
91
- console.log('rss url:', `${baseUrl}${config.site.base + RSSFilename}`)
92
- console.log('include', posts.length, 'posts')
93
- console.log()
94
- console.log()
95
- }