@sugarat/theme 0.1.49 → 0.1.50
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 +1 -1
- package/node.js +23 -19
- package/package.json +23 -23
- package/src/components/BlogAlert.vue +17 -17
- package/src/components/BlogApp.vue +81 -49
- package/src/components/BlogArticleAnalyze.vue +56 -57
- package/src/components/BlogComment.vue +53 -50
- package/src/components/BlogDocCover.vue +4 -4
- package/src/components/BlogFriendLink.vue +40 -31
- package/src/components/BlogHomeBanner.vue +22 -16
- package/src/components/BlogHomeOverview.vue +20 -20
- package/src/components/BlogHomeTags.vue +49 -40
- package/src/components/BlogHotArticle.vue +43 -36
- package/src/components/BlogImagePreview.vue +7 -5
- package/src/components/BlogItem.vue +42 -43
- package/src/components/BlogList.vue +46 -42
- package/src/components/BlogPopover.vue +41 -39
- package/src/components/BlogRecommendArticle.vue +58 -48
- package/src/components/BlogSearch.vue +143 -145
- package/src/components/UserWorks.vue +214 -210
- package/src/composables/config/blog.ts +7 -5
- package/src/composables/config/index.ts +33 -31
- package/src/constants/svg.ts +2 -2
- package/src/index.ts +1 -2
- package/src/node.ts +2 -2
- package/src/styles/scss/global.scss +0 -5
- package/src/utils/client/index.ts +9 -8
- package/src/utils/node/genFeed.ts +8 -7
- package/src/utils/node/index.ts +8 -6
- package/src/utils/node/mdPlugins.ts +29 -22
- package/src/utils/node/theme.ts +16 -13
- package/src/utils/node/vitePlugins.ts +7 -6
- package/types/vue-shim.d.ts +1 -1
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import './styles/index.scss'
|
|
|
5
5
|
import 'element-plus/dist/index.css'
|
|
6
6
|
import 'element-plus/theme-chalk/dark/css-vars.css'
|
|
7
7
|
|
|
8
|
-
import { Theme } from 'vitepress'
|
|
8
|
+
import type { Theme } from 'vitepress'
|
|
9
9
|
import DefaultTheme from 'vitepress/theme'
|
|
10
10
|
import BlogApp from './components/BlogApp.vue'
|
|
11
11
|
import { withConfigProvider } from './composables/config/blog'
|
|
@@ -22,7 +22,6 @@ export const BlogTheme: Theme = {
|
|
|
22
22
|
Layout: withConfigProvider(BlogApp),
|
|
23
23
|
enhanceApp(ctx) {
|
|
24
24
|
DefaultTheme.enhanceApp(ctx)
|
|
25
|
-
// @ts-ignore
|
|
26
25
|
ctx.app.component('TimelinePage', TimelinePage)
|
|
27
26
|
ctx.app.component('UserWorksPage', UserWorksPage)
|
|
28
27
|
}
|
package/src/node.ts
CHANGED
|
@@ -5,8 +5,8 @@ import type { Theme } from './composables/config/index'
|
|
|
5
5
|
import {
|
|
6
6
|
getMarkdownPlugins,
|
|
7
7
|
registerMdPlugins,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
supportRunExtendsPlugin,
|
|
9
|
+
wrapperCfgWithMermaid
|
|
10
10
|
} from './utils/node/mdPlugins'
|
|
11
11
|
import { getArticles, patchVPThemeConfig } from './utils/node/theme'
|
|
12
12
|
import { getVitePlugins, registerVitePlugins } from './utils/node/vitePlugins'
|
|
@@ -11,7 +11,7 @@ export function formatDate(d: any, fmt = 'yyyy-MM-dd hh:mm:ss') {
|
|
|
11
11
|
'm+': d.getMinutes(), // 分
|
|
12
12
|
's+': d.getSeconds(), // 秒
|
|
13
13
|
'q+': Math.floor((d.getMonth() + 3) / 3), // 季度
|
|
14
|
-
S: d.getMilliseconds() // 毫秒
|
|
14
|
+
'S': d.getMilliseconds() // 毫秒
|
|
15
15
|
}
|
|
16
16
|
if (/(y+)/.test(fmt)) {
|
|
17
17
|
fmt = fmt.replace(
|
|
@@ -65,8 +65,8 @@ export function formatShowDate(date: Date | string) {
|
|
|
65
65
|
return formatDate(new Date(date), 'yyyy-MM-dd')
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const pattern
|
|
69
|
-
/[a-zA-Z0-9_\u0392-\
|
|
68
|
+
const pattern
|
|
69
|
+
= /[a-zA-Z0-9_\u0392-\u03C9\u00C0-\u00FF\u0600-\u06FF\u0400-\u04FF]+|[\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF\u3040-\u309F\uAC00-\uD7AF]+/g
|
|
70
70
|
|
|
71
71
|
// copy from https://github.com/youngjuning/vscode-juejin-wordcount/blob/main/count-word.ts
|
|
72
72
|
export default function countWord(data: string) {
|
|
@@ -76,9 +76,10 @@ export default function countWord(data: string) {
|
|
|
76
76
|
return 0
|
|
77
77
|
}
|
|
78
78
|
for (let i = 0; i < m.length; i += 1) {
|
|
79
|
-
if (m[i].charCodeAt(0) >=
|
|
79
|
+
if (m[i].charCodeAt(0) >= 0x4E00) {
|
|
80
80
|
count += m[i].length
|
|
81
|
-
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
82
83
|
count += 1
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -87,7 +88,7 @@ export default function countWord(data: string) {
|
|
|
87
88
|
|
|
88
89
|
export function chineseSearchOptimize(input: string) {
|
|
89
90
|
return input
|
|
90
|
-
.replace(/[\
|
|
91
|
+
.replace(/[\u4E00-\u9FA5]/g, ' $& ')
|
|
91
92
|
.replace(/\s+/g, ' ')
|
|
92
93
|
.trim()
|
|
93
94
|
}
|
|
@@ -105,7 +106,7 @@ export function getGithubUpdateTime(url: string) {
|
|
|
105
106
|
}
|
|
106
107
|
const [owner, repo] = match[1].split('/')
|
|
107
108
|
return fetch(`https://api.github.com/repos/${owner}/${repo}`)
|
|
108
|
-
.then(
|
|
109
|
+
.then(res => res.json())
|
|
109
110
|
.then((res) => {
|
|
110
111
|
return res.updated_at
|
|
111
112
|
})
|
|
@@ -128,7 +129,7 @@ export function getGithubDirUpdateTime(
|
|
|
128
129
|
baseUrl += `?path=${dir}`
|
|
129
130
|
}
|
|
130
131
|
return fetch(baseUrl)
|
|
131
|
-
.then(
|
|
132
|
+
.then(res => res.json())
|
|
132
133
|
.then((res) => {
|
|
133
134
|
return [res].flat()[0].commit.committer.date
|
|
134
135
|
})
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import fs, { writeFileSync } from 'fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import fs, { writeFileSync } from 'node:fs'
|
|
4
4
|
import { Feed } from 'feed'
|
|
5
5
|
import type { SiteConfig } from 'vitepress'
|
|
6
6
|
import type { Theme } from '../../composables/config/index'
|
|
7
|
-
import { withBase } from './index'
|
|
8
7
|
import { pageMap } from './theme'
|
|
8
|
+
import { withBase } from './index'
|
|
9
9
|
|
|
10
10
|
export async function genFeed(config: SiteConfig) {
|
|
11
11
|
const blogCfg: Theme.BlogConfig = config.userConfig.themeConfig.blog
|
|
12
12
|
let posts: Theme.PageData[] = blogCfg.pagesData
|
|
13
13
|
const { RSS, authorList = [] } = blogCfg
|
|
14
|
-
if (!RSS)
|
|
14
|
+
if (!RSS)
|
|
15
|
+
return
|
|
15
16
|
const { createMarkdownRenderer } = await import('vitepress')
|
|
16
17
|
|
|
17
18
|
const mdRender = await createMarkdownRenderer(
|
|
@@ -38,9 +39,9 @@ export async function genFeed(config: SiteConfig) {
|
|
|
38
39
|
|
|
39
40
|
posts = posts
|
|
40
41
|
// 过滤掉 layout:home
|
|
41
|
-
.filter(
|
|
42
|
+
.filter(v => v.meta.layout !== 'home')
|
|
42
43
|
// 过滤掉不展示的
|
|
43
|
-
.filter(
|
|
44
|
+
.filter(v => v.meta.hidden !== true)
|
|
44
45
|
|
|
45
46
|
if (undefined !== RSS?.limit && RSS?.limit > 0) {
|
|
46
47
|
posts.splice(RSS.limit)
|
|
@@ -59,7 +60,7 @@ export async function genFeed(config: SiteConfig) {
|
|
|
59
60
|
link = link.endsWith('/')
|
|
60
61
|
? link
|
|
61
62
|
: `${link}${config?.cleanUrls ? '' : '.html'}`
|
|
62
|
-
const authorLink = authorList.find(
|
|
63
|
+
const authorLink = authorList.find(v => v.nickname === author)?.url
|
|
63
64
|
let html
|
|
64
65
|
const filepath = pageMap.get(route)
|
|
65
66
|
if (filepath) {
|
package/src/utils/node/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable global-require */
|
|
2
2
|
/* eslint-disable prefer-rest-params */
|
|
3
|
-
import { spawn, spawnSync } from 'child_process'
|
|
3
|
+
import { spawn, spawnSync } from 'node:child_process'
|
|
4
4
|
import { formatDate } from '../client'
|
|
5
5
|
|
|
6
6
|
export function clearMatterContent(content: string) {
|
|
@@ -15,7 +15,8 @@ export function clearMatterContent(content: string) {
|
|
|
15
15
|
if (line.trim() === '---') {
|
|
16
16
|
if (first___ === undefined) {
|
|
17
17
|
first___ = pre.length
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
|
+
else if (second___ === undefined) {
|
|
19
20
|
second___ = pre.length
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -30,8 +31,8 @@ export function clearMatterContent(content: string) {
|
|
|
30
31
|
)
|
|
31
32
|
}
|
|
32
33
|
export function getDefaultTitle(content: string) {
|
|
33
|
-
const title
|
|
34
|
-
clearMatterContent(content)
|
|
34
|
+
const title
|
|
35
|
+
= clearMatterContent(content)
|
|
35
36
|
.split('\n')
|
|
36
37
|
?.find((str) => {
|
|
37
38
|
return str.startsWith('# ')
|
|
@@ -53,7 +54,8 @@ export function getFileBirthTime(url: string) {
|
|
|
53
54
|
if (infoStr) {
|
|
54
55
|
date = new Date(infoStr)
|
|
55
56
|
}
|
|
56
|
-
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
57
59
|
return formatDate(date)
|
|
58
60
|
}
|
|
59
61
|
|
|
@@ -87,7 +89,7 @@ export function getTextSummary(text: string, count = 100) {
|
|
|
87
89
|
// 除去加粗
|
|
88
90
|
?.replace(/\*\*(.*?)\*\*/g, '$1')
|
|
89
91
|
?.split('\n')
|
|
90
|
-
?.filter(
|
|
92
|
+
?.filter(v => !!v)
|
|
91
93
|
?.slice(1)
|
|
92
94
|
?.join('\n')
|
|
93
95
|
?.replace(/>(.*)/, '')
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable global-require */
|
|
2
2
|
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
|
|
3
3
|
import type { UserConfig } from 'vitepress'
|
|
4
|
-
import { aliasObjectToArray } from './index'
|
|
5
4
|
import type { Theme } from '../../composables/config/index'
|
|
5
|
+
import { aliasObjectToArray } from './index'
|
|
6
6
|
|
|
7
7
|
export function getMarkdownPlugins(cfg?: Partial<Theme.BlogConfig>) {
|
|
8
8
|
const markdownPlugin: any[] = []
|
|
@@ -38,33 +38,39 @@ export function registerMdPlugins(vpCfg: any, plugins: any[]) {
|
|
|
38
38
|
* 流程图支持,配置mermaid
|
|
39
39
|
*/
|
|
40
40
|
export function assignMermaid(config: any) {
|
|
41
|
-
if (!config?.mermaid)
|
|
41
|
+
if (!config?.mermaid)
|
|
42
|
+
return
|
|
42
43
|
|
|
43
|
-
if (!config.vite)
|
|
44
|
-
|
|
44
|
+
if (!config.vite)
|
|
45
|
+
config.vite = {}
|
|
46
|
+
if (!config.vite.plugins)
|
|
47
|
+
config.vite.plugins = []
|
|
45
48
|
const { MermaidPlugin } = require('vitepress-plugin-mermaid')
|
|
46
49
|
config.vite.plugins.push(MermaidPlugin(config.mermaid))
|
|
47
|
-
if (!config.vite.resolve)
|
|
48
|
-
|
|
50
|
+
if (!config.vite.resolve)
|
|
51
|
+
config.vite.resolve = {}
|
|
52
|
+
if (!config.vite.resolve.alias)
|
|
53
|
+
config.vite.resolve.alias = {}
|
|
49
54
|
|
|
50
55
|
config.vite.resolve.alias = [
|
|
51
56
|
...aliasObjectToArray({
|
|
52
57
|
...config.vite.resolve.alias,
|
|
53
58
|
'cytoscape/dist/cytoscape.umd.js': 'cytoscape/dist/cytoscape.esm.js',
|
|
54
|
-
mermaid: 'mermaid/dist/mermaid.esm.mjs'
|
|
59
|
+
'mermaid': 'mermaid/dist/mermaid.esm.mjs'
|
|
55
60
|
}),
|
|
56
61
|
{ find: /^dayjs\/(.*).js/, replacement: 'dayjs/esm/$1' }
|
|
57
62
|
]
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
export function wrapperCfgWithMermaid(config: UserConfig<Theme.Config>): any {
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
// eslint-disable-next-line ts/ban-ts-comment
|
|
67
|
+
// @ts-expect-error
|
|
68
|
+
const extendThemeConfig = (config.extends?.themeConfig?.blog
|
|
69
|
+
|| {}) as Theme.BlogConfig
|
|
64
70
|
|
|
65
71
|
// 开关支持Mermaid
|
|
66
|
-
const resultConfig
|
|
67
|
-
extendThemeConfig.mermaid === false
|
|
72
|
+
const resultConfig
|
|
73
|
+
= extendThemeConfig.mermaid === false
|
|
68
74
|
? config
|
|
69
75
|
: {
|
|
70
76
|
...config,
|
|
@@ -77,17 +83,18 @@ export function wrapperCfgWithMermaid(config: UserConfig<Theme.Config>): any {
|
|
|
77
83
|
|
|
78
84
|
export function supportRunExtendsPlugin(config: UserConfig<Theme.Config>) {
|
|
79
85
|
// 处理markdown插件
|
|
80
|
-
if (!config.markdown)
|
|
86
|
+
if (!config.markdown)
|
|
87
|
+
config.markdown = {}
|
|
81
88
|
// 支持运行继承的markdown插件
|
|
82
|
-
// @ts-
|
|
89
|
+
// @ts-expect-error
|
|
83
90
|
if (config.extends?.markdown?.config) {
|
|
84
|
-
const markdownExtendsConfigOriginal
|
|
85
|
-
// @ts-
|
|
86
|
-
config.extends?.markdown?.config
|
|
91
|
+
const markdownExtendsConfigOriginal
|
|
92
|
+
// @ts-expect-error
|
|
93
|
+
= config.extends?.markdown?.config
|
|
87
94
|
const selfMarkdownConfig = config.markdown?.config
|
|
88
95
|
|
|
89
96
|
config.markdown.config = (...rest: any[]) => {
|
|
90
|
-
// @ts-
|
|
97
|
+
// @ts-expect-error
|
|
91
98
|
selfMarkdownConfig?.(...rest)
|
|
92
99
|
markdownExtendsConfigOriginal?.(...rest)
|
|
93
100
|
}
|
|
@@ -97,10 +104,10 @@ export function supportRunExtendsPlugin(config: UserConfig<Theme.Config>) {
|
|
|
97
104
|
const inlineConfig = config.extends as UserConfig<Theme.Config>
|
|
98
105
|
|
|
99
106
|
if (
|
|
100
|
-
inlineConfig.themeConfig?.blog?.RSS
|
|
101
|
-
inlineConfig.themeConfig?.blog?.RSS?.icon !== false
|
|
102
|
-
inlineConfig.themeConfig?.socialLinks?.length
|
|
103
|
-
!inlineConfig.themeConfig?.socialLinks?.[0].link
|
|
107
|
+
inlineConfig.themeConfig?.blog?.RSS
|
|
108
|
+
&& inlineConfig.themeConfig?.blog?.RSS?.icon !== false
|
|
109
|
+
&& inlineConfig.themeConfig?.socialLinks?.length
|
|
110
|
+
&& !inlineConfig.themeConfig?.socialLinks?.[0].link
|
|
104
111
|
) {
|
|
105
112
|
const { RSS } = inlineConfig.themeConfig?.blog
|
|
106
113
|
inlineConfig.themeConfig.socialLinks[0].link = `${RSS.baseUrl}${
|
package/src/utils/node/theme.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/* eslint-disable prefer-rest-params */
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import process from 'node:process'
|
|
2
5
|
import glob from 'fast-glob'
|
|
3
6
|
import matter from 'gray-matter'
|
|
4
|
-
import fs from 'fs'
|
|
5
|
-
import path from 'path'
|
|
6
7
|
import type { Theme } from '../../composables/config/index'
|
|
7
|
-
import { getDefaultTitle, getFileBirthTime, getTextSummary } from './index'
|
|
8
8
|
import { formatDate } from '../client'
|
|
9
|
+
import { getDefaultTitle, getFileBirthTime, getTextSummary } from './index'
|
|
9
10
|
|
|
10
11
|
export function patchDefaultThemeSideBar(cfg?: Partial<Theme.BlogConfig>) {
|
|
11
12
|
return cfg?.blog !== false && cfg?.recommend !== false
|
|
@@ -44,7 +45,8 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
44
45
|
),
|
|
45
46
|
''
|
|
46
47
|
)
|
|
47
|
-
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
48
50
|
route = route.replace(
|
|
49
51
|
new RegExp(
|
|
50
52
|
`^${path
|
|
@@ -75,7 +77,8 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
75
77
|
// meta.date = formatDate(v)
|
|
76
78
|
// })
|
|
77
79
|
meta.date = getFileBirthTime(v)
|
|
78
|
-
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
79
82
|
const timeZone = cfg?.timeZone ?? 8
|
|
80
83
|
meta.date = formatDate(
|
|
81
84
|
new Date(`${new Date(meta.date).toUTCString()}+${timeZone}`)
|
|
@@ -83,8 +86,8 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
// 处理tags和categories,兼容历史文章
|
|
86
|
-
meta.categories
|
|
87
|
-
typeof meta.categories === 'string'
|
|
89
|
+
meta.categories
|
|
90
|
+
= typeof meta.categories === 'string'
|
|
88
91
|
? [meta.categories]
|
|
89
92
|
: meta.categories
|
|
90
93
|
meta.tags = typeof meta.tags === 'string' ? [meta.tags] : meta.tags
|
|
@@ -96,13 +99,13 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
96
99
|
|
|
97
100
|
// 获取摘要信息
|
|
98
101
|
const wordCount = 100
|
|
99
|
-
meta.description
|
|
100
|
-
meta.description || getTextSummary(fileContent, wordCount)
|
|
102
|
+
meta.description
|
|
103
|
+
= meta.description || getTextSummary(fileContent, wordCount)
|
|
101
104
|
|
|
102
105
|
// 获取封面图
|
|
103
|
-
meta.cover
|
|
104
|
-
meta.cover
|
|
105
|
-
(fileContent.match(/[!]\[.*?\]\((https:\/\/.+)\)/)?.[1] || '')
|
|
106
|
+
meta.cover
|
|
107
|
+
= meta.cover
|
|
108
|
+
?? (fileContent.match(/[!]\[.*?\]\((https:\/\/.+)\)/)?.[1] || '')
|
|
106
109
|
|
|
107
110
|
// 是否发布 默认发布
|
|
108
111
|
if (meta.publish === false) {
|
|
@@ -115,7 +118,7 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
115
118
|
meta
|
|
116
119
|
}
|
|
117
120
|
})
|
|
118
|
-
.filter(
|
|
121
|
+
.filter(v => v.meta.layout !== 'home')
|
|
119
122
|
return data as Theme.PageData[]
|
|
120
123
|
}
|
|
121
124
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { execSync } from 'node:child_process'
|
|
3
|
+
import process from 'node:process'
|
|
1
4
|
import type { SiteConfig } from 'vitepress'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import { execSync } from 'child_process'
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
chineseSearchOptimize,
|
|
7
|
+
pagefindPlugin
|
|
7
8
|
} from 'vitepress-plugin-pagefind'
|
|
8
9
|
import type { Theme } from '../../composables/config/index'
|
|
9
10
|
import { genFeed } from './genFeed'
|
|
@@ -101,8 +102,8 @@ export function inlineBuildEndPlugin(buildEndFn: any[]) {
|
|
|
101
102
|
vitepressConfig.buildEnd = (siteCfg) => {
|
|
102
103
|
selfBuildEnd?.(siteCfg)
|
|
103
104
|
buildEndFn
|
|
104
|
-
.filter(
|
|
105
|
-
.forEach(
|
|
105
|
+
.filter(fn => typeof fn === 'function')
|
|
106
|
+
.forEach(fn => fn(siteCfg))
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
}
|
package/types/vue-shim.d.ts
CHANGED