@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
|
@@ -44,7 +44,7 @@ import { ref, computed } from 'vue'
|
|
|
44
44
|
import { ElButton, ElLink } from 'element-plus'
|
|
45
45
|
import { withBase } from 'vitepress'
|
|
46
46
|
import { useArticles, useBlogConfig } from '../composables/config/blog'
|
|
47
|
-
import { formatShowDate } from '../utils/
|
|
47
|
+
import { formatShowDate } from '../utils/client'
|
|
48
48
|
|
|
49
49
|
const { hotArticle } = useBlogConfig()
|
|
50
50
|
const title = computed(() => hotArticle?.title || '🔥 精选文章')
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
import { withBase } from 'vitepress'
|
|
43
43
|
import { computed } from 'vue'
|
|
44
44
|
import { useWindowSize } from '@vueuse/core'
|
|
45
|
-
import { formatShowDate } from '../utils/
|
|
45
|
+
import { formatShowDate } from '../utils/client'
|
|
46
46
|
|
|
47
47
|
const { width } = useWindowSize()
|
|
48
48
|
const inMobile = computed(() => width.value <= 500)
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
import { ref, computed } from 'vue'
|
|
51
51
|
import { useRoute, withBase } from 'vitepress'
|
|
52
52
|
import { ElButton, ElLink } from 'element-plus'
|
|
53
|
-
import { formatShowDate } from '../utils/
|
|
53
|
+
import { formatShowDate } from '../utils/client'
|
|
54
54
|
import { useArticles, useBlogConfig } from '../composables/config/blog'
|
|
55
55
|
|
|
56
56
|
const { recommend: _recommend } = useBlogConfig()
|
|
57
57
|
|
|
58
58
|
const sidebarStyle = computed(() =>
|
|
59
|
-
_recommend && _recommend?.style ? _recommend.style : '
|
|
59
|
+
_recommend && _recommend?.style ? _recommend.style : 'sidebar'
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
const recommendPadding = computed(() =>
|
|
@@ -132,7 +132,7 @@ import { computed, nextTick, ref, watch, onBeforeMount, onMounted } from 'vue'
|
|
|
132
132
|
import { Command } from 'vue-command-palette'
|
|
133
133
|
import { useRoute, useRouter, withBase } from 'vitepress'
|
|
134
134
|
import { useMagicKeys, useWindowSize } from '@vueuse/core'
|
|
135
|
-
import { chineseSearchOptimize, formatDate } from '../utils'
|
|
135
|
+
import { chineseSearchOptimize, formatDate } from '../utils/client'
|
|
136
136
|
import { useArticles, useBlogConfig } from '../composables/config/blog'
|
|
137
137
|
import { Theme } from '../composables/config'
|
|
138
138
|
import LogoPagefind from './LogoPagefind.vue'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ElButton } from 'element-plus'
|
|
2
2
|
import type { DefaultTheme } from 'vitepress'
|
|
3
|
+
import type { FeedOptions } from 'feed'
|
|
3
4
|
|
|
4
5
|
export namespace BlogPopover {
|
|
5
6
|
export interface Title {
|
|
@@ -113,7 +114,7 @@ export namespace Theme {
|
|
|
113
114
|
empty?: string | boolean
|
|
114
115
|
/**
|
|
115
116
|
* 设置推荐文章的展示风格
|
|
116
|
-
* @default '
|
|
117
|
+
* @default 'sidebar'
|
|
117
118
|
*/
|
|
118
119
|
style?: 'card' | 'sidebar'
|
|
119
120
|
}
|
|
@@ -266,7 +267,7 @@ export namespace Theme {
|
|
|
266
267
|
works?: UserWorks
|
|
267
268
|
/**
|
|
268
269
|
* https://mermaid.js.org/config/setup/modules/mermaidAPI.html#mermaidapi-configuration-defaults for options
|
|
269
|
-
* @default
|
|
270
|
+
* @default true
|
|
270
271
|
*/
|
|
271
272
|
mermaid?: any
|
|
272
273
|
/**
|
|
@@ -274,8 +275,29 @@ export namespace Theme {
|
|
|
274
275
|
* @default 8 => 'UTC+8'
|
|
275
276
|
* */
|
|
276
277
|
timeZone?: number
|
|
278
|
+
/**
|
|
279
|
+
* 启用RSS配置
|
|
280
|
+
*/
|
|
281
|
+
RSS?: RSSOptions
|
|
277
282
|
}
|
|
278
283
|
|
|
284
|
+
export type RSSOptions = FeedOptions & {
|
|
285
|
+
baseUrl: string
|
|
286
|
+
/**
|
|
287
|
+
* 线上访问的RSS地址
|
|
288
|
+
*/
|
|
289
|
+
url: string
|
|
290
|
+
/**
|
|
291
|
+
* 输出的RSS文件名
|
|
292
|
+
* @default 'feed.rss'
|
|
293
|
+
*/
|
|
294
|
+
filename?: string
|
|
295
|
+
/**
|
|
296
|
+
* 是否展示RSS的图标
|
|
297
|
+
* @default true
|
|
298
|
+
*/
|
|
299
|
+
showIcon?: boolean
|
|
300
|
+
}
|
|
279
301
|
export interface Config extends DefaultTheme.Config {
|
|
280
302
|
blog?: BlogConfig
|
|
281
303
|
}
|
package/src/node.ts
CHANGED
|
@@ -1,387 +1,56 @@
|
|
|
1
1
|
/* eslint-disable global-require */
|
|
2
2
|
/* eslint-disable prefer-rest-params */
|
|
3
|
-
import
|
|
4
|
-
import matter from 'gray-matter'
|
|
5
|
-
import fs from 'fs'
|
|
6
|
-
import { execSync, spawn, spawnSync } from 'child_process'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
import type { SiteConfig, UserConfig } from 'vitepress'
|
|
9
|
-
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
|
|
10
|
-
import { formatDate } from './utils/index'
|
|
3
|
+
import type { UserConfig } from 'vitepress'
|
|
11
4
|
import type { Theme } from './composables/config/index'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
import {
|
|
6
|
+
getMarkdownPlugins,
|
|
7
|
+
registerMdPlugins,
|
|
8
|
+
wrapperCfgWithMermaid,
|
|
9
|
+
supportRunExtendsPlugin
|
|
10
|
+
} from './utils/node/mdPlugins'
|
|
11
|
+
import { getArticles, patchVPThemeConfig } from './utils/node/theme'
|
|
12
|
+
import { getVitePlugins, registerVitePlugins } from './utils/node/vitePlugins'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 获取主题的配置
|
|
16
|
+
* @param cfg 主题配置
|
|
17
|
+
*/
|
|
15
18
|
export function getThemeConfig(cfg?: Partial<Theme.BlogConfig>) {
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const data = files
|
|
20
|
-
.map((v) => {
|
|
21
|
-
let route = v
|
|
22
|
-
// 处理文件后缀名
|
|
23
|
-
.replace('.md', '')
|
|
24
|
-
|
|
25
|
-
// 去除 srcDir 处理目录名
|
|
26
|
-
if (route.startsWith('./')) {
|
|
27
|
-
route = route.replace(
|
|
28
|
-
new RegExp(
|
|
29
|
-
`^\\.\\/${path
|
|
30
|
-
.join(srcDir, '/')
|
|
31
|
-
.replace(new RegExp(`\\${path.sep}`, 'g'), '/')}`
|
|
32
|
-
),
|
|
33
|
-
''
|
|
34
|
-
)
|
|
35
|
-
} else {
|
|
36
|
-
route = route.replace(
|
|
37
|
-
new RegExp(
|
|
38
|
-
`^${path
|
|
39
|
-
.join(srcDir, '/')
|
|
40
|
-
.replace(new RegExp(`\\${path.sep}`, 'g'), '/')}`
|
|
41
|
-
),
|
|
42
|
-
''
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const fileContent = fs.readFileSync(v, 'utf-8')
|
|
47
|
-
|
|
48
|
-
const meta: Partial<Theme.PageMeta> = {
|
|
49
|
-
...matter(fileContent).data
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!meta.title) {
|
|
53
|
-
meta.title = getDefaultTitle(fileContent)
|
|
54
|
-
}
|
|
55
|
-
if (!meta.date) {
|
|
56
|
-
// getGitTimestamp(v).then((v) => {
|
|
57
|
-
// meta.date = formatDate(v)
|
|
58
|
-
// })
|
|
59
|
-
meta.date = getFileBirthTime(v)
|
|
60
|
-
} else {
|
|
61
|
-
const timeZone = cfg?.timeZone ?? 8
|
|
62
|
-
meta.date = formatDate(
|
|
63
|
-
new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 处理tags和categories,兼容历史文章
|
|
68
|
-
meta.categories =
|
|
69
|
-
typeof meta.categories === 'string'
|
|
70
|
-
? [meta.categories]
|
|
71
|
-
: meta.categories
|
|
72
|
-
meta.tags = typeof meta.tags === 'string' ? [meta.tags] : meta.tags
|
|
73
|
-
meta.tag = [meta.tag || []]
|
|
74
|
-
.flat()
|
|
75
|
-
.concat([
|
|
76
|
-
...new Set([...(meta.categories || []), ...(meta.tags || [])])
|
|
77
|
-
])
|
|
78
|
-
|
|
79
|
-
// 获取摘要信息
|
|
80
|
-
const wordCount = 100
|
|
81
|
-
meta.description =
|
|
82
|
-
meta.description || getTextSummary(fileContent, wordCount)
|
|
83
|
-
|
|
84
|
-
// 获取封面图
|
|
85
|
-
meta.cover =
|
|
86
|
-
meta.cover ??
|
|
87
|
-
(fileContent.match(/[!]\[.*?\]\((https:\/\/.+)\)/)?.[1] || '')
|
|
88
|
-
|
|
89
|
-
// 是否发布 默认发布
|
|
90
|
-
if (meta.publish === false) {
|
|
91
|
-
meta.hidden = true
|
|
92
|
-
meta.recommend = false
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
route: `/${route}`,
|
|
97
|
-
meta
|
|
98
|
-
}
|
|
99
|
-
})
|
|
100
|
-
.filter((v) => v.meta.layout !== 'home')
|
|
101
|
-
|
|
102
|
-
const extraConfig: any = {}
|
|
19
|
+
// 文章数据
|
|
20
|
+
const pagesData = getArticles(cfg)
|
|
21
|
+
const extraVPConfig: any = {}
|
|
103
22
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
)
|
|
108
|
-
checkKeys.push('vite')
|
|
109
|
-
|
|
110
|
-
let resolveConfig: any
|
|
111
|
-
extraConfig.vite = {
|
|
112
|
-
plugins: [
|
|
113
|
-
{
|
|
114
|
-
name: '@sugarar/theme-plugin-pagefind',
|
|
115
|
-
enforce: 'pre',
|
|
116
|
-
configResolved(config: any) {
|
|
117
|
-
if (resolveConfig) {
|
|
118
|
-
return
|
|
119
|
-
}
|
|
120
|
-
resolveConfig = config
|
|
121
|
-
|
|
122
|
-
const vitepressConfig: SiteConfig = config.vitepress
|
|
123
|
-
if (!vitepressConfig) {
|
|
124
|
-
return
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// 添加 自定义 vitepress 的钩子
|
|
128
|
-
const selfBuildEnd = vitepressConfig.buildEnd
|
|
129
|
-
vitepressConfig.buildEnd = (siteConfig: any) => {
|
|
130
|
-
// 调用自己的
|
|
131
|
-
selfBuildEnd?.(siteConfig)
|
|
132
|
-
// 调用pagefind
|
|
133
|
-
const ignore: string[] = [
|
|
134
|
-
// 侧边栏内容
|
|
135
|
-
'div.aside',
|
|
136
|
-
// 标题锚点
|
|
137
|
-
'a.header-anchor'
|
|
138
|
-
]
|
|
139
|
-
const { log } = console
|
|
140
|
-
log()
|
|
141
|
-
log('=== pagefind: https://pagefind.app/ ===')
|
|
142
|
-
let command = `npx pagefind --source ${path.join(
|
|
143
|
-
process.argv.slice(2)?.[1] || '.',
|
|
144
|
-
'.vitepress/dist'
|
|
145
|
-
)}`
|
|
146
|
-
|
|
147
|
-
if (ignore.length) {
|
|
148
|
-
command += ` --exclude-selectors "${ignore.join(', ')}"`
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
log(command)
|
|
152
|
-
log()
|
|
153
|
-
execSync(command, {
|
|
154
|
-
stdio: 'inherit'
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
// 添加检索的内容标识
|
|
159
|
-
transform(code: string, id: string) {
|
|
160
|
-
if (id.endsWith('theme-default/Layout.vue')) {
|
|
161
|
-
return code.replace(
|
|
162
|
-
'<VPContent>',
|
|
163
|
-
'<VPContent data-pagefind-body>'
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
return code
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
]
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const markdownPlugin: any[] = []
|
|
173
|
-
// tabs支持
|
|
174
|
-
if (cfg?.tabs) {
|
|
175
|
-
markdownPlugin.push(tabsMarkdownPlugin)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// 流程图支持
|
|
179
|
-
if (cfg) {
|
|
180
|
-
cfg.mermaid = cfg?.mermaid ?? true
|
|
181
|
-
}
|
|
182
|
-
if (cfg?.mermaid !== false) {
|
|
183
|
-
const { MermaidMarkdown } = require('vitepress-plugin-mermaid')
|
|
184
|
-
markdownPlugin.push(MermaidMarkdown)
|
|
185
|
-
}
|
|
23
|
+
// 获取要加载的vite插件
|
|
24
|
+
const vitePlugins = getVitePlugins(cfg)
|
|
25
|
+
// 注册Vite插件
|
|
26
|
+
registerVitePlugins(extraVPConfig, vitePlugins)
|
|
186
27
|
|
|
28
|
+
// 获取要加载的markdown插件
|
|
29
|
+
const markdownPlugin = getMarkdownPlugins(cfg)
|
|
187
30
|
// 注册markdown插件
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
config(...rest: any[]) {
|
|
191
|
-
markdownPlugin.forEach((plugin) => {
|
|
192
|
-
plugin?.(...rest)
|
|
193
|
-
})
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
31
|
+
registerMdPlugins(extraVPConfig, markdownPlugin)
|
|
32
|
+
|
|
197
33
|
return {
|
|
198
34
|
themeConfig: {
|
|
199
35
|
blog: {
|
|
200
|
-
pagesData
|
|
36
|
+
pagesData,
|
|
201
37
|
...cfg
|
|
202
38
|
},
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
sidebar: [
|
|
206
|
-
{
|
|
207
|
-
text: '',
|
|
208
|
-
items: []
|
|
209
|
-
}
|
|
210
|
-
]
|
|
211
|
-
}
|
|
212
|
-
: undefined)
|
|
39
|
+
// 补充一些额外的配置用于继承
|
|
40
|
+
...patchVPThemeConfig(cfg)
|
|
213
41
|
},
|
|
214
|
-
...
|
|
42
|
+
...extraVPConfig
|
|
215
43
|
}
|
|
216
44
|
}
|
|
217
45
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
.split('\n')
|
|
222
|
-
?.find((str) => {
|
|
223
|
-
return str.startsWith('# ')
|
|
224
|
-
})
|
|
225
|
-
?.slice(2)
|
|
226
|
-
.replace(/^\s+|\s+$/g, '') || ''
|
|
227
|
-
return title
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function clearMatterContent(content: string) {
|
|
231
|
-
let first___: unknown
|
|
232
|
-
let second___: unknown
|
|
233
|
-
|
|
234
|
-
const lines = content.split('\n').reduce<string[]>((pre, line) => {
|
|
235
|
-
// 移除开头的空白行
|
|
236
|
-
if (!line.trim() && pre.length === 0) {
|
|
237
|
-
return pre
|
|
238
|
-
}
|
|
239
|
-
if (line.trim() === '---') {
|
|
240
|
-
if (first___ === undefined) {
|
|
241
|
-
first___ = pre.length
|
|
242
|
-
} else if (second___ === undefined) {
|
|
243
|
-
second___ = pre.length
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
pre.push(line)
|
|
247
|
-
return pre
|
|
248
|
-
}, [])
|
|
249
|
-
return (
|
|
250
|
-
lines
|
|
251
|
-
// 剔除---之间的内容
|
|
252
|
-
.slice((second___ as number) || 0)
|
|
253
|
-
.join('\n')
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export function getFileBirthTime(url: string) {
|
|
258
|
-
let date = new Date()
|
|
259
|
-
|
|
260
|
-
try {
|
|
261
|
-
// 参考 vitepress 中的 getGitTimestamp 实现
|
|
262
|
-
const infoStr = spawnSync('git', ['log', '-1', '--pretty="%ci"', url])
|
|
263
|
-
.stdout?.toString()
|
|
264
|
-
.replace(/["']/g, '')
|
|
265
|
-
.trim()
|
|
266
|
-
if (infoStr) {
|
|
267
|
-
date = new Date(infoStr)
|
|
268
|
-
}
|
|
269
|
-
} catch (error) {
|
|
270
|
-
return formatDate(date)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return formatDate(date)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export function getGitTimestamp(file: string) {
|
|
277
|
-
return new Promise((resolve, reject) => {
|
|
278
|
-
const child = spawn('git', ['log', '-1', '--pretty="%ci"', file])
|
|
279
|
-
let output = ''
|
|
280
|
-
child.stdout.on('data', (d) => {
|
|
281
|
-
output += String(d)
|
|
282
|
-
})
|
|
283
|
-
child.on('close', () => {
|
|
284
|
-
resolve(+new Date(output))
|
|
285
|
-
})
|
|
286
|
-
child.on('error', reject)
|
|
287
|
-
})
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function getTextSummary(text: string, count = 100) {
|
|
291
|
-
return (
|
|
292
|
-
clearMatterContent(text)
|
|
293
|
-
.match(/^# ([\s\S]+)/m)?.[1]
|
|
294
|
-
// 除去标题
|
|
295
|
-
?.replace(/#/g, '')
|
|
296
|
-
// 除去图片
|
|
297
|
-
?.replace(/!\[.*?\]\(.*?\)/g, '')
|
|
298
|
-
// 除去链接
|
|
299
|
-
?.replace(/\[(.*?)\]\(.*?\)/g, '$1')
|
|
300
|
-
// 除去加粗
|
|
301
|
-
?.replace(/\*\*(.*?)\*\*/g, '$1')
|
|
302
|
-
?.split('\n')
|
|
303
|
-
?.filter((v) => !!v)
|
|
304
|
-
?.slice(1)
|
|
305
|
-
?.join('\n')
|
|
306
|
-
?.replace(/>(.*)/, '')
|
|
307
|
-
?.slice(0, count)
|
|
308
|
-
)
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
export function assignMermaid(config: any) {
|
|
312
|
-
if (!config?.mermaid) return
|
|
313
|
-
|
|
314
|
-
if (!config.vite) config.vite = {}
|
|
315
|
-
if (!config.vite.plugins) config.vite.plugins = []
|
|
316
|
-
const { MermaidPlugin } = require('vitepress-plugin-mermaid')
|
|
317
|
-
config.vite.plugins.push(MermaidPlugin(config.mermaid))
|
|
318
|
-
if (!config.vite.resolve) config.vite.resolve = {}
|
|
319
|
-
if (!config.vite.resolve.alias) config.vite.resolve.alias = {}
|
|
320
|
-
|
|
321
|
-
config.vite.resolve.alias = [
|
|
322
|
-
...aliasObjectToArray({
|
|
323
|
-
...config.vite.resolve.alias,
|
|
324
|
-
'cytoscape/dist/cytoscape.umd.js': 'cytoscape/dist/cytoscape.esm.js',
|
|
325
|
-
mermaid: 'mermaid/dist/mermaid.esm.mjs'
|
|
326
|
-
}),
|
|
327
|
-
{ find: /^dayjs\/(.*).js/, replacement: 'dayjs/esm/$1' }
|
|
328
|
-
]
|
|
329
|
-
}
|
|
330
|
-
function aliasObjectToArray(obj: Record<string, string>) {
|
|
331
|
-
return Object.entries(obj).map(([find, replacement]) => ({
|
|
332
|
-
find,
|
|
333
|
-
replacement
|
|
334
|
-
}))
|
|
335
|
-
}
|
|
46
|
+
/**
|
|
47
|
+
* defineConfig Helper
|
|
48
|
+
*/
|
|
336
49
|
export function defineConfig(config: UserConfig<Theme.Config>): any {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (config.themeConfig?.themeConfig) {
|
|
340
|
-
config.extends = checkKeys.reduce((pre, key) => {
|
|
341
|
-
// @ts-ignore
|
|
342
|
-
pre[key] = config.themeConfig[key]
|
|
343
|
-
// @ts-ignore
|
|
344
|
-
delete config.themeConfig[key]
|
|
345
|
-
return pre
|
|
346
|
-
}, {})
|
|
347
|
-
|
|
348
|
-
// 打印warn信息
|
|
349
|
-
setTimeout(() => {
|
|
350
|
-
console.warn('==↓ 主题配置方式过期,请尽快参照文档更新 ↓==')
|
|
351
|
-
console.warn('https://theme.sugarat.top/config/global.html')
|
|
352
|
-
}, 1200)
|
|
353
|
-
}
|
|
354
|
-
// @ts-ignore
|
|
355
|
-
const extendThemeConfig = (config.extends?.themeConfig?.blog ||
|
|
356
|
-
{}) as Theme.BlogConfig
|
|
357
|
-
|
|
358
|
-
// 开关支持Mermaid
|
|
359
|
-
const resultConfig =
|
|
360
|
-
extendThemeConfig.mermaid === false
|
|
361
|
-
? config
|
|
362
|
-
: {
|
|
363
|
-
...config,
|
|
364
|
-
mermaid:
|
|
365
|
-
extendThemeConfig.mermaid === true ? {} : extendThemeConfig.mermaid
|
|
366
|
-
}
|
|
367
|
-
assignMermaid(resultConfig)
|
|
368
|
-
|
|
369
|
-
// 处理markdown插件
|
|
370
|
-
if (!resultConfig.markdown) resultConfig.markdown = {}
|
|
371
|
-
// @ts-ignore
|
|
372
|
-
if (config.extends?.markdown?.config) {
|
|
373
|
-
const markdownExtendsConfigOriginal =
|
|
374
|
-
// @ts-ignore
|
|
375
|
-
config.extends?.markdown?.config
|
|
376
|
-
const selfMarkdownConfig = resultConfig.markdown?.config
|
|
377
|
-
|
|
378
|
-
resultConfig.markdown.config = (...rest: any[]) => {
|
|
379
|
-
// @ts-ignore
|
|
380
|
-
selfMarkdownConfig?.(...rest)
|
|
381
|
-
markdownExtendsConfigOriginal?.(...rest)
|
|
382
|
-
}
|
|
383
|
-
}
|
|
50
|
+
const resultConfig = wrapperCfgWithMermaid(config)
|
|
51
|
+
supportRunExtendsPlugin(resultConfig)
|
|
384
52
|
return resultConfig
|
|
385
53
|
}
|
|
386
54
|
|
|
55
|
+
// 重新导包 tabsMarkdownPlugin 导出CJS格式支持
|
|
387
56
|
export { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
|
package/src/styles/index.scss
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { writeFileSync } from 'fs'
|
|
4
|
+
import { Feed } from 'feed'
|
|
5
|
+
import type { SiteConfig } from 'vitepress'
|
|
6
|
+
import type { Theme } from '../../composables/config/index'
|
|
7
|
+
import { withBase } from './index'
|
|
8
|
+
|
|
9
|
+
export function genFeed(config: SiteConfig) {
|
|
10
|
+
const blogCfg: Theme.BlogConfig = config.userConfig.themeConfig.blog
|
|
11
|
+
const posts: Theme.PageData[] = blogCfg.pagesData
|
|
12
|
+
const { RSS, authorList = [] } = blogCfg
|
|
13
|
+
if (!RSS) return
|
|
14
|
+
console.log()
|
|
15
|
+
console.log('=== feed: https://github.com/jpmonette/feed ===')
|
|
16
|
+
const { base } = config.userConfig
|
|
17
|
+
|
|
18
|
+
const { baseUrl, filename } = RSS
|
|
19
|
+
const feed = new Feed(RSS)
|
|
20
|
+
|
|
21
|
+
posts.sort(
|
|
22
|
+
(a, b) =>
|
|
23
|
+
+new Date(b.meta.date as string) - +new Date(a.meta.date as string)
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
for (const { route, meta } of posts) {
|
|
27
|
+
const { title, description, date, hidden } = meta
|
|
28
|
+
if (hidden) continue
|
|
29
|
+
const author = meta.author ?? blogCfg.author
|
|
30
|
+
const link = `${baseUrl}${withBase(base || '', route)}.html`
|
|
31
|
+
const authorLink = authorList.find((v) => v.nickname === author)?.url
|
|
32
|
+
feed.addItem({
|
|
33
|
+
title,
|
|
34
|
+
id: link,
|
|
35
|
+
// TODO: 待定,添加transform
|
|
36
|
+
link,
|
|
37
|
+
description,
|
|
38
|
+
// TODO: 待定,文章多的时候,会导致 RSS 文件过大
|
|
39
|
+
// content: html,
|
|
40
|
+
author: [
|
|
41
|
+
{
|
|
42
|
+
name: author,
|
|
43
|
+
link: authorLink
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
date: new Date(date)
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
const RSSFile = path.join(config.outDir, filename || 'feed.rss')
|
|
50
|
+
writeFileSync(RSSFile, feed.rss2())
|
|
51
|
+
console.log('🎉 RSS generated', filename || 'feed.rss')
|
|
52
|
+
console.log()
|
|
53
|
+
}
|