hexo-theme-stellar 1.19.0 → 1.21.0

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.
Files changed (89) hide show
  1. package/README.md +3 -3
  2. package/_config.yml +49 -22
  3. package/languages/zh-CN.yml +1 -1
  4. package/languages/zh-TW.yml +1 -1
  5. package/layout/404.ejs +1 -1
  6. package/layout/_partial/cover/wiki_cover.ejs +10 -16
  7. package/layout/_partial/head.ejs +3 -3
  8. package/layout/_partial/main/article/article_footer.ejs +86 -54
  9. package/layout/_partial/main/article/read_next.ejs +17 -12
  10. package/layout/_partial/main/navbar/breadcrumb.ejs +55 -17
  11. package/layout/_partial/main/navbar/list_post.ejs +6 -4
  12. package/layout/_partial/main/navbar/list_wiki.ejs +4 -3
  13. package/layout/_partial/main/post_list/post_card.ejs +1 -1
  14. package/layout/_partial/main/post_list/wiki_card.ejs +6 -11
  15. package/layout/_partial/{main/article/ai_abstract.ejs → plugins/ai/tianli_gpt.ejs} +3 -2
  16. package/layout/_partial/plugins/comments/beaudar/script.ejs +1 -1
  17. package/layout/_partial/plugins/comments/giscus/script.ejs +1 -1
  18. package/layout/_partial/plugins/comments/layout.ejs +2 -2
  19. package/layout/_partial/plugins/comments/utterances/script.ejs +1 -1
  20. package/layout/_partial/sidebar/header.ejs +1 -1
  21. package/layout/_partial/sidebar/index.ejs +4 -4
  22. package/layout/_partial/widgets/ghissues.ejs +1 -1
  23. package/layout/_partial/widgets/ghrepo.ejs +1 -1
  24. package/layout/_partial/widgets/ghuser.ejs +1 -1
  25. package/layout/_partial/widgets/recent.ejs +3 -3
  26. package/layout/_partial/widgets/related.ejs +13 -21
  27. package/layout/_partial/widgets/toc.ejs +20 -12
  28. package/layout/index.ejs +13 -11
  29. package/layout/mermaid.ejs +8 -4
  30. package/layout/page.ejs +3 -0
  31. package/layout/post.ejs +1 -1
  32. package/layout/wiki.ejs +4 -1
  33. package/package.json +1 -1
  34. package/scripts/events/lib/doc_tree.js +142 -97
  35. package/scripts/filters/index.js +4 -1
  36. package/scripts/helpers/category_color.js +18 -5
  37. package/scripts/tags/index.js +5 -3
  38. package/scripts/tags/inline-labels.js +2 -2
  39. package/scripts/tags/lib/banner.js +68 -0
  40. package/scripts/tags/lib/{ablock.js → box.js} +4 -4
  41. package/scripts/tags/lib/checkbox.js +1 -1
  42. package/scripts/tags/lib/folders.js +1 -1
  43. package/scripts/tags/lib/folding.js +1 -1
  44. package/scripts/tags/lib/gallery.js +51 -0
  45. package/scripts/tags/lib/hashtag.js +36 -0
  46. package/scripts/tags/lib/image.js +5 -1
  47. package/scripts/tags/lib/mark.js +1 -1
  48. package/scripts/tags/lib/navbar.js +15 -34
  49. package/scripts/tags/lib/note.js +1 -1
  50. package/scripts/tags/lib/okr.js +140 -0
  51. package/scripts/tags/lib/swiper.js +1 -1
  52. package/scripts/tags/lib/timeline.js +3 -3
  53. package/scripts/tags/lib/toc.js +1 -1
  54. package/source/css/_common/highlight.styl +3 -0
  55. package/source/css/_custom.styl +2 -2
  56. package/source/css/_defines/theme.styl +0 -1
  57. package/source/css/_layout/list.styl +12 -4
  58. package/source/css/_layout/md.styl +11 -8
  59. package/source/css/_layout/partial/bread-nav.styl +32 -0
  60. package/source/css/_layout/partial/cover.styl +2 -0
  61. package/source/css/_layout/partial/paginator.styl +9 -5
  62. package/source/css/_layout/tag-plugins/banner.styl +106 -0
  63. package/source/css/_layout/tag-plugins/common.styl +33 -39
  64. package/source/css/_layout/tag-plugins/folding.styl +1 -1
  65. package/source/css/_layout/tag-plugins/frame.styl +1 -1
  66. package/source/css/_layout/tag-plugins/gallery.styl +46 -0
  67. package/source/css/_layout/tag-plugins/grid.styl +0 -9
  68. package/source/css/_layout/tag-plugins/hashtag.styl +17 -0
  69. package/source/css/_layout/tag-plugins/mark.styl +2 -5
  70. package/source/css/_layout/tag-plugins/note.styl +2 -1
  71. package/source/css/_layout/tag-plugins/okr.styl +106 -0
  72. package/source/css/_layout/tag-plugins/timeline.styl +14 -1
  73. package/source/css/_layout/widgets/ghuser.styl +5 -6
  74. package/source/css/_plugins/copycode.styl +17 -6
  75. package/source/css/_plugins/fancybox.styl +4 -0
  76. package/source/css/_plugins/index.styl +2 -0
  77. package/source/css/_plugins/mermaid.styl +125 -10
  78. package/source/css/{_layout/partial/ai_abstract.styl → _plugins/tianli_gpt.styl} +2 -2
  79. package/source/js/main.js +25 -3
  80. package/source/js/plugins/copycode.js +1 -7
  81. package/source/js/plugins/fcircle.js +3 -3
  82. package/source/js/plugins/friends.js +3 -3
  83. package/source/js/plugins/linkcard.js +1 -1
  84. package/source/js/plugins/memos.js +133 -0
  85. package/source/js/plugins/sites.js +4 -4
  86. package/source/js/plugins/timeline.js +3 -3
  87. package/source/js/plugins/weibo.js +3 -3
  88. package/scripts/tags/lib/tag.js +0 -35
  89. package/source/css/_layout/tag-plugins/tag.styl +0 -13
@@ -7,157 +7,202 @@
7
7
  class WikiPage {
8
8
  constructor(page) {
9
9
  this.id = page._id
10
+ this.wiki = page.wiki
10
11
  this.title = page.title
12
+ this.seo_title = page.seo_title
11
13
  this.path = page.path
14
+ this.path_key = page.path.replace('.html', '')
12
15
  this.layout = page.layout
13
- this.seo_title = page.seo_title
14
- this.wiki = page.wiki
15
- this.order = page.order || 0
16
16
  this.updated = page.updated
17
17
  }
18
18
  }
19
19
 
20
- function createWikiObject(ctx) {
21
- const wiki = { projects:{} }
22
- const { projects } = ctx.locals.get('data')
23
- if (projects) {
24
- Object.assign(wiki.projects, projects)
20
+ function getWikiObject(ctx) {
21
+ var wiki = { tree:{} }
22
+ const data = ctx.locals.get('data')
23
+ var list = []
24
+ for (let key of Object.keys(data)) {
25
+ if (key.includes('wiki/') && key.length > 5) {
26
+ let newKey = key.replace('wiki/', '')
27
+ let obj = data[key]
28
+ if ((typeof obj.tags == 'string') && obj.tags.constructor == String) {
29
+ obj.tags = [obj.tags]
30
+ }
31
+ if ((typeof obj.toc == 'object') && obj.toc.constructor == Array) {
32
+ obj.toc = { '': obj.toc }
33
+ }
34
+ obj.id = newKey
35
+ if (obj.sort == null) {
36
+ obj.sort = 0
37
+ }
38
+ if (obj.path?.startsWith('/')) {
39
+ obj.path = obj.path.substring(1)
40
+ }
41
+ if (obj.path?.endsWith('/') == false) {
42
+ obj.path = obj.path + '/'
43
+ }
44
+ list.push(obj)
45
+ }
46
+ }
47
+ list = list.sort((p1, p2) => p2.sort - p1.sort)
48
+ for (let item of list) {
49
+ wiki.tree[item.id] = item
25
50
  }
26
51
  return wiki
27
52
  }
28
53
 
29
54
  module.exports = ctx => {
30
55
  // wiki 配置
31
- var wiki = createWikiObject(ctx)
56
+ var wiki = getWikiObject(ctx)
32
57
  const pages = ctx.locals.get('pages')
33
58
  // wiki 所有页面
34
- const wiki_pages = pages.filter(p => (p.layout === 'wiki') && (p.wiki != undefined) && (p.wiki.length > 0)).map(p => new WikiPage(p))
35
-
59
+ const wiki_pages = pages.filter(p => (p.layout === 'wiki')).map(p => new WikiPage(p))
60
+ const wiki_list = Object.keys(wiki.tree)
61
+ // 上架的项目列表
62
+ wiki.shelf = ctx.locals.get('data').wiki
63
+
36
64
  // 数据整合:项目标签
37
65
  var all_tag_name = []
38
- for (let id of Object.keys(wiki.projects)) {
39
- let proj = wiki.projects[id]
40
- let tags = proj.tags
66
+ for (let id of wiki_list) {
67
+ let item = wiki.tree[id]
68
+ let tags = item.tags
41
69
  if (tags) {
42
- if ((typeof tags == 'string') && tags.constructor == String) {
43
- if (all_tag_name.includes(tags) === false) {
44
- all_tag_name.push(tags)
70
+ tags.forEach((tag, i) => {
71
+ if (all_tag_name.includes(tag) === false) {
72
+ all_tag_name.push(tag)
45
73
  }
46
- // 类型转换
47
- tags = [tags]
48
- } else if ((typeof tags == 'object') && tags.constructor == Array) {
49
- tags.forEach((tag, i) => {
50
- if (all_tag_name.includes(tag) === false) {
51
- all_tag_name.push(tag)
52
- }
53
- })
54
- }
55
- wiki.projects[id].tags = tags
74
+ })
75
+ wiki.tree[id].tags = tags
56
76
  }
57
77
  }
58
- // 补充未分组的项目
59
- const projs = Object.keys(wiki.projects)
60
- wiki_pages.forEach((p, i) => {
61
- if (projs.includes(p.wiki) == false) {
62
- if (wiki.projects[p.wiki] == undefined) {
63
- wiki.projects[p.wiki] = {}
64
- wiki.projects[p.wiki].pages = []
65
- }
66
- var proj = wiki.projects[p.wiki]
67
- if (proj.description == undefined) {
68
- proj.description = p.description
69
- }
70
- wiki.projects[p.wiki].pages.push(p)
71
- }
72
- })
78
+
73
79
  // 补充项目名称和首页
74
- for (let id of Object.keys(wiki.projects)) {
75
- let proj = wiki.projects[id]
76
- proj.id = id
77
- if (proj.title == undefined || proj.title.length === 0) {
78
- proj.title = id
80
+ for (let id of wiki_list) {
81
+ let item = wiki.tree[id]
82
+ item.id = id
83
+ if (item.title == undefined || item.title.length === 0) {
84
+ item.title = id
79
85
  }
80
- if (proj.name == undefined || proj.name.length == 0) {
81
- proj.name = id
86
+ if (item.name == undefined || item.name.length == 0) {
87
+ item.name = id
82
88
  }
83
89
  }
84
- // 补充 order
85
- wiki_pages.forEach((p, i) => {
86
- if (p.order == undefined) {
87
- p.order = 0
88
- }
89
- })
90
-
90
+
91
91
  // 数据整合:每个项目的子页面
92
- for (let id of Object.keys(wiki.projects)) {
93
- let proj = wiki.projects[id]
94
- let proj_pages = wiki_pages.filter(p => p.wiki === id).sort((p1, p2) => p1.order < p2.order ? -1 : 1)
95
- if (!proj_pages || proj_pages.length == 0) {
92
+ for (let i = 0; i < wiki_list.length; i++) {
93
+ let id = wiki_list[i];
94
+ let item = wiki.tree[id]
95
+ let sub_pages = wiki_pages.filter(p => p.wiki === id)
96
+ if (!sub_pages || sub_pages.length == 0) {
97
+ wiki_list.splice(i, 1)
98
+ delete wiki.tree[id]
96
99
  continue
97
100
  }
98
- proj.homepage = proj_pages[0]
99
- proj.homepage.is_homepage = true
100
- // 内页按 section 分组
101
- var section_configs = []
102
- if (proj.sections) {
103
- for (let t of Object.keys(proj.sections)) {
104
- let range = proj.sections[t]
105
- if (range.length > 1) {
106
- section_configs.push({
107
- title: t,
108
- from: range[0],
109
- to: range[1]
110
- })
101
+
102
+ // 首页
103
+ // 未特别指定首页时,获取TOC第一页作为首页
104
+ if (item.homepage == null && item.toc != null) {
105
+ for (let id of Object.keys(item.toc)) {
106
+ const sec = item.toc[id]
107
+ for (let key of sec) {
108
+ let hs = sub_pages.filter(p => p.path_key == item.path + key)
109
+ if (hs.length > 0) {
110
+ item.homepage = hs[0]
111
+ break
112
+ }
113
+ }
114
+ if (item.homepage != null) {
115
+ break
111
116
  }
112
117
  }
113
118
  }
119
+ if (item.homepage == null) {
120
+ item.homepage = sub_pages[0]
121
+ }
122
+ item.homepage.is_homepage = true
123
+ // 内页分组
114
124
  var sections = []
115
- section_configs.forEach((sec, i) => {
116
- const sec_pages = proj_pages.filter( p => p.order >= sec.from && p.order <= sec.to )
117
- if (sec_pages && sec_pages.length > 0) {
125
+ var others = sub_pages
126
+ if (item.toc) {
127
+ // 根据配置设置顺序
128
+ for (let title of Object.keys(item.toc)) {
129
+ var sec = { title: title, pages: []}
130
+ for (let key of item.toc[title]) {
131
+ sec.pages = sec.pages.concat(sub_pages.filter(p => p.path_key == item.path + key))
132
+ others = others.filter(p => p.path_key != item.path + key)
133
+ }
134
+ sections.push(sec)
135
+ }
136
+ if (others.length > 0 && others.filter(p => p.title?.length > 0).length > 0) {
118
137
  sections.push({
119
- title: sec.title,
120
- pages: sec_pages
138
+ title: '...',
139
+ pages: others.sort((p1, p2) => p1.path - p2.path)
121
140
  })
122
141
  }
123
- })
124
- proj.sections = sections
125
- proj.pages = proj_pages
142
+ } else {
143
+ // 自动设置顺序
144
+ sections.push({
145
+ pages: sub_pages.sort((p1, p2) => p1.path - p2.path)
146
+ })
147
+ }
148
+
149
+ // page number
150
+ var page_number = 0
151
+ for (let sec of sections) {
152
+ for (let page of sec.pages) {
153
+ page.page_number = page_number++
154
+ }
155
+ }
156
+ item.sections = sections
157
+ item.pages = sub_pages
126
158
  }
127
-
159
+
128
160
  // 全站所有的项目标签
129
161
  var all_tags = {}
130
162
  all_tag_name.forEach((tag_name, i) => {
131
- var projs = []
132
- for (let id of Object.keys(wiki.projects)) {
133
- let proj = wiki.projects[id]
134
- if (proj.tags && proj.tags.includes(tag_name) === true && projs.includes(tag_name) === false) {
135
- projs.push(proj.id)
163
+ var items = []
164
+ for (let id of wiki_list) {
165
+ let item = wiki.tree[id]
166
+ // 过滤掉找不到页面的项目
167
+ if (item.homepage == null) {
168
+ continue
169
+ }
170
+ // 过滤掉未上架的项目
171
+ if (!wiki.shelf.includes(item.id)) {
172
+ continue
173
+ }
174
+ if (item.tags && item.tags.includes(tag_name) === true && items.includes(tag_name) === false) {
175
+ items.push(item.id)
136
176
  }
137
177
  }
138
178
  all_tags[tag_name] = {
139
179
  name: tag_name,
140
180
  path: (ctx.config.wiki_dir || 'wiki') + '/tags/' + tag_name + '/index.html',
141
- items: projs
181
+ items: items
142
182
  }
143
183
  })
144
184
 
145
185
  // 关联相似项目
146
- for (let id of Object.keys(wiki.projects)) {
147
- let proj = wiki.projects[id]
148
- if (proj.tags) {
149
- var related = []
150
- proj.tags.forEach((tag_name, i) => {
151
- let tagObj = all_tags[tag_name]
152
- related = related.concat(tagObj.items)
153
- related = [...new Set(related)]
186
+ for (let id of wiki_list) {
187
+ let item = wiki.tree[id]
188
+ if (item.tags) {
189
+ var relatedItems = []
190
+ item.tags.forEach((tag_name, i) => {
191
+ let relatedOtherItems = all_tags[tag_name].items.filter(name => name != item.id)
192
+ if (relatedOtherItems.length > 0) {
193
+ relatedItems.push({
194
+ name: tag_name,
195
+ items: relatedOtherItems
196
+ })
197
+ }
154
198
  })
155
- proj.related = related
199
+ item.relatedItems = relatedItems
156
200
  }
157
201
  }
158
202
 
159
203
  wiki.all_tags = all_tags
160
204
  wiki.all_pages = wiki_pages
205
+ wiki.shelf = ctx.locals.get('data').wiki
161
206
  ctx.theme.config.wiki = wiki
162
207
 
163
208
  }
@@ -5,7 +5,10 @@ hexo.extend.filter.register('after_render:html', require('./lib/img_onerror').pr
5
5
 
6
6
  function change_image(data) {
7
7
  if (this.theme.config.tag_plugins.image.parse_markdown) {
8
- data.content = data.content.replace(/!\[([^\]]*)]\(([^(]+)\)/g, '{% image $2 $1 %}');
8
+ data.content = data.content.replace(
9
+ /!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/g,
10
+ '{% image $2 $3 %}'
11
+ );
9
12
  }
10
13
  return data;
11
14
  }
@@ -1,9 +1,22 @@
1
1
  'use strict';
2
2
 
3
3
  hexo.extend.helper.register('category_color', function(cat){
4
- const cfg = hexo.theme.config;
5
- if (cfg.article.category_color && cfg.article.category_color[cat]) {
6
- return ' style="color:' + cfg.article.category_color[cat] + '"';
4
+ const { config } = hexo.theme
5
+ const color = config.article.category_color[cat]
6
+ if (color) {
7
+ var textColor = color
8
+ if (color.startsWith('#')) {
9
+ textColor = color
10
+ } else {
11
+ textColor = '#' + color
12
+ }
13
+ var bgColor = textColor
14
+ if (textColor.length == (1+3)) { // #fff
15
+ bgColor += '2'
16
+ } else if (textColor.length == (1+6)) { // #ffffff
17
+ bgColor += '20'
18
+ }
19
+ return ` style="--text-p3:${textColor};--theme-block:${bgColor}"`;
7
20
  }
8
- return '';
9
- });
21
+ return ''
22
+ })
@@ -4,12 +4,14 @@
4
4
 
5
5
  // container
6
6
  hexo.extend.tag.register('tabs', require('./lib/tabs')(hexo), true)
7
- hexo.extend.tag.register('ablock', require('./lib/ablock')(hexo), true)
7
+ hexo.extend.tag.register('box', require('./lib/box')(hexo), true)
8
8
  hexo.extend.tag.register('about', require('./lib/about')(hexo), true)
9
9
  hexo.extend.tag.register('folding', require('./lib/folding')(hexo), true)
10
10
  hexo.extend.tag.register('folders', require('./lib/folders')(hexo), true)
11
11
  hexo.extend.tag.register('grid', require('./lib/grid')(hexo), true)
12
12
  hexo.extend.tag.register('swiper', require('./lib/swiper')(hexo), true)
13
+ hexo.extend.tag.register('gallery', require('./lib/gallery')(hexo), {ends: true})
14
+ hexo.extend.tag.register('banner', require('./lib/banner')(hexo), true)
13
15
 
14
16
  // data
15
17
  hexo.extend.tag.register('users', require('./lib/friends')(hexo))
@@ -32,6 +34,6 @@ hexo.extend.tag.register('navbar', require('./lib/navbar')(hexo))
32
34
  hexo.extend.tag.register('note', require('./lib/note')(hexo))
33
35
  hexo.extend.tag.register('poetry', require('./lib/poetry')(hexo), true)
34
36
  hexo.extend.tag.register('quot', require('./lib/quot')(hexo))
35
- hexo.extend.tag.register('tag', require('./lib/tag')(hexo))
36
-
37
+ hexo.extend.tag.register('hashtag', require('./lib/hashtag')(hexo))
38
+ hexo.extend.tag.register('okr', require('./lib/okr')(hexo), {ends: true})
37
39
  // others
@@ -29,7 +29,7 @@ hexo.extend.tag.register('psw', function(args) {
29
29
  hexo.extend.tag.register('sup', function(args) {
30
30
  args = hexo.args.map(args, ['color'], ['text'])
31
31
  var el = ''
32
- el += '<sup class="tag-plugin sup"' + ' ' + hexo.args.joinTags(args, ['color']).join(' ') + '>'
32
+ el += '<sup class="tag-plugin colorful sup"' + ' ' + hexo.args.joinTags(args, ['color']).join(' ') + '>'
33
33
  el += args.text
34
34
  el += '</sup>'
35
35
  return el
@@ -37,7 +37,7 @@ hexo.extend.tag.register('sup', function(args) {
37
37
  hexo.extend.tag.register('sub', function(args) {
38
38
  args = hexo.args.map(args, ['color'], ['text'])
39
39
  var el = ''
40
- el += '<sub class="tag-plugin sub"' + ' ' + hexo.args.joinTags(args, ['color']).join(' ') + '>'
40
+ el += '<sub class="tag-plugin colorful sub"' + ' ' + hexo.args.joinTags(args, ['color']).join(' ') + '>'
41
41
  el += args.text
42
42
  el += '</sub>'
43
43
  return el
@@ -0,0 +1,68 @@
1
+ /**
2
+ * banner.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
+ *
5
+ * {% banner title [subtitle] [bg:src] [avatar:src] [link] %}
6
+ * {% navbar xxx %}
7
+ * {% endbanner %}
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ module.exports = ctx => function(args, content) {
13
+ const url_for = require('hexo-util').url_for.bind(ctx)
14
+ args = ctx.args.map(args, ['bg', 'avatar', 'link'], ['title', 'subtitle'])
15
+ var el = ''
16
+ el += `<div class="tag-plugin banner">`
17
+ // bg
18
+ el += `<img class="bg" src="${args.bg ? args.bg : ctx.theme.config.default.banner}">`
19
+ // content
20
+ el += `<div class="content">`
21
+ // content.top
22
+ el += `<div class="top">`
23
+ // content.top.back
24
+ if (args.link?.length > 0) {
25
+ el += `<div></div>`
26
+ } else {
27
+ el += `
28
+ <button class="back cap" onclick="window.history.back()">
29
+ <svg aria-hidden="true" viewBox="0 0 16 16" fill="currentColor"><path fill-rule="evenodd" d="M7.78 12.53a.75.75 0 01-1.06 0L2.47 8.28a.75.75 0 010-1.06l4.25-4.25a.75.75 0 011.06 1.06L4.81 7h7.44a.75.75 0 010 1.5H4.81l2.97 2.97a.75.75 0 010 1.06z"></path></svg>
30
+ </button>
31
+ `
32
+ }
33
+
34
+ // content.top.menus
35
+ const rows = content.split('\n').filter(item => item.trim().length > 0)
36
+ for (let row of rows) {
37
+ if (row.includes('tag-plugin navbar')) {
38
+ el += row
39
+ break
40
+ }
41
+ }
42
+ el += `</div>`
43
+ // content.bottom
44
+ el += `<div class="bottom">`
45
+ // content.bottom.avatar
46
+ if (args.avatar?.length > 0) {
47
+ el += `<img class="avatar" src="${args.avatar}">`
48
+ }
49
+ // content.bottom.text-area
50
+ if (args.title?.length > 0 || args.subtitle?.length > 0) {
51
+ el += `<div class="text-area">`
52
+ if (args.title?.length > 0) {
53
+ el += `<div class="text title">${args.title}</div>`
54
+ }
55
+ if (args.subtitle?.length > 0) {
56
+ el += `<div class="text subtitle">${args.subtitle}</div>`
57
+ }
58
+ el += `</div>`
59
+ }
60
+ el += `</div>`
61
+ el += `</div>`
62
+ // link
63
+ if (args.link?.length > 0) {
64
+ el += `<a class="banner-link" href="${args.link}"></a>`
65
+ }
66
+ el += `</div>`
67
+ return el
68
+ }
@@ -1,10 +1,10 @@
1
1
  /**
2
- * ablock.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
2
+ * box.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
3
3
  * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
4
  *
5
- * {% ablock [color:color] [child:codeblock/tabs] title %}
5
+ * {% box [color:color] [child:codeblock/tabs] title %}
6
6
  * body
7
- * {% endablock %}
7
+ * {% endbox %}
8
8
  */
9
9
 
10
10
  'use strict';
@@ -17,7 +17,7 @@ module.exports = ctx => function(args, content) {
17
17
  }
18
18
  var el = ''
19
19
  // header
20
- el += '<div class="tag-plugin note"'
20
+ el += '<div class="tag-plugin colorful note"'
21
21
  el += ' ' + ctx.args.joinTags(args, ['color', 'child']).join(' ')
22
22
  el += '>'
23
23
  // title
@@ -13,7 +13,7 @@ module.exports = (ctx, type) => function(args) {
13
13
  args = ctx.args.map(args, ['color', 'checked', 'symbol'], ['text'])
14
14
  var el = ''
15
15
  // div
16
- el += '<div class="tag-plugin checkbox"'
16
+ el += '<div class="tag-plugin colorful checkbox"'
17
17
  el += ' ' + ctx.args.joinTags(args, ['color', 'symbol']).join(' ')
18
18
  el += '>'
19
19
  // input
@@ -15,7 +15,7 @@
15
15
  module.exports = ctx => function(args, content) {
16
16
  args = ctx.args.map(args, ['color'])
17
17
  var el = ''
18
- el += '<div class="tag-plugin folders"'
18
+ el += '<div class="tag-plugin colorful folders"'
19
19
  el += ' ' + ctx.args.joinTags(args, ['color']).join(' ')
20
20
  el += '>'
21
21
 
@@ -13,7 +13,7 @@ module.exports = ctx => function(args, content) {
13
13
  args = ctx.args.map(args, ['color', 'child', 'open'], ['title'])
14
14
  var el = ''
15
15
  // header
16
- el += '<details class="tag-plugin folding"'
16
+ el += '<details class="tag-plugin colorful folding"'
17
17
  el += ' ' + ctx.args.joinTags(args, ['color', 'child']).join(' ')
18
18
  if (args.open && args.open == 'true') {
19
19
  el += ' open'
@@ -0,0 +1,51 @@
1
+ /**
2
+ * gallery.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
+ *
5
+ * {% gallery size:small/medium/large %}
6
+ * /xxx.png
7
+ * /xxx.png
8
+ * /xxx.png
9
+ * /xxx.png
10
+ * {% endgallery %}
11
+ */
12
+
13
+ 'use strict'
14
+
15
+ function img(src, alt) {
16
+ let img = ''
17
+ img += `<img src="${src}"`
18
+ if (alt?.length > 0) {
19
+ img += ` alt="${alt}"`
20
+ }
21
+ img += `/>`
22
+ // cap
23
+ img += `<div class="image-meta">`
24
+ if (alt?.length > 0) {
25
+ img += `<span class="image-caption">${alt}</span>`
26
+ }
27
+ img += `</div>`
28
+ return img
29
+ }
30
+
31
+ module.exports = ctx => function(args, content) {
32
+ args = ctx.args.map(args, ['size'])
33
+ var el = ''
34
+ el += '<div class="tag-plugin gallery"'
35
+ el += ' ' + ctx.args.joinTags(args, ['size']).join(' ')
36
+ el += '>'
37
+ const rows = content.split(/<!--\s*row(.*?)\s*-->/g).filter(item => item.trim().length > 0)
38
+ for (let row of rows) {
39
+ const img_mds = row.split('\n').filter(item => item.trim().length > 0)
40
+ for (let md of img_mds) {
41
+ const matches = md.match(/\!\[(.*?)\]\((.*?)\)/i)
42
+ if (matches?.length > 2) {
43
+ let alt = matches[1]
44
+ let src = matches[2]
45
+ el += `<div class="cell">${img(src, alt)}</div>`
46
+ }
47
+ }
48
+ }
49
+ el += '</div>'
50
+ return el
51
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * hashtag.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
+ *
5
+ * {% hashtag text href [color:color] %}
6
+ *
7
+ */
8
+
9
+ 'use strict'
10
+
11
+ const tag_colors = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple']
12
+ var tag_index = 0
13
+
14
+ module.exports = ctx => function(args) {
15
+ args = ctx.args.map(args, ['color'], ['text', 'href'])
16
+ if (args.color == null) {
17
+ const default_color = ctx.theme.config.tag_plugins.hashtag?.default_color
18
+ if (default_color) {
19
+ args.color = default_color
20
+ } else {
21
+ args.color = tag_colors[tag_index]
22
+ tag_index += 1
23
+ if (tag_index >= tag_colors.length) {
24
+ tag_index = 0
25
+ }
26
+ }
27
+ }
28
+ var el = ''
29
+ el += '<a class="tag-plugin colorful hashtag"'
30
+ el += ' ' + ctx.args.joinTags(args, ['color', 'href']).join(' ')
31
+ el += '>'
32
+ el += '<svg t="1701408144765" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4228" width="200" height="200"><path d="M426.6 64.8c34.8 5.8 58.4 38.8 52.6 73.6l-19.6 117.6h190.2l23-138.6c5.8-34.8 38.8-58.4 73.6-52.6s58.4 38.8 52.6 73.6l-19.4 117.6H896c35.4 0 64 28.6 64 64s-28.6 64-64 64h-137.8l-42.6 256H832c35.4 0 64 28.6 64 64s-28.6 64-64 64h-137.8l-23 138.6c-5.8 34.8-38.8 58.4-73.6 52.6s-58.4-38.8-52.6-73.6l19.6-117.4h-190.4l-23 138.6c-5.8 34.8-38.8 58.4-73.6 52.6s-58.4-38.8-52.6-73.6l19.4-117.8H128c-35.4 0-64-28.6-64-64s28.6-64 64-64h137.8l42.6-256H192c-35.4 0-64-28.6-64-64s28.6-64 64-64h137.8l23-138.6c5.8-34.8 38.8-58.4 73.6-52.6z m11.6 319.2l-42.6 256h190.2l42.6-256h-190.2z" p-id="4229"></path></svg>'
33
+ el += '<span>' + args.text + '</span>'
34
+ el += '</a>'
35
+ return el
36
+ }
@@ -71,7 +71,11 @@ module.exports = ctx => function(args) {
71
71
  if (args.download == 'true') {
72
72
  href = args.src
73
73
  }
74
- el += '<a class="image-download blur" style="opacity:0" target="_blank" download="' + args.alt + 'href="' + href + '"><svg class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3734"><path d="M561.00682908 685.55838913a111.03077546 111.03077546 0 0 1-106.8895062 0L256.23182837 487.72885783a55.96309219 55.96309219 0 0 1 79.13181253-79.18777574L450.70357448 523.88101491V181.55477937a55.96309219 55.96309219 0 0 1 111.92618438 0v344.06109173l117.07478902-117.07478901a55.96309219 55.96309219 0 0 1 79.13181252 79.18777574zM282.81429711 797.1487951h447.70473912a55.96309219 55.96309219 0 0 1 0 111.92618438H282.81429711a55.96309219 55.96309219 0 0 1 0-111.92618438z" p-id="3735"></path></svg></a>'
74
+ let download = ''
75
+ if (args.alt) {
76
+ download = ' download="' + args.alt + '"'
77
+ }
78
+ el += '<a class="image-download blur" style="opacity:0" target="_blank"' + download + ' href="' + href + '"><svg class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3734"><path d="M561.00682908 685.55838913a111.03077546 111.03077546 0 0 1-106.8895062 0L256.23182837 487.72885783a55.96309219 55.96309219 0 0 1 79.13181253-79.18777574L450.70357448 523.88101491V181.55477937a55.96309219 55.96309219 0 0 1 111.92618438 0v344.06109173l117.07478902-117.07478901a55.96309219 55.96309219 0 0 1 79.13181252 79.18777574zM282.81429711 797.1487951h447.70473912a55.96309219 55.96309219 0 0 1 0 111.92618438H282.81429711a55.96309219 55.96309219 0 0 1 0-111.92618438z" p-id="3735"></path></svg></a>'
75
79
  }
76
80
  el += '</div>'
77
81
 
@@ -14,7 +14,7 @@ module.exports = ctx => function(args) {
14
14
  args.color = ctx.theme.config.tag_plugins.mark.default_color
15
15
  }
16
16
  var el = ''
17
- el += '<mark class="tag-plugin mark"'
17
+ el += '<mark class="tag-plugin colorful mark"'
18
18
  el += ' ' + ctx.args.joinTags(args, ['color']).join(' ')
19
19
  el += '>'
20
20
  el += args.text