@sugarat/theme 0.2.14 → 0.2.16
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 +33 -0
- package/node.js +15 -3
- package/package.json +4 -3
- package/src/components/BlogArticleAnalyze.vue +10 -2
- package/src/components/BlogRecommendArticle.vue +2 -1
- package/src/composables/config/blog.ts +12 -0
- package/src/composables/config/index.ts +34 -0
- package/src/styles/index.scss +45 -19
- package/src/utils/node/index.ts +3 -1
- package/src/utils/node/mdPlugins.ts +14 -0
- package/src/utils/node/theme.ts +2 -0
- package/src/utils/node/vitePlugins.ts +1 -1
package/node.d.ts
CHANGED
|
@@ -73,6 +73,16 @@ declare namespace Theme {
|
|
|
73
73
|
*/
|
|
74
74
|
album: string;
|
|
75
75
|
publish?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* 文章作者,标签等信息插入位置
|
|
78
|
+
* @default 'h1'
|
|
79
|
+
*/
|
|
80
|
+
docMetaInsertSelector?: string;
|
|
81
|
+
/**
|
|
82
|
+
* 文章作者,标签等信息插入位置
|
|
83
|
+
* @default 'after'
|
|
84
|
+
*/
|
|
85
|
+
docMetaInsertPosition?: 'before' | 'after';
|
|
76
86
|
}
|
|
77
87
|
interface PageData {
|
|
78
88
|
route: string;
|
|
@@ -307,6 +317,29 @@ declare namespace Theme {
|
|
|
307
317
|
* 首页页脚
|
|
308
318
|
*/
|
|
309
319
|
footer?: Footer | Footer[];
|
|
320
|
+
/**
|
|
321
|
+
* 文章作者,标签等信息插入位置
|
|
322
|
+
* @default 'h1'
|
|
323
|
+
*/
|
|
324
|
+
docMetaInsertSelector?: string;
|
|
325
|
+
/**
|
|
326
|
+
* 文章作者,标签等信息插入位置
|
|
327
|
+
* @default 'after'
|
|
328
|
+
*/
|
|
329
|
+
docMetaInsertPosition?: 'before' | 'after';
|
|
330
|
+
/**
|
|
331
|
+
* 配置内置的 markdown-it-task-checkbox 插件,设置 false 则关闭
|
|
332
|
+
* 详见 https://github.com/linsir/markdown-it-task-checkbox
|
|
333
|
+
*/
|
|
334
|
+
taskCheckbox?: TaskCheckbox | boolean;
|
|
335
|
+
}
|
|
336
|
+
interface TaskCheckbox {
|
|
337
|
+
disabled?: boolean;
|
|
338
|
+
divWrap?: boolean;
|
|
339
|
+
divClass?: string;
|
|
340
|
+
idPrefix?: string;
|
|
341
|
+
ulClass?: string;
|
|
342
|
+
liClass?: string;
|
|
310
343
|
}
|
|
311
344
|
type RSSOptions = RSSPluginOptions;
|
|
312
345
|
interface Footer {
|
package/node.js
CHANGED
|
@@ -36,7 +36,7 @@ __export(node_exports, {
|
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(node_exports);
|
|
38
38
|
|
|
39
|
-
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.
|
|
39
|
+
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.36_vue@3.3.4/node_modules/vitepress-plugin-tabs/dist/index.js
|
|
40
40
|
var tabsMarker = "=tabs";
|
|
41
41
|
var tabsMarkerLen = tabsMarker.length;
|
|
42
42
|
var ruleBlockTabs = (state, startLine, endLine, silent) => {
|
|
@@ -295,8 +295,9 @@ function isBase64ImageURL(url) {
|
|
|
295
295
|
const regex = /^data:image\/[a-z]+;base64,/;
|
|
296
296
|
return regex.test(url);
|
|
297
297
|
}
|
|
298
|
+
var imageRegex = /!\[.*?\]\((.*?)\s*(".*?")?\)/;
|
|
298
299
|
function getFirstImagURLFromMD(content, route) {
|
|
299
|
-
const url = content.match(
|
|
300
|
+
const url = content.match(imageRegex)?.[1];
|
|
300
301
|
const isHTTPSource = url && url.startsWith("http");
|
|
301
302
|
if (!url) {
|
|
302
303
|
return "";
|
|
@@ -323,8 +324,19 @@ function getMarkdownPlugins(cfg) {
|
|
|
323
324
|
markdownPlugin.push(MermaidMarkdown);
|
|
324
325
|
}
|
|
325
326
|
}
|
|
327
|
+
if (cfg) {
|
|
328
|
+
cfg.taskCheckbox = cfg?.taskCheckbox ?? true;
|
|
329
|
+
if (cfg.taskCheckbox !== false) {
|
|
330
|
+
markdownPlugin.push(taskCheckboxPlugin(cfg.taskCheckbox));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
326
333
|
return markdownPlugin;
|
|
327
334
|
}
|
|
335
|
+
function taskCheckboxPlugin(ops) {
|
|
336
|
+
return (md) => {
|
|
337
|
+
md.use(require("markdown-it-task-checkbox"), ops);
|
|
338
|
+
};
|
|
339
|
+
}
|
|
328
340
|
function registerMdPlugins(vpCfg, plugins) {
|
|
329
341
|
if (plugins.length) {
|
|
330
342
|
vpCfg.markdown = {
|
|
@@ -514,7 +526,7 @@ function coverImgTransform() {
|
|
|
514
526
|
});
|
|
515
527
|
for (const page of blogConfig.pagesData) {
|
|
516
528
|
const { cover } = page.meta;
|
|
517
|
-
if (!cover?.startsWith("/")) {
|
|
529
|
+
if (!cover?.startsWith?.("/")) {
|
|
518
530
|
continue;
|
|
519
531
|
}
|
|
520
532
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"author": "sugar",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,10 +40,11 @@
|
|
|
40
40
|
"@vueuse/core": "^9.6.0",
|
|
41
41
|
"fast-glob": "^3.2.12",
|
|
42
42
|
"gray-matter": "^4.0.3",
|
|
43
|
+
"markdown-it-task-checkbox": "^1.0.6",
|
|
43
44
|
"mermaid": "^10.2.4",
|
|
44
45
|
"vitepress-plugin-mermaid": "2.0.13",
|
|
45
46
|
"vitepress-plugin-pagefind": "0.2.10",
|
|
46
|
-
"vitepress-plugin-rss": "0.2.
|
|
47
|
+
"vitepress-plugin-rss": "0.2.1",
|
|
47
48
|
"vitepress-plugin-tabs": "0.2.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
@@ -55,7 +56,7 @@
|
|
|
55
56
|
"pagefind": "1.0.3",
|
|
56
57
|
"sass": "^1.56.1",
|
|
57
58
|
"typescript": "^4.8.2",
|
|
58
|
-
"vitepress": "1.0.0-rc.
|
|
59
|
+
"vitepress": "1.0.0-rc.36",
|
|
59
60
|
"vue": "^3.3.4"
|
|
60
61
|
},
|
|
61
62
|
"scripts": {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
EditPen,
|
|
12
12
|
UserFilled
|
|
13
13
|
} from '@element-plus/icons-vue'
|
|
14
|
-
import { useBlogConfig, useCurrentArticle } from '../composables/config/blog'
|
|
14
|
+
import { useBlogConfig, useCurrentArticle, useDocMetaInsertPosition, useDocMetaInsertSelector } from '../composables/config/blog'
|
|
15
15
|
import countWord, { formatShowDate } from '../utils/client'
|
|
16
16
|
import type { Theme } from '../composables/config'
|
|
17
17
|
import BlogDocCover from './BlogDocCover.vue'
|
|
@@ -52,6 +52,9 @@ const readTime = computed(() => {
|
|
|
52
52
|
return Math.ceil((wordTime.value + imageTime.value) / 60)
|
|
53
53
|
})
|
|
54
54
|
|
|
55
|
+
const docMetaInsertSelector = useDocMetaInsertSelector()
|
|
56
|
+
const docMetaInsertPosition = useDocMetaInsertPosition()
|
|
57
|
+
|
|
55
58
|
const route = useRoute()
|
|
56
59
|
const $des = ref<HTMLDivElement>()
|
|
57
60
|
|
|
@@ -71,7 +74,12 @@ function analyze() {
|
|
|
71
74
|
|| ''
|
|
72
75
|
|
|
73
76
|
wordCount.value = countWord(words)
|
|
74
|
-
|
|
77
|
+
|
|
78
|
+
let el = docDomContainer?.querySelector(docMetaInsertSelector.value)
|
|
79
|
+
if (!el) {
|
|
80
|
+
el = docDomContainer?.querySelector('h1')
|
|
81
|
+
}
|
|
82
|
+
el?.[docMetaInsertPosition.value]?.($des.value!)
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
onMounted(() => {
|
|
@@ -79,7 +79,8 @@ const recommendList = computed(() => {
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
function isCurrentDoc(value: string) {
|
|
82
|
-
|
|
82
|
+
const path = decodeURIComponent(route.path).replace(/.html$/, '')
|
|
83
|
+
return [value, value.replace(/index$/, '')].includes(path)
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
const currentPage = ref(1)
|
|
@@ -77,6 +77,18 @@ export function withConfigProvider(App: Component) {
|
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
export function useDocMetaInsertSelector() {
|
|
81
|
+
const blogConfig = useConfig()
|
|
82
|
+
const { frontmatter } = useData()
|
|
83
|
+
return computed(() => frontmatter.value?.docMetaInsertSelector || blogConfig.config?.blog?.docMetaInsertSelector || 'h1')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function useDocMetaInsertPosition() {
|
|
87
|
+
const blogConfig = useConfig()
|
|
88
|
+
const { frontmatter } = useData()
|
|
89
|
+
return computed(() => frontmatter.value?.docMetaInsertPosition || blogConfig.config?.blog?.docMetaInsertPosition || 'after')
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
export function useConfig() {
|
|
81
93
|
return {
|
|
82
94
|
config: inject(configSymbol)!.value
|
|
@@ -79,6 +79,16 @@ export namespace Theme {
|
|
|
79
79
|
album: string
|
|
80
80
|
// 是否发布
|
|
81
81
|
publish?: boolean
|
|
82
|
+
/**
|
|
83
|
+
* 文章作者,标签等信息插入位置
|
|
84
|
+
* @default 'h1'
|
|
85
|
+
*/
|
|
86
|
+
docMetaInsertSelector?: string
|
|
87
|
+
/**
|
|
88
|
+
* 文章作者,标签等信息插入位置
|
|
89
|
+
* @default 'after'
|
|
90
|
+
*/
|
|
91
|
+
docMetaInsertPosition?: 'before' | 'after'
|
|
82
92
|
}
|
|
83
93
|
export interface PageData {
|
|
84
94
|
route: string
|
|
@@ -339,6 +349,30 @@ export namespace Theme {
|
|
|
339
349
|
* 首页页脚
|
|
340
350
|
*/
|
|
341
351
|
footer?: Footer | Footer[]
|
|
352
|
+
/**
|
|
353
|
+
* 文章作者,标签等信息插入位置
|
|
354
|
+
* @default 'h1'
|
|
355
|
+
*/
|
|
356
|
+
docMetaInsertSelector?: string
|
|
357
|
+
/**
|
|
358
|
+
* 文章作者,标签等信息插入位置
|
|
359
|
+
* @default 'after'
|
|
360
|
+
*/
|
|
361
|
+
docMetaInsertPosition?: 'before' | 'after'
|
|
362
|
+
/**
|
|
363
|
+
* 配置内置的 markdown-it-task-checkbox 插件,设置 false 则关闭
|
|
364
|
+
* 详见 https://github.com/linsir/markdown-it-task-checkbox
|
|
365
|
+
*/
|
|
366
|
+
taskCheckbox?: TaskCheckbox | boolean
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export interface TaskCheckbox {
|
|
370
|
+
disabled?: boolean
|
|
371
|
+
divWrap?: boolean
|
|
372
|
+
divClass?: string
|
|
373
|
+
idPrefix?: string
|
|
374
|
+
ulClass?: string
|
|
375
|
+
liClass?: string
|
|
342
376
|
}
|
|
343
377
|
|
|
344
378
|
export type RSSOptions = RSSPluginOptions
|
package/src/styles/index.scss
CHANGED
|
@@ -23,7 +23,7 @@ html.dark {
|
|
|
23
23
|
}
|
|
24
24
|
.VPHome {
|
|
25
25
|
&::before {
|
|
26
|
-
content:
|
|
26
|
+
content: "";
|
|
27
27
|
inset: 0;
|
|
28
28
|
position: fixed;
|
|
29
29
|
top: 0;
|
|
@@ -33,17 +33,13 @@ html.dark {
|
|
|
33
33
|
min-height: 100%;
|
|
34
34
|
}
|
|
35
35
|
min-height: calc(100vh - var(--vp-nav-height));
|
|
36
|
-
background: radial-gradient(
|
|
37
|
-
ellipse,
|
|
38
|
-
rgba(var(--bg-gradient-home), 1) 0%,
|
|
39
|
-
rgba(var(--bg-gradient-home), 0) 700%
|
|
40
|
-
);
|
|
36
|
+
background: radial-gradient(ellipse, rgba(var(--bg-gradient-home), 1) 0%, rgba(var(--bg-gradient-home), 0) 700%);
|
|
41
37
|
}
|
|
42
38
|
|
|
43
39
|
@media screen and (min-width: 960px) {
|
|
44
|
-
#VPContent.is-home.VPContent{
|
|
40
|
+
#VPContent.is-home.VPContent {
|
|
45
41
|
padding-top: 0;
|
|
46
|
-
.VPHome{
|
|
42
|
+
.VPHome {
|
|
47
43
|
min-height: 100vh;
|
|
48
44
|
}
|
|
49
45
|
}
|
|
@@ -85,10 +81,7 @@ html.dark {
|
|
|
85
81
|
// sidebar
|
|
86
82
|
@media (min-width: 1440px) {
|
|
87
83
|
aside.VPSidebar {
|
|
88
|
-
padding-left: max(
|
|
89
|
-
32px,
|
|
90
|
-
calc((100% - (var(--vp-layout-max-width) - 16px)) / 2)
|
|
91
|
-
) !important;
|
|
84
|
+
padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 16px)) / 2)) !important;
|
|
92
85
|
padding-right: 10px !important;
|
|
93
86
|
}
|
|
94
87
|
}
|
|
@@ -126,20 +119,53 @@ html.dark {
|
|
|
126
119
|
background-color: var(--vp-c-brand-1);
|
|
127
120
|
}
|
|
128
121
|
|
|
129
|
-
|
|
130
|
-
main .vp-doc a{
|
|
122
|
+
main .vp-doc a {
|
|
131
123
|
text-decoration: none;
|
|
132
124
|
}
|
|
133
|
-
main .vp-doc a:hover{
|
|
125
|
+
main .vp-doc a:hover {
|
|
134
126
|
text-decoration: underline dotted;
|
|
135
127
|
}
|
|
136
128
|
|
|
137
|
-
|
|
138
129
|
// 自定义全局样式
|
|
139
|
-
span.svg-icon{
|
|
140
|
-
svg{
|
|
130
|
+
span.svg-icon {
|
|
131
|
+
svg {
|
|
141
132
|
width: 14px;
|
|
142
133
|
height: 14px;
|
|
143
134
|
margin-right: 4px;
|
|
144
135
|
}
|
|
145
|
-
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.vp-doc ul.task-list {
|
|
139
|
+
list-style: none;
|
|
140
|
+
padding-left: 10px;
|
|
141
|
+
|
|
142
|
+
input[type="checkbox"] {
|
|
143
|
+
cursor: pointer;
|
|
144
|
+
position: relative;
|
|
145
|
+
width: 13px;
|
|
146
|
+
height: 13px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
input[type="checkbox"]::after {
|
|
150
|
+
position: absolute;
|
|
151
|
+
top: 0;
|
|
152
|
+
color: #000;
|
|
153
|
+
width: 13px;
|
|
154
|
+
height: 13px;
|
|
155
|
+
display: inline-block;
|
|
156
|
+
visibility: visible;
|
|
157
|
+
padding-left: 0px;
|
|
158
|
+
text-align: center;
|
|
159
|
+
content: " ";
|
|
160
|
+
border-radius: 3px;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
input[type="checkbox"]:checked::after {
|
|
164
|
+
content: "✓";
|
|
165
|
+
color: #fff;
|
|
166
|
+
line-height: 14px;
|
|
167
|
+
font-size: 10px;
|
|
168
|
+
font-weight: bold;
|
|
169
|
+
background-color: var(--vp-c-brand-1);
|
|
170
|
+
}
|
|
171
|
+
}
|
package/src/utils/node/index.ts
CHANGED
|
@@ -126,12 +126,14 @@ function isBase64ImageURL(url: string) {
|
|
|
126
126
|
return regex.test(url)
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
const imageRegex = /!\[.*?\]\((.*?)\s*(".*?")?\)/
|
|
130
|
+
|
|
129
131
|
/**
|
|
130
132
|
* 从文档内容中提取封面
|
|
131
133
|
* @param content 文档内容
|
|
132
134
|
*/
|
|
133
135
|
export function getFirstImagURLFromMD(content: string, route: string) {
|
|
134
|
-
const url = content.match(
|
|
136
|
+
const url = content.match(imageRegex)?.[1]
|
|
135
137
|
const isHTTPSource = url && url.startsWith('http')
|
|
136
138
|
if (!url) {
|
|
137
139
|
return ''
|
|
@@ -19,9 +19,23 @@ export function getMarkdownPlugins(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
19
19
|
markdownPlugin.push(MermaidMarkdown)
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
if (cfg) {
|
|
24
|
+
cfg.taskCheckbox = cfg?.taskCheckbox ?? true
|
|
25
|
+
if (cfg.taskCheckbox !== false) {
|
|
26
|
+
markdownPlugin.push(taskCheckboxPlugin(cfg.taskCheckbox))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
return markdownPlugin
|
|
23
31
|
}
|
|
24
32
|
|
|
33
|
+
export function taskCheckboxPlugin(ops: Theme.TaskCheckbox | boolean) {
|
|
34
|
+
return (md: any) => {
|
|
35
|
+
md.use(require('markdown-it-task-checkbox'), ops)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
export function registerMdPlugins(vpCfg: any, plugins: any[]) {
|
|
26
40
|
if (plugins.length) {
|
|
27
41
|
vpCfg.markdown = {
|
package/src/utils/node/theme.ts
CHANGED
|
@@ -61,6 +61,7 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
61
61
|
|
|
62
62
|
const fileContent = fs.readFileSync(v, 'utf-8')
|
|
63
63
|
// TODO:摘要生成优化
|
|
64
|
+
// TODO: 用上内容content
|
|
64
65
|
const { data: frontmatter, excerpt } = matter(fileContent, {
|
|
65
66
|
excerpt: true
|
|
66
67
|
})
|
|
@@ -70,6 +71,7 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
if (!meta.title) {
|
|
74
|
+
// TODO:优化标题的采集
|
|
73
75
|
meta.title = getDefaultTitle(fileContent)
|
|
74
76
|
}
|
|
75
77
|
if (!meta.date) {
|