hexo-theme-volantis 5.8.1 → 6.0.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.
- package/CHANGELOG.md +3 -44
- package/_cdn.yml +449 -0
- package/_config.yml +155 -157
- package/languages/en.yml +9 -10
- package/languages/zh-CN.yml +11 -15
- package/languages/zh-TW.yml +10 -11
- package/layout/_meta/category.ejs +10 -5
- package/layout/_meta/counter.ejs +14 -17
- package/layout/_meta/tags.ejs +3 -0
- package/layout/_meta/walinecount.ejs +1 -1
- package/layout/_partial/article.ejs +8 -3
- package/layout/_partial/cover.ejs +4 -4
- package/layout/_partial/footer.ejs +1 -1
- package/layout/_partial/head.ejs +7 -18
- package/layout/_partial/header.ejs +6 -6
- package/layout/_partial/post.ejs +3 -3
- package/layout/_partial/scripts/_ctrl.ejs +43 -2
- package/layout/_partial/scripts/config.ejs +69 -0
- package/layout/_partial/scripts/global.ejs +137 -60
- package/layout/_partial/scripts/index.ejs +16 -23
- package/layout/_plugins/_page_plugins/artitalk/index.ejs +1 -1
- package/layout/_plugins/_page_plugins/bbtalk/index.ejs +1 -1
- package/layout/_plugins/_page_plugins/fcircle/index.ejs +9 -8
- package/layout/_plugins/_page_plugins/katex/index.ejs +3 -3
- package/layout/_plugins/_page_plugins/mathjax/index.ejs +1 -1
- package/layout/_plugins/aplayer/layout.ejs +31 -23
- package/layout/_plugins/aplayer/script.ejs +93 -65
- package/layout/_plugins/comments/artalk/script.ejs +31 -40
- package/layout/_plugins/comments/discuss/script.ejs +1 -1
- package/layout/_plugins/comments/disqusjs/script.ejs +2 -2
- package/layout/_plugins/comments/gitalk/script.ejs +1 -1
- package/layout/_plugins/comments/twikoo/script.ejs +1 -1
- package/layout/_plugins/comments/vssue/script.ejs +3 -3
- package/layout/_plugins/comments/waline/script.ejs +2 -2
- package/layout/_plugins/github-api/script.ejs +3 -3
- package/layout/_plugins/lazyload/script.ejs +1 -1
- package/layout/_plugins/nodewaves/script.ejs +1 -1
- package/layout/_plugins/pace/script.ejs +15 -0
- package/layout/_plugins/parallax/script.ejs +1 -1
- package/layout/_plugins/pjax/index.ejs +66 -11
- package/layout/_plugins/pjax/pdata.ejs +5 -5
- package/layout/_plugins/preload/script.ejs +2 -2
- package/layout/_plugins/rightmenus/layout.ejs +4 -4
- package/layout/_plugins/scrollreveal/script.ejs +2 -2
- package/layout/_plugins/search/script.ejs +11 -8
- package/layout/_plugins/swiper/script.ejs +2 -2
- package/layout/{_partial/scripts/toc.ejs → _plugins/toc/script.ejs} +40 -36
- package/layout/_widget/webinfo.ejs +13 -14
- package/layout/friends.ejs +2 -2
- package/layout/layout.ejs +1 -15
- package/package.json +4 -4
- package/scripts/events/lib/cdn.js +206 -0
- package/scripts/events/lib/check-configuration.js +7 -7
- package/scripts/events/lib/check-environment.js +17 -17
- package/scripts/events/lib/config.js +0 -24
- package/scripts/events/lib/render-stylus.js +5 -5
- package/scripts/events/lib/stellar-tag-utils.js +2 -2
- package/scripts/filters/hexo-blog-encrypt-callback.js +44 -0
- package/scripts/filters/img.js +1 -1
- package/scripts/filters/replace.js +3 -3
- package/scripts/filters/z-lazyload.js +3 -5
- package/scripts/helpers/first-style.js +2 -2
- package/scripts/helpers/head/generate_seo.js +11 -9
- package/scripts/helpers/head/generate_title__keywords__description.js +19 -6
- package/scripts/helpers/related-posts.js +3 -3
- package/scripts/helpers/structured-data/lib/blogposting.js +1 -1
- package/scripts/helpers/structured-data/lib/breadcrumblist.js +1 -1
- package/scripts/helpers/structured-data/lib/config.js +1 -1
- package/scripts/helpers/structured-data/lib/website.js +1 -1
- package/scripts/helpers//346/226/207/347/253/240/346/216/250/350/215/220.js +184 -0
- package/scripts/tags/btn.js +2 -2
- package/scripts/tags/btns.js +3 -3
- package/scripts/tags/checkbox.js +6 -6
- package/scripts/tags/contributors.js +7 -7
- package/scripts/tags/dropmenu.js +8 -8
- package/scripts/tags/fancybox.js +6 -6
- package/scripts/tags/folding.js +5 -5
- package/scripts/tags/frame.js +3 -3
- package/scripts/tags/friends.js +8 -8
- package/scripts/tags/ghcard.js +7 -7
- package/scripts/tags/image.js +6 -6
- package/scripts/tags/inline-labels.js +6 -6
- package/scripts/tags/link.js +5 -5
- package/scripts/tags/md.js +4 -4
- package/scripts/tags/media.js +5 -5
- package/scripts/tags/note.js +12 -12
- package/scripts/tags/pandown.js +29 -29
- package/scripts/tags/site.js +4 -4
- package/scripts/tags/span.js +4 -4
- package/scripts/tags/table.js +2 -2
- package/scripts/tags/tabs.js +23 -23
- package/scripts/tags/timeline.js +5 -5
- package/source/css/_first/base_first.styl +1 -1
- package/source/css/_style/_layout/article.styl +43 -0
- package/source/css/_style/_layout/main.styl +1 -1
- package/source/css/_style/_layout/search.styl +206 -14
- package/source/css/_style/_plugins/index.styl +1 -3
- package/source/js/app.js +133 -160
- package/source/js/plugins/parallax.js +1 -1
- package/source/js/plugins/rightMenus.js +24 -20
- package/source/js/search/algolia.js +239 -0
- package/source/js/search/hexo.js +8 -2
- package/source/js/search/meilisearch.js +220 -0
- package/layout/_partial/scripts/_ctrl/cdnCtrl.ejs +0 -127
- package/layout/_partial/scripts/_ctrl/coverCtrl.ejs +0 -43
- package/layout/_plugins/analytics/LCCounter.ejs +0 -207
- package/layout/_plugins/pjax/animate.ejs +0 -31
- package/layout/_plugins/rightmenu/layout.ejs +0 -119
- package/scripts/helpers/revisioned.js +0 -167
- package/source/css/_style/_plugins/pjaxanimate.styl +0 -160
- package/source/js/plugins/rightMenu.js +0 -577
- /package/layout/{_partial/scripts/content-visibility-scroll-fix.ejs → _plugins/content-visibility/script.ejs} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
// https://github.com/D0n9X1n/hexo-blog-encrypt/blob/master/ReadMe.zh.md#关于-callback-函数
|
|
3
|
+
hexo.extend.filter.register('before_post_render', function (data) {
|
|
4
|
+
const tagEncryptPairs = [];
|
|
5
|
+
let password = data.password;
|
|
6
|
+
let tagUsed = false;
|
|
7
|
+
|
|
8
|
+
// use a empty password to disable category encryption
|
|
9
|
+
if (password === "") {
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
if (hexo.config.encrypt === undefined) {
|
|
13
|
+
hexo.config.encrypt = [];
|
|
14
|
+
}
|
|
15
|
+
if (('encrypt' in hexo.config) && ('tags' in hexo.config.encrypt)) {
|
|
16
|
+
hexo.config.encrypt.tags.forEach((tagObj) => {
|
|
17
|
+
tagEncryptPairs[tagObj.name] = tagObj.password;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (data.tags) {
|
|
21
|
+
data.tags.forEach((cTag) => {
|
|
22
|
+
if (tagEncryptPairs.hasOwnProperty(cTag.name)) {
|
|
23
|
+
tagUsed = password ? tagUsed : cTag.name;
|
|
24
|
+
password = password || tagEncryptPairs[cTag.name];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (password == undefined) {
|
|
29
|
+
return data;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// callback
|
|
33
|
+
data.content += `
|
|
34
|
+
<style>
|
|
35
|
+
#toc-div {
|
|
36
|
+
display: block !important;
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
39
|
+
<script>
|
|
40
|
+
volantis.pjax.method.complete.start();
|
|
41
|
+
</script>
|
|
42
|
+
`
|
|
43
|
+
return data;
|
|
44
|
+
});
|
package/scripts/filters/img.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
hexo.extend.filter.register('after_post_render', function(data) {
|
|
5
|
+
hexo.extend.filter.register('after_post_render', function (data) {
|
|
6
6
|
data.content = data.content.replace(/<p><img src="(.*?)" alt="(.*?)"\/><\/p>/g, '<div class="img-wrap"><div class="img-bg"><img class="img" src="$1" alt="$2"\/><\/div><span class="image-caption">$2<\/span><\/div>');
|
|
7
7
|
return data;
|
|
8
8
|
});
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
hexo.extend.filter.register('after_render:html', function(data) {
|
|
5
|
+
hexo.extend.filter.register('after_render:html', function (data) {
|
|
6
6
|
if (hexo.theme.config.replace) {
|
|
7
7
|
hexo.theme.config.replace.forEach(e => {
|
|
8
8
|
let s = e.split(" => ")
|
|
9
9
|
let a = s[0]
|
|
10
10
|
let b = s[1]
|
|
11
|
-
data = data.replace(new RegExp(a,"g"), b);
|
|
11
|
+
data = data.replace(new RegExp(a, "g"), b);
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
return data;
|
|
15
|
-
},999999999999);
|
|
15
|
+
}, 999999999999);
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const fs = require('hexo-fs');
|
|
4
|
-
|
|
5
3
|
function lazyProcess(htmlContent, target) {
|
|
6
4
|
const cfg = this.theme.config.plugins.lazyload;
|
|
7
5
|
if (cfg == undefined || cfg.enable != true) {
|
|
@@ -13,7 +11,7 @@ function lazyProcess(htmlContent, target) {
|
|
|
13
11
|
}
|
|
14
12
|
}
|
|
15
13
|
const loadingImg = cfg.loadingImg;
|
|
16
|
-
return htmlContent.replace(/<img(.*?)src="(.*?)"(.*?)>/gi, function(str, p1, p2) {
|
|
14
|
+
return htmlContent.replace(/<img(.*?)src="(.*?)"(.*?)>/gi, function (str, p1, p2) {
|
|
17
15
|
// might be duplicate
|
|
18
16
|
if (/data-srcset/gi.test(str)) {
|
|
19
17
|
return str;
|
|
@@ -57,12 +55,12 @@ function lazyProcess(htmlContent, target) {
|
|
|
57
55
|
});
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
let processPost = function(data) {
|
|
58
|
+
let processPost = function (data) {
|
|
61
59
|
data.content = lazyProcess.call(this, data.content, 'post');
|
|
62
60
|
return data;
|
|
63
61
|
};
|
|
64
62
|
|
|
65
|
-
let processSite = function(htmlContent) {
|
|
63
|
+
let processSite = function (htmlContent) {
|
|
66
64
|
return lazyProcess.call(this, htmlContent, 'site');
|
|
67
65
|
};
|
|
68
66
|
|
|
@@ -6,8 +6,8 @@ function generateFirstCSS() {
|
|
|
6
6
|
let s = fs.readFileSync(
|
|
7
7
|
hexo.theme.context.theme_dir + "source/css/first.styl"
|
|
8
8
|
);
|
|
9
|
-
hexo.renderStylus(s).then((css)=>{
|
|
10
|
-
hexo.locals.set('FirstCSS', function(){
|
|
9
|
+
hexo.renderStylus(s).then((css) => {
|
|
10
|
+
hexo.locals.set('FirstCSS', function () {
|
|
11
11
|
return css
|
|
12
12
|
});
|
|
13
13
|
})
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
hexo.extend.helper.register('generate_seo', function (theme, page) {
|
|
2
2
|
const hexo = this;
|
|
3
|
-
let robots_content="";
|
|
3
|
+
let robots_content = "";
|
|
4
4
|
if (page.robots) {
|
|
5
5
|
robots_content = page.robots
|
|
6
6
|
} else if (theme.seo && theme.seo.robots) {
|
|
7
7
|
if (hexo.is_home()) {
|
|
8
8
|
if (page.prev == 0) {
|
|
9
|
-
robots_content=theme.seo.robots.home_first_page
|
|
10
|
-
}else{
|
|
11
|
-
robots_content=theme.seo.robots.home_other_pages
|
|
9
|
+
robots_content = theme.seo.robots.home_first_page
|
|
10
|
+
} else {
|
|
11
|
+
robots_content = theme.seo.robots.home_other_pages
|
|
12
12
|
}
|
|
13
13
|
} else if (hexo.is_archive()) {
|
|
14
|
-
robots_content=theme.seo.robots.archive
|
|
14
|
+
robots_content = theme.seo.robots.archive
|
|
15
15
|
} else if (hexo.is_category()) {
|
|
16
|
-
robots_content=theme.seo.robots.category
|
|
16
|
+
robots_content = theme.seo.robots.category
|
|
17
17
|
} else if (hexo.is_tag()) {
|
|
18
|
-
robots_content=theme.seo.robots.tag
|
|
18
|
+
robots_content = theme.seo.robots.tag
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
if(robots_content){
|
|
21
|
+
if (robots_content) {
|
|
22
22
|
return `<meta name="robots" content="${robots_content}">`
|
|
23
|
+
}else{
|
|
24
|
+
return `<meta name="robots" content="index,follow">`
|
|
23
25
|
}
|
|
24
|
-
});
|
|
26
|
+
});
|
|
@@ -29,16 +29,29 @@ function init(hexo, config, theme, page) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
if (theme.seo && theme.seo.use_tags_as_keywords) {
|
|
32
|
-
if
|
|
32
|
+
if(!keywords){
|
|
33
|
+
if (page.categories && page.categories.length > 0) {
|
|
34
|
+
let categories = page.categories
|
|
35
|
+
.map(function (tag) {
|
|
36
|
+
return tag.name ? tag.name : tag;
|
|
37
|
+
})
|
|
38
|
+
.join(",");
|
|
39
|
+
if (categories.length > 0) {
|
|
40
|
+
keywords += categories;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (page.tags && page.tags.length > 0) {
|
|
33
44
|
let tags = page.tags
|
|
34
|
-
.map(function (
|
|
35
|
-
return
|
|
45
|
+
.map(function (tag) {
|
|
46
|
+
return tag.name ? tag.name : tag;
|
|
36
47
|
})
|
|
37
48
|
.join(",");
|
|
38
49
|
if (tags.length > 0) {
|
|
50
|
+
keywords += ", ";
|
|
39
51
|
keywords += tags;
|
|
40
52
|
}
|
|
41
53
|
}
|
|
54
|
+
}
|
|
42
55
|
}
|
|
43
56
|
if (theme.seo && theme.seo.use_excerpt_as_description) {
|
|
44
57
|
if (page.description == undefined) {
|
|
@@ -86,7 +99,7 @@ hexo.extend.helper.register("generate_description", function (config, theme, pag
|
|
|
86
99
|
if (!description) {
|
|
87
100
|
if (config.description) {
|
|
88
101
|
description = config.description
|
|
89
|
-
}else{
|
|
102
|
+
} else {
|
|
90
103
|
description = config.title
|
|
91
104
|
}
|
|
92
105
|
}
|
|
@@ -95,7 +108,7 @@ hexo.extend.helper.register("generate_description", function (config, theme, pag
|
|
|
95
108
|
});
|
|
96
109
|
// open_graph() 函数会生成一个 description 标签??? https://github.com/hexojs/hexo/blob/92b979f4a3fa8714aebd3d11c3295d466b870905/lib/plugins/helper/open_graph.js#L98
|
|
97
110
|
// 移除 open_graph() 函数会生成的 description
|
|
98
|
-
hexo.extend.filter.register('after_render:html', function(data) {
|
|
111
|
+
hexo.extend.filter.register('after_render:html', function (data) {
|
|
99
112
|
data = data.replace(/<meta name="description".*>/g, "");
|
|
100
113
|
return data;
|
|
101
|
-
},99);
|
|
114
|
+
}, 99);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
var util = require('hexo-util');
|
|
7
7
|
|
|
8
8
|
// Examples of helper
|
|
9
|
-
hexo.extend.helper.register('htmlGenerator', function(args) {
|
|
9
|
+
hexo.extend.helper.register('htmlGenerator', function (args) {
|
|
10
10
|
if (!args || !args.json || args.json.length == 0) return '';
|
|
11
11
|
const cfg = hexo.theme.config.article.body.footer_widget.related_posts;
|
|
12
12
|
var returnHTML = '';
|
|
@@ -35,10 +35,10 @@ hexo.extend.helper.register('htmlGenerator', function(args) {
|
|
|
35
35
|
ret += '<span class="title">' + list.title + '</span>';
|
|
36
36
|
|
|
37
37
|
if (list.excerpt && list.excerpt.length > 0) {
|
|
38
|
-
ret += '<span class="excerpt">' + util.truncate(util.stripHTML(list.excerpt), {length: 64}) + '</span>';
|
|
38
|
+
ret += '<span class="excerpt">' + util.truncate(util.stripHTML(list.excerpt), { length: 64 }) + '</span>';
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
ret +=
|
|
41
|
+
ret += '</a>';
|
|
42
42
|
return ret;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -124,7 +124,7 @@ module.exports = (hexo, option) => {
|
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
if (hexo.is_page()&&page.categories) {
|
|
127
|
+
if (hexo.is_page() && page.categories) {
|
|
128
128
|
let temp = "/"
|
|
129
129
|
for (let index = 0; index < page.categories.length; index++) {
|
|
130
130
|
const cat = page.categories[index];
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const 文章库 = [];
|
|
2
|
+
const 语料库 = [];
|
|
3
|
+
let 标记 = null;
|
|
4
|
+
|
|
5
|
+
hexo.extend.filter.register('template_locals', function (本地变量) {
|
|
6
|
+
const cfg = hexo.theme.config.article.body.footer_widget.recommended_article;
|
|
7
|
+
if (!cfg.enable) {
|
|
8
|
+
return 本地变量;
|
|
9
|
+
}
|
|
10
|
+
if (!标记) {
|
|
11
|
+
标记 = 1
|
|
12
|
+
获取数据(本地变量.site.posts, cfg)
|
|
13
|
+
获取数据(本地变量.site.pages, cfg)
|
|
14
|
+
文章推荐(cfg)
|
|
15
|
+
}
|
|
16
|
+
return 本地变量;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
function 获取数据(s, cfg) {
|
|
20
|
+
s.each(function (p) {
|
|
21
|
+
if (["post", "docs"].includes(p.layout)) {
|
|
22
|
+
文章库.push({
|
|
23
|
+
path: p.path,
|
|
24
|
+
title: p.title || p.seo_title || p.short_title,
|
|
25
|
+
headimg: p.headimg || cfg.placeholder_img,
|
|
26
|
+
})
|
|
27
|
+
语料库.push(分词(p.raw))
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function 数据清洗(数据) {
|
|
33
|
+
const 标点符号列表 = [
|
|
34
|
+
",", ".", "?", "!", ":", ";", "、", "……", "~", "&", "@", "#", ",", "。", "?", "!", ":", ";", "·", "…", "~", "&", "@", "#", "“", "”", "‘", "’", "〝", "〞", "\"", "'", """, "'", "´", "'", "(", ")", "【",
|
|
35
|
+
"】", "《", "》", "<", ">", "﹝", "﹞", "<", ">", "(", ")", "[", "]", "«", "»", "‹", "›", "〔", "〕", "〈", "〉", "{", "}", "[", "]", "「", "」", "{", "}", "〖", "〗", "『", "』", "︵", "︷", "︹", "︿", "︽", "﹁",
|
|
36
|
+
"﹃", "︻", "︗", "/", "|", "\\", "︶", "︸", "︺", "﹀", "︾", "﹂", "﹄", "﹄", "︼", "︘", "/", "|", "\",
|
|
37
|
+
"_", "¯", "_", " ̄", "﹏", "﹋", "﹍", "﹉", "﹎", "﹊", "`", "ˋ", "¦", "︴", "¡", "¿", "^", "ˇ", "", "¨", "ˊ", " ", " ",
|
|
38
|
+
"%", "*", "-", "+", "=", "¥", "$", "(", ")"
|
|
39
|
+
]
|
|
40
|
+
数据 = 数据.replace(/\s/g, " ")
|
|
41
|
+
数据 = 数据.replace(/\!\[(.*?)\]\(.*?\)/g, (_a, b) => { return b })
|
|
42
|
+
数据 = 数据.replace(/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/g, " ")
|
|
43
|
+
for (const 标点符号 of 标点符号列表) {
|
|
44
|
+
数据 = 数据.replace(new RegExp("\\" + 标点符号, "g"), " ")
|
|
45
|
+
}
|
|
46
|
+
数据 = 数据.replace(/\d+/g, " ")
|
|
47
|
+
数据 = 数据.replace(/\s/g, " ")
|
|
48
|
+
return 数据
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function 分词(数据) {
|
|
52
|
+
const 结巴 = require("nodejieba");
|
|
53
|
+
return 结巴.cut(数据清洗(数据), true).filter(词 => 词 !== " " && !/^[0-9]*$/.test(词))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function 余弦相似度(向量1, 向量2) {
|
|
57
|
+
let 分子 = 0;
|
|
58
|
+
let 根式1 = 0;
|
|
59
|
+
let 根式2 = 0;
|
|
60
|
+
if (向量1.length == 向量2.length) {
|
|
61
|
+
for (let i = 0; i < 向量1.length; i++) {
|
|
62
|
+
分子 += (向量1[i] * 向量2[i])
|
|
63
|
+
根式1 += (向量1[i] * 向量1[i])
|
|
64
|
+
根式2 += (向量2[i] * 向量2[i])
|
|
65
|
+
}
|
|
66
|
+
return 分子 / (Math.sqrt(根式1) * Math.sqrt(根式2))
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
function 文章推荐(cfg) {
|
|
72
|
+
const 数据集 = {};
|
|
73
|
+
const 相似度集 = {};
|
|
74
|
+
const 推荐集 = {}
|
|
75
|
+
let 所有文章中所有的词 = [];
|
|
76
|
+
|
|
77
|
+
for (let i = 0; i < 语料库.length; i++) {
|
|
78
|
+
const 分词表 = 语料库[i];
|
|
79
|
+
所有文章中所有的词 = [...new Set(所有文章中所有的词.concat(分词表))]
|
|
80
|
+
}
|
|
81
|
+
const 词库 = {}
|
|
82
|
+
所有文章中所有的词.forEach(e => {
|
|
83
|
+
词库[e] = 0
|
|
84
|
+
})
|
|
85
|
+
const 包含该词的文档数库 = JSON.parse(JSON.stringify(词库))
|
|
86
|
+
for (let i = 0; i < 语料库.length; i++) {
|
|
87
|
+
const 文章路径 = 文章库[i].path;
|
|
88
|
+
const 文章中的词 = 语料库[i];
|
|
89
|
+
|
|
90
|
+
const 词在文章中出现的次数库 = 文章中的词.reduce((词计数对象, 词名称) => {
|
|
91
|
+
if (词名称 in 词计数对象) {
|
|
92
|
+
词计数对象[词名称]++;
|
|
93
|
+
}
|
|
94
|
+
return 词计数对象
|
|
95
|
+
}, JSON.parse(JSON.stringify(词库)))
|
|
96
|
+
|
|
97
|
+
数据集[文章路径] = {};
|
|
98
|
+
数据集[文章路径]["词频"] = JSON.parse(JSON.stringify(词库));
|
|
99
|
+
for (const 词 of Object.keys(词库)) {
|
|
100
|
+
数据集[文章路径]["词频"][词] = 词在文章中出现的次数库[词] / 文章中的词.length;
|
|
101
|
+
if (词在文章中出现的次数库[词]) {
|
|
102
|
+
包含该词的文档数库[词]++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < 语料库.length; i++) {
|
|
108
|
+
const 文章路径 = 文章库[i].path;
|
|
109
|
+
数据集[文章路径]["逆文档频率"] = JSON.parse(JSON.stringify(词库));
|
|
110
|
+
数据集[文章路径]["词频-逆文档频率"] = JSON.parse(JSON.stringify(词库));
|
|
111
|
+
数据集[文章路径]["词频向量"] = []
|
|
112
|
+
for (const 词 of Object.keys(词库)) {
|
|
113
|
+
const 逆文档频率 = Math.log(语料库.length / (包含该词的文档数库[词] + 1))
|
|
114
|
+
const 词频逆文档频率 = 数据集[文章路径]["词频"][词] * 逆文档频率
|
|
115
|
+
// 数据集[文章路径]["逆文档频率"][词] = 逆文档频率
|
|
116
|
+
// 数据集[文章路径]["词频-逆文档频率"][词] = 词频逆文档频率
|
|
117
|
+
数据集[文章路径]["词频向量"].push(词频逆文档频率)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (let i = 0; i < 语料库.length; i++) {
|
|
121
|
+
const 文章路径1 = 文章库[i].path;
|
|
122
|
+
相似度集[文章路径1] = {}
|
|
123
|
+
for (let j = 0; j < 语料库.length; j++) {
|
|
124
|
+
const 文章路径2 = 文章库[j].path;
|
|
125
|
+
相似度集[文章路径1][文章路径2] = 余弦相似度(数据集[文章路径1]["词频向量"], 数据集[文章路径2]["词频向量"]);
|
|
126
|
+
}
|
|
127
|
+
for (let j = 0; j < 语料库.length; j++) {
|
|
128
|
+
推荐集[文章路径1] = Object.keys(相似度集[文章路径1]).sort(function (a, b) {
|
|
129
|
+
return 相似度集[文章路径1][b] - 相似度集[文章路径1][a]; // 降序
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
const index = 推荐集[文章路径1].indexOf(文章路径1);
|
|
133
|
+
if (index > -1) {
|
|
134
|
+
推荐集[文章路径1].splice(index, 1);
|
|
135
|
+
}
|
|
136
|
+
推荐集[文章路径1] = 推荐集[文章路径1].slice(0, cfg.max_count);
|
|
137
|
+
for (let j = 0; j < 推荐集[文章路径1].length; j++) {
|
|
138
|
+
const e = 推荐集[文章路径1][j];
|
|
139
|
+
推荐集[文章路径1][j] = 文章库.filter(w => w.path == e)[0]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
hexo.locals.set('推荐集', function () {
|
|
143
|
+
return 推荐集
|
|
144
|
+
});
|
|
145
|
+
// console.log(hexo.locals.get('推荐集'));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
hexo.extend.helper.register('文章推荐生成器', function (post) {
|
|
149
|
+
if (!post) return '';
|
|
150
|
+
const cfg = hexo.theme.config.article.body.footer_widget.recommended_article;
|
|
151
|
+
if (!cfg.enable) {
|
|
152
|
+
return "";
|
|
153
|
+
}
|
|
154
|
+
for (const dir of cfg.skip_dirs) {
|
|
155
|
+
if (new RegExp("^" + dir, "g").test(post.path)) {
|
|
156
|
+
return "";
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const 推荐集 = hexo.locals.get('推荐集');
|
|
160
|
+
const 推荐文章 = 推荐集[post.path];
|
|
161
|
+
// console.log(post.path);
|
|
162
|
+
// console.log(推荐文章);
|
|
163
|
+
return 用户界面(推荐文章, cfg);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
function 用户界面(推荐文章, cfg) {
|
|
167
|
+
let html = ""
|
|
168
|
+
for (const item of 推荐文章) {
|
|
169
|
+
html += Item界面(item)
|
|
170
|
+
}
|
|
171
|
+
return `<div class="recommended-article">
|
|
172
|
+
<div class="recommended-article-header">
|
|
173
|
+
<i class="${cfg.icon} fa-fw" aria-hidden="true"></i><span>${cfg.title}</span>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="recommended-article-group">${html}</div>
|
|
176
|
+
</div>`
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function Item界面(item) {
|
|
180
|
+
return `<a class="recommended-article-item" href="${hexo.config.root + item.path}" title="${item.title}" rel="bookmark">
|
|
181
|
+
<img src="${item.headimg}" alt="${item.title}">
|
|
182
|
+
<span class="title">${item.title}</span>
|
|
183
|
+
</a>`
|
|
184
|
+
}
|
package/scripts/tags/btn.js
CHANGED
package/scripts/tags/btns.js
CHANGED
|
@@ -7,10 +7,10 @@ function postBtns(args, content) {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
function postCell(args, content) {
|
|
10
|
-
if(/::/g.test(args)){
|
|
10
|
+
if (/::/g.test(args)) {
|
|
11
11
|
args = args.join(' ').split('::');
|
|
12
12
|
}
|
|
13
|
-
else{
|
|
13
|
+
else {
|
|
14
14
|
args = args.join(' ').split(',');
|
|
15
15
|
}
|
|
16
16
|
let text = args[0] || '';
|
|
@@ -36,5 +36,5 @@ function postCell(args, content) {
|
|
|
36
36
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
hexo.extend.tag.register('btns', postBtns, {ends: true});
|
|
39
|
+
hexo.extend.tag.register('btns', postBtns, { ends: true });
|
|
40
40
|
hexo.extend.tag.register('cell', postCell);
|
package/scripts/tags/checkbox.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function postCheckbox(args) {
|
|
4
|
-
if(/::/g.test(args)){
|
|
4
|
+
if (/::/g.test(args)) {
|
|
5
5
|
args = args.join(' ').split('::');
|
|
6
6
|
}
|
|
7
|
-
else{
|
|
7
|
+
else {
|
|
8
8
|
args = args.join(' ').split(',');
|
|
9
9
|
}
|
|
10
10
|
var cls = '';
|
|
@@ -24,15 +24,15 @@ function postCheckbox(args) {
|
|
|
24
24
|
}
|
|
25
25
|
if (text.length > 0) {
|
|
26
26
|
return `<div class='checkbox${cls}'><input type="checkbox" ${checked ? 'checked="checked"' : ''}/>
|
|
27
|
-
${hexo.render.renderSync({text: text, engine: 'markdown'}).split('\n').join('')}
|
|
27
|
+
${hexo.render.renderSync({ text: text, engine: 'markdown' }).split('\n').join('')}
|
|
28
28
|
</div>`;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
function postRadio(args) {
|
|
32
|
-
if(/::/g.test(args)){
|
|
32
|
+
if (/::/g.test(args)) {
|
|
33
33
|
args = args.join(' ').split('::');
|
|
34
34
|
}
|
|
35
|
-
else{
|
|
35
|
+
else {
|
|
36
36
|
args = args.join(' ').split(',');
|
|
37
37
|
}
|
|
38
38
|
var cls = '';
|
|
@@ -52,7 +52,7 @@ function postRadio(args) {
|
|
|
52
52
|
}
|
|
53
53
|
if (text.length > 0) {
|
|
54
54
|
return `<div class='checkbox${cls}'><input type="radio" ${checked ? 'checked="checked"' : ''}/>
|
|
55
|
-
${hexo.render.renderSync({text: text, engine: 'markdown'}).split('\n').join('')}
|
|
55
|
+
${hexo.render.renderSync({ text: text, engine: 'markdown' }).split('\n').join('')}
|
|
56
56
|
</div>`;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -7,19 +7,19 @@
|
|
|
7
7
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
|
-
hexo.extend.tag.register('contributors', function(args) {
|
|
10
|
+
hexo.extend.tag.register('contributors', function (args) {
|
|
11
11
|
args = hexo.args.map(args, ['only', 'not', 'api', 'source', 'repo']);
|
|
12
12
|
if (args.only) {
|
|
13
|
-
if(/::/g.test(args.only)){
|
|
13
|
+
if (/::/g.test(args.only)) {
|
|
14
14
|
args.only = args.only.split('::');
|
|
15
|
-
}else{
|
|
15
|
+
} else {
|
|
16
16
|
args.only = args.only.split(',');
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
if (args.not) {
|
|
20
|
-
if(/::/g.test(args.not)){
|
|
20
|
+
if (/::/g.test(args.not)) {
|
|
21
21
|
args.not = args.not.split('::');
|
|
22
|
-
}else{
|
|
22
|
+
} else {
|
|
23
23
|
args.not = args.not.split(',');
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -40,10 +40,10 @@ hexo.extend.tag.register('contributors', function(args) {
|
|
|
40
40
|
function groupHeader(group) {
|
|
41
41
|
var header = '<div class="group-header">';
|
|
42
42
|
if (group.title) {
|
|
43
|
-
header += hexo.render.renderSync({text: group.title, engine: 'markdown'}).split('\n').join('');
|
|
43
|
+
header += hexo.render.renderSync({ text: group.title, engine: 'markdown' }).split('\n').join('');
|
|
44
44
|
}
|
|
45
45
|
if (group.description) {
|
|
46
|
-
header += hexo.render.renderSync({text: group.description, engine: 'markdown'}).split('\n').join('');
|
|
46
|
+
header += hexo.render.renderSync({ text: group.description, engine: 'markdown' }).split('\n').join('');
|
|
47
47
|
}
|
|
48
48
|
header += '</div>';
|
|
49
49
|
return header;
|
package/scripts/tags/dropmenu.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function postMenu(args, content) {
|
|
4
|
-
if(/::/g.test(args)){
|
|
4
|
+
if (/::/g.test(args)) {
|
|
5
5
|
args = args.join(' ').split('::');
|
|
6
6
|
}
|
|
7
|
-
else{
|
|
7
|
+
else {
|
|
8
8
|
args = args.join(' ').split(',');
|
|
9
9
|
}
|
|
10
10
|
if (args.length == 1) {
|
|
@@ -46,10 +46,10 @@ function postMenu(args, content) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
function postSubmenu(args, content) {
|
|
49
|
-
if(/::/g.test(args)){
|
|
49
|
+
if (/::/g.test(args)) {
|
|
50
50
|
args = args.join(' ').split('::');
|
|
51
51
|
}
|
|
52
|
-
else{
|
|
52
|
+
else {
|
|
53
53
|
args = args.join(' ').split(',');
|
|
54
54
|
}
|
|
55
55
|
const text = args[0] || '';
|
|
@@ -75,10 +75,10 @@ function postSubmenu(args, content) {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function postMenuItem(args) {
|
|
78
|
-
if(/::/g.test(args)){
|
|
78
|
+
if (/::/g.test(args)) {
|
|
79
79
|
args = args.join(' ').split('::');
|
|
80
80
|
}
|
|
81
|
-
else{
|
|
81
|
+
else {
|
|
82
82
|
args = args.join(' ').split(',');
|
|
83
83
|
}
|
|
84
84
|
let text = args[0] || '';
|
|
@@ -118,6 +118,6 @@ function postMenuItem(args) {
|
|
|
118
118
|
// {% menu 标题 %}
|
|
119
119
|
// {% menu 前缀, 标题 %}
|
|
120
120
|
// {% menu 前缀, 标题, 后缀 %}
|
|
121
|
-
hexo.extend.tag.register('menu', postMenu, {ends: true});
|
|
122
|
-
hexo.extend.tag.register('submenu', postSubmenu, {ends: true});
|
|
121
|
+
hexo.extend.tag.register('menu', postMenu, { ends: true });
|
|
122
|
+
hexo.extend.tag.register('submenu', postSubmenu, { ends: true });
|
|
123
123
|
hexo.extend.tag.register('menuitem', postMenuItem);
|
package/scripts/tags/fancybox.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function renderImg(content) {
|
|
4
|
-
return `${hexo.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('')}`;
|
|
4
|
+
return `${hexo.render.renderSync({ text: content, engine: 'markdown' }).split('\n').join('')}`;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
function buidAlt(alt) {
|
|
@@ -14,8 +14,8 @@ function buidAlt(alt) {
|
|
|
14
14
|
|
|
15
15
|
function buidImgFancybox(content, group) {
|
|
16
16
|
let html = renderImg(content).trim();
|
|
17
|
-
if(html.startsWith('<p>') &&
|
|
18
|
-
html=html.substring(0, html.length-4).substring(3);
|
|
17
|
+
if (html.startsWith('<p>') && html.endsWith('</p>')) { // 去除无用的 p 标签包裹
|
|
18
|
+
html = html.substring(0, html.length - 4).substring(3);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
let imageTags = html.includes('image-caption') ? 'image' : undefined;
|
|
@@ -31,10 +31,10 @@ function buidImgFancybox(content, group) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function postFancybox(args, content) {
|
|
34
|
-
if(/::/g.test(args)){
|
|
34
|
+
if (/::/g.test(args)) {
|
|
35
35
|
args = args.join(' ').split('::');
|
|
36
36
|
}
|
|
37
|
-
else{
|
|
37
|
+
else {
|
|
38
38
|
args = args.join(' ').split(',');
|
|
39
39
|
}
|
|
40
40
|
const cls = args[0];
|
|
@@ -49,4 +49,4 @@ function postFancybox(args, content) {
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
hexo.extend.tag.register('gallery', postFancybox, {ends: true});
|
|
52
|
+
hexo.extend.tag.register('gallery', postFancybox, { ends: true });
|