hexo-theme-stellar 1.32.0 → 1.32.1
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/_config.yml +2 -2
- package/package.json +1 -1
- package/scripts/events/lib/get_image_ratios.js +53 -31
- package/scripts/tags/index.js +1 -1
- package/scripts/tags/lib/{quote.js → blockquote.js} +5 -5
- package/scripts/tags/lib/navbar.js +2 -2
- package/source/css/_common/base.styl +16 -5
- package/source/css/_common/canonical.styl +1 -1
- package/source/css/_common/highlight.styl +5 -2
- package/source/css/_components/pages/article-story.styl +34 -32
- package/source/css/_components/tag-plugins/copy.styl +11 -7
- package/source/css/_components/tag-plugins/navbar.styl +18 -8
- package/source/css/_components/tag-plugins/note.styl +0 -3
- package/source/css/_components/tag-plugins/override.styl +0 -5
- package/source/css/_components/tag-plugins/quote.styl +1 -1
- package/source/css/_components/widgets/list.styl +1 -1
- package/source/css/_components/widgets/toc.styl +1 -1
- package/source/css/_plugins/comments/twikoo.styl +1 -1
package/_config.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
######## Stellar info ########
|
|
2
2
|
stellar:
|
|
3
|
-
version: '1.32.
|
|
3
|
+
version: '1.32.1'
|
|
4
4
|
homepage: 'https://xaoxuu.com/wiki/stellar/'
|
|
5
5
|
repo: 'https://github.com/xaoxuu/hexo-theme-stellar'
|
|
6
6
|
main_css: /css/main.css
|
|
@@ -608,7 +608,7 @@ plugins:
|
|
|
608
608
|
|
|
609
609
|
style:
|
|
610
610
|
prefers_theme: auto # auto / light / dark
|
|
611
|
-
smooth_scroll:
|
|
611
|
+
smooth_scroll: true # true / false 开启时如果目录过长可能无法准确定位
|
|
612
612
|
font-size:
|
|
613
613
|
root: 16px # 改这个会影响全局所有文字的字号
|
|
614
614
|
body: 17px # 影响正文区域的字号,如果改成 px 则不受 root 影响
|
package/package.json
CHANGED
|
@@ -10,25 +10,44 @@ let cache = fs.existsSync(outputPath)
|
|
|
10
10
|
? JSON.parse(fs.readFileSync(outputPath))
|
|
11
11
|
: {};
|
|
12
12
|
|
|
13
|
-
// 提取 Markdown
|
|
14
|
-
function
|
|
15
|
-
const
|
|
13
|
+
// 提取 Markdown 中的图片链接并处理已有 ratio
|
|
14
|
+
function extractImageUrlsAndCacheRatio(content, relative, ctx) {
|
|
15
|
+
const urlsToProbe = [];
|
|
16
16
|
const tagImgRegex = /{%\s+image\s+[^%]*?\b(https?:\/\/[^\s%]+)[^%]*?%}/g;
|
|
17
17
|
|
|
18
|
+
if (!cache[relative]) cache[relative] = {};
|
|
19
|
+
|
|
18
20
|
let match;
|
|
19
21
|
while ((match = tagImgRegex.exec(content)) !== null) {
|
|
20
|
-
|
|
22
|
+
const fullTag = match[0];
|
|
23
|
+
const url = match[1];
|
|
24
|
+
|
|
25
|
+
// ratio:xxx 或 ratio:xxx/yyy
|
|
26
|
+
const ratioMatch = fullTag.match(/ratio:([0-9./]+)/);
|
|
27
|
+
const ratioStr = ratioMatch ? ratioMatch[1] : null;
|
|
28
|
+
|
|
29
|
+
if (cache[relative][url]) {
|
|
30
|
+
// 已有缓存,跳过
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (ratioStr) {
|
|
35
|
+
cache[relative][url] = ratioStr;
|
|
36
|
+
// 🧠 实时写入
|
|
37
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
38
|
+
fs.writeFileSync(outputPath, JSON.stringify(cache, null, 2));
|
|
39
|
+
} else {
|
|
40
|
+
urlsToProbe.push(url);
|
|
41
|
+
}
|
|
21
42
|
}
|
|
22
43
|
|
|
23
|
-
return
|
|
44
|
+
return urlsToProbe;
|
|
24
45
|
}
|
|
25
46
|
|
|
26
|
-
|
|
27
|
-
// 远程图片尺寸探测
|
|
47
|
+
// 探测远程图片尺寸
|
|
28
48
|
async function getImageRatio(ctx, url) {
|
|
29
|
-
if (!url.startsWith('http'))
|
|
30
|
-
|
|
31
|
-
}
|
|
49
|
+
if (!url.startsWith('http')) return null;
|
|
50
|
+
|
|
32
51
|
try {
|
|
33
52
|
const result = await probe(url);
|
|
34
53
|
return `${result.width}/${result.height}`;
|
|
@@ -38,46 +57,49 @@ async function getImageRatio(ctx, url) {
|
|
|
38
57
|
}
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
|
|
42
60
|
// 主逻辑
|
|
43
61
|
module.exports = async (ctx, options) => {
|
|
44
62
|
const cacheExists = fs.existsSync(outputPath);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
ctx.log.info(
|
|
64
|
+
cacheExists
|
|
65
|
+
? '正在获取图片长宽比。缓存已存在,开始增量更新...'
|
|
66
|
+
: '正在获取图片长宽比。首次可能耗时较久,请耐心等待...'
|
|
67
|
+
);
|
|
50
68
|
|
|
51
69
|
const mdFiles = glob.sync('source/**/*.md');
|
|
52
70
|
|
|
53
71
|
for (const file of mdFiles) {
|
|
54
72
|
const relative = path.relative(process.cwd(), file);
|
|
55
73
|
const content = fs.readFileSync(file, 'utf8');
|
|
56
|
-
const imageUrls = extractImageUrls(content);
|
|
57
|
-
const currentUrls = new Set(imageUrls);
|
|
58
74
|
|
|
59
|
-
//
|
|
75
|
+
// 初始化文件级缓存(提取前先建好结构)
|
|
60
76
|
if (!cache[relative]) {
|
|
61
77
|
cache[relative] = {};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const imageUrls = extractImageUrlsAndCacheRatio(content, relative, ctx);
|
|
81
|
+
const currentUrls = new Set([
|
|
82
|
+
...imageUrls,
|
|
83
|
+
...Object.keys(cache[relative])
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
// 清理已被 Markdown 中移除的旧记录
|
|
87
|
+
for (const oldUrl of Object.keys(cache[relative])) {
|
|
88
|
+
if (!currentUrls.has(oldUrl)) {
|
|
89
|
+
delete cache[relative][oldUrl];
|
|
67
90
|
}
|
|
68
91
|
}
|
|
69
92
|
|
|
70
|
-
//
|
|
93
|
+
// 探测未缓存图片
|
|
71
94
|
for (const url of imageUrls) {
|
|
72
|
-
if (cache[relative][url])
|
|
73
|
-
|
|
74
|
-
}
|
|
95
|
+
if (cache[relative][url]) continue;
|
|
96
|
+
|
|
75
97
|
const ratio = await getImageRatio(ctx, url);
|
|
76
98
|
if (ratio) {
|
|
77
99
|
cache[relative][url] = ratio;
|
|
78
|
-
ctx.log.info(
|
|
100
|
+
ctx.log.info(`✅ 探测添加: ${url} → ${ratio}`);
|
|
79
101
|
|
|
80
|
-
//
|
|
102
|
+
// 实时落盘
|
|
81
103
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
82
104
|
fs.writeFileSync(outputPath, JSON.stringify(cache, null, 2));
|
|
83
105
|
}
|
|
@@ -85,4 +107,4 @@ module.exports = async (ctx, options) => {
|
|
|
85
107
|
}
|
|
86
108
|
|
|
87
109
|
ctx.log.info('[image-ratios.json] 生成完成');
|
|
88
|
-
};
|
|
110
|
+
};
|
package/scripts/tags/index.js
CHANGED
|
@@ -40,7 +40,7 @@ hexo.extend.tag.register('navbar', require('./lib/navbar')(hexo))
|
|
|
40
40
|
hexo.extend.tag.register('note', require('./lib/note')(hexo))
|
|
41
41
|
hexo.extend.tag.register('poetry', require('./lib/poetry')(hexo), true)
|
|
42
42
|
hexo.extend.tag.register('quot', require('./lib/quot')(hexo))
|
|
43
|
-
hexo.extend.tag.register('
|
|
43
|
+
hexo.extend.tag.register('blockquote', require('./lib/blockquote')(hexo), true)
|
|
44
44
|
hexo.extend.tag.register('hashtag', require('./lib/hashtag')(hexo))
|
|
45
45
|
hexo.extend.tag.register('okr', require('./lib/okr')(hexo), {ends: true})
|
|
46
46
|
hexo.extend.tag.register('audio', require('./lib/audio')(hexo))
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* blockquote.js v1.1 | https://github.com/xaoxuu/hexo-theme-stellar/
|
|
3
3
|
* 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* {%
|
|
5
|
+
* blockquote:
|
|
6
|
+
* {% blockquote [indent:true/false] %}
|
|
7
7
|
* body
|
|
8
|
-
* {%
|
|
8
|
+
* {% endblockquote %}
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ module.exports = ctx => function(args, content) {
|
|
|
15
15
|
var el = ''
|
|
16
16
|
args = ctx.args.map(args, ['indent'], [])
|
|
17
17
|
|
|
18
|
-
el += `<div class="tag-plugin
|
|
18
|
+
el += `<div class="tag-plugin blockquote" indent="${args.indent}">`
|
|
19
19
|
el += ctx.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('')
|
|
20
20
|
el += `</div>`
|
|
21
21
|
return el
|
|
@@ -18,7 +18,7 @@ module.exports = ctx => function(args) {
|
|
|
18
18
|
if (args.links) {
|
|
19
19
|
args.links = args.links.split(' ')
|
|
20
20
|
}
|
|
21
|
-
var el = `<div class="tag-plugin navbar"
|
|
21
|
+
var el = `<div class="tag-plugin navbar">`
|
|
22
22
|
for (let link of args.links) {
|
|
23
23
|
const matches = link.match(/\[(.*?)\]\((.*?)\)/i)
|
|
24
24
|
if (matches?.length > 2) {
|
|
@@ -33,6 +33,6 @@ module.exports = ctx => function(args) {
|
|
|
33
33
|
el += `<a class="link" href="#${link}">${link}</a>`
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
el += `</
|
|
36
|
+
el += `</div>`
|
|
37
37
|
return el
|
|
38
38
|
}
|
|
@@ -35,24 +35,35 @@ ul,ol
|
|
|
35
35
|
table:not([class])
|
|
36
36
|
border-collapse: collapse
|
|
37
37
|
overflow: auto
|
|
38
|
-
display: block
|
|
39
38
|
margin: 1rem 0
|
|
40
39
|
max-width: 100%
|
|
41
40
|
vertical-align: text-top
|
|
42
41
|
--fsp: $fsp2
|
|
43
42
|
font-size: var(--fsp)
|
|
43
|
+
scrollbar(0,0)
|
|
44
|
+
display: table
|
|
44
45
|
th
|
|
45
46
|
background: var(--block)
|
|
47
|
+
border-top: 1px solid var(--block-border)
|
|
48
|
+
border-bottom: 1px solid var(--block-border)
|
|
46
49
|
td,th
|
|
47
|
-
padding:
|
|
48
|
-
border: 1px solid var(--block-border)
|
|
50
|
+
padding: 4px 1em
|
|
49
51
|
line-height: 1.5
|
|
50
52
|
tr
|
|
51
|
-
|
|
52
|
-
white-space:nowrap
|
|
53
|
+
border-bottom: 1px dashed var(--block-border)
|
|
53
54
|
trans()
|
|
54
55
|
&:hover
|
|
55
56
|
background: var(--block)
|
|
56
57
|
|
|
58
|
+
@media screen and (min-width: $device-mobile-max)
|
|
59
|
+
width 100%
|
|
60
|
+
|
|
61
|
+
@media screen and (max-width: $device-mobile-max)
|
|
62
|
+
display: block
|
|
63
|
+
tr
|
|
64
|
+
word-break: keep-all
|
|
65
|
+
white-space:nowrap
|
|
66
|
+
|
|
67
|
+
|
|
57
68
|
*[ff=title]
|
|
58
69
|
font-family: $ff-logo
|
|
@@ -36,7 +36,7 @@ p>code:not([class]),li>code:not([class])
|
|
|
36
36
|
display: block
|
|
37
37
|
border-bottom-left-radius: $border-button
|
|
38
38
|
border-bottom-right-radius: $border-button
|
|
39
|
-
background: var(--block
|
|
39
|
+
background: var(--block)
|
|
40
40
|
>table
|
|
41
41
|
overflow: auto
|
|
42
42
|
display: block
|
|
@@ -50,6 +50,7 @@ p>code:not([class]),li>code:not([class])
|
|
|
50
50
|
scrollbar-codeblock(convert(hexo-config('style.codeblock.scrollbar')))
|
|
51
51
|
tr
|
|
52
52
|
background: transparent
|
|
53
|
+
border: none
|
|
53
54
|
&:hover
|
|
54
55
|
background: transparent
|
|
55
56
|
|
|
@@ -88,11 +89,13 @@ p>code:not([class]),li>code:not([class])
|
|
|
88
89
|
background: var(--block)
|
|
89
90
|
margin: 0
|
|
90
91
|
padding: 1em 0
|
|
92
|
+
pre
|
|
93
|
+
background: none
|
|
91
94
|
.blob-code-inner
|
|
92
95
|
color: var(--text-p1)
|
|
93
96
|
font-family: $ff-codeblock
|
|
94
97
|
.gist-meta
|
|
95
|
-
background: var(--block
|
|
98
|
+
background: var(--block)
|
|
96
99
|
|
|
97
100
|
|
|
98
101
|
table:not([class])
|
|
@@ -82,38 +82,7 @@
|
|
|
82
82
|
margin: 2em 0 1.5em
|
|
83
83
|
>a:first-child
|
|
84
84
|
display: none
|
|
85
|
-
|
|
86
|
-
>blockquote,.tag-plugin.quote
|
|
87
|
-
text-align: center
|
|
88
|
-
--inset: calc(var(--fsp) * 2)
|
|
89
|
-
margin-left: var(--inset)
|
|
90
|
-
margin-right: var(--inset)
|
|
91
|
-
background: var(--block)
|
|
92
|
-
padding: 1rem 2rem
|
|
93
|
-
border-radius: $border-card
|
|
94
|
-
&:before,&:after
|
|
95
|
-
position: absolute
|
|
96
|
-
font-size: 2rem
|
|
97
|
-
background-color: hsla($color-theme, 0.25)
|
|
98
|
-
top: -0.3em
|
|
99
|
-
width: 1em
|
|
100
|
-
height: 1em
|
|
101
|
-
content: ''
|
|
102
|
-
opacity 1
|
|
103
|
-
trans1 all
|
|
104
|
-
&:before
|
|
105
|
-
left: -0.3em
|
|
106
|
-
svg-mask-icon($iQuoteLeft)
|
|
107
|
-
&:after
|
|
108
|
-
right: -0.3em
|
|
109
|
-
svg-mask-icon($iQuoteRight)
|
|
110
|
-
p:not([class])
|
|
111
|
-
color: var(--text-p2)
|
|
112
|
-
font-size: $fs-body
|
|
113
|
-
text-indent: 2em
|
|
114
|
-
&:hover
|
|
115
|
-
&:before,&:after
|
|
116
|
-
background-color: hsla($color-theme, 0.5)
|
|
85
|
+
|
|
117
86
|
// 取消缩进效果
|
|
118
87
|
.poetry, .okr, .timeline, li, .article-footer
|
|
119
88
|
p:not([class])
|
|
@@ -124,6 +93,39 @@
|
|
|
124
93
|
border-radius: $border-image-l
|
|
125
94
|
|
|
126
95
|
|
|
96
|
+
.l_body[type=story] .md-text.content>blockquote, .md-text.content .tag-plugin.blockquote
|
|
97
|
+
text-align: center
|
|
98
|
+
--inset: calc(var(--fsp) * 2)
|
|
99
|
+
margin-left: var(--inset)
|
|
100
|
+
margin-right: var(--inset)
|
|
101
|
+
background: var(--block)
|
|
102
|
+
padding: 1rem 2rem
|
|
103
|
+
border-radius: $border-card
|
|
104
|
+
&:before,&:after
|
|
105
|
+
position: absolute
|
|
106
|
+
font-size: 2rem
|
|
107
|
+
background-color: hsla($color-theme, 0.25)
|
|
108
|
+
top: -0.3em
|
|
109
|
+
width: 1em
|
|
110
|
+
height: 1em
|
|
111
|
+
content: ''
|
|
112
|
+
opacity 1
|
|
113
|
+
trans1 all
|
|
114
|
+
&:before
|
|
115
|
+
left: -0.3em
|
|
116
|
+
svg-mask-icon($iQuoteLeft)
|
|
117
|
+
&:after
|
|
118
|
+
right: -0.3em
|
|
119
|
+
svg-mask-icon($iQuoteRight)
|
|
120
|
+
p:not([class])
|
|
121
|
+
color: var(--text-p2)
|
|
122
|
+
font-size: $fs-body
|
|
123
|
+
text-indent: 2em
|
|
124
|
+
&:hover
|
|
125
|
+
&:before,&:after
|
|
126
|
+
background-color: hsla($color-theme, 0.5)
|
|
127
|
+
|
|
128
|
+
|
|
127
129
|
.l_body[type=story] .article.banner .content .bottom.only-title
|
|
128
130
|
justify-content: center
|
|
129
131
|
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
width: 100%
|
|
10
10
|
min-width: 200px
|
|
11
11
|
span
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
border-
|
|
16
|
-
|
|
12
|
+
padding: .25rem .5rem
|
|
13
|
+
margin: auto .5rem
|
|
14
|
+
line-height: 1
|
|
15
|
+
border-radius: 4px
|
|
16
|
+
background: hsla($color-theme, 0.2)
|
|
17
|
+
color: $color-theme
|
|
17
18
|
font-family: $ff-code
|
|
18
19
|
font-size: $fs-13
|
|
19
20
|
font-weight: 700
|
|
@@ -25,11 +26,14 @@
|
|
|
25
26
|
color: var(--text-p2)
|
|
26
27
|
line-height: 3
|
|
27
28
|
text-indent: 1rem
|
|
29
|
+
span+input.copy-area
|
|
30
|
+
text-indent: 0
|
|
28
31
|
button.copy-btn
|
|
29
|
-
margin: 2px
|
|
32
|
+
margin: 2px 2px 2px 0
|
|
30
33
|
border-radius: 'calc(%s - 2px)' % $border-bar
|
|
31
34
|
display: inline-block
|
|
32
|
-
background:
|
|
35
|
+
background: var(--block)
|
|
36
|
+
trans1 all
|
|
33
37
|
line-height: 0
|
|
34
38
|
font-size: 1rem
|
|
35
39
|
padding: 0 .75rem
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
.tag-plugin.navbar
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
display: inline-flex
|
|
3
|
+
background: var(--card)
|
|
4
|
+
border-radius: $border-button
|
|
5
|
+
z-index inherit
|
|
6
|
+
box-shadow: 0 0 8px hsla(black, 0.04)
|
|
7
|
+
a
|
|
8
|
+
box-sizing: border-box
|
|
9
|
+
padding: .25rem 1rem
|
|
10
|
+
margin: 2px
|
|
11
|
+
color: inherit
|
|
12
|
+
border-radius: 'calc(%s - 1px)' % $border-button
|
|
13
|
+
trans1 all
|
|
14
|
+
&+a
|
|
15
|
+
margin-left: 0
|
|
16
|
+
&.active
|
|
17
|
+
background: var(--block)
|
|
18
|
+
&:hover
|
|
19
|
+
background: var(--block)
|