diff --git a/README.md b/README.md index eefe5d4f..5f150d15 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ 繁中 -Redefine +Redefine @@ -26,7 +26,7 @@ ## 🌐 Online Demo -- [Anonymous Land](https://ohevan.com) +- [EvanNotFound's Blog](https://ohevan.com) - [Theme Redefine Demo](https://redefine.ohevan.com) ## ⛰️ Some functions diff --git a/README_zh-CN.md b/README_zh-CN.md index 010b379b..cf46f04c 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -5,8 +5,7 @@ 繁中 -Redefine - +Redefine # hexo-theme-redefine @@ -26,7 +25,7 @@ ## 🌐 在线演示站 -- [Anonymous Land](https://ohevan.com) +- [EvanNotFound's Blog](https://ohevan.com) - [Theme Redefine Demo](https://redefine.ohevan.com) ## ⛰️ 部分功能 diff --git a/README_zh-TW.md b/README_zh-TW.md index 92484fb2..f9f4950e 100644 --- a/README_zh-TW.md +++ b/README_zh-TW.md @@ -5,7 +5,7 @@ 简中 -Redefine +Redefine @@ -27,7 +27,7 @@ ## 🌐 在線演示站 -- [Anonymous Land](https://ohevan.com) +- [EvanNotFound's Blog](https://ohevan.com) - [Theme Redefine Demo](https://redefine.ohevan.com) ## ⛰️ 部分功能 diff --git a/_config.yml b/_config.yml index 72589780..d9f7a350 100755 --- a/_config.yml +++ b/_config.yml @@ -51,6 +51,10 @@ style: light: "#fff" # first screen title color (light mode) dark: "#d1d1b6" # first screen title color (dark mode) description: Theme Redefine # the title in the middle of the first screen. HTML supported (e.g. svg html code of your logo) + custom_font: # custom font for the first screen + enable: false + font_family: # the font family name of the url below + font_url: # The url to the font file # Scroll style settings scroll: @@ -90,7 +94,7 @@ menu: #you can customize, i18n files are in the theme's languages folder. fa-reg # submenus: # Me: /about # Github: https://github.com/EvanNotFound/hexo-theme-redefine - # Blog: https://www.evanluo.top + # Blog: https://ohevan.com # Friends: /friends # Links: # icon: fa-regular fa-link @@ -243,6 +247,21 @@ cdn: pjax: enable: true +# --------------------------------------------------------------------------------------- +# Article recommendation (transplant from Volantis) +# --------------------------------------------------------------------------------------- +recommended_article: # 文章推荐,需要 npm install nodejieba + enable: false + title: 推荐阅读 + icon: fa-solid fa-bookmark + max_count: 3 + placeholder_img: https://evan.beee.top/img/wallhaven-wqery6-light.webp + # 不展示文章推荐: + # front-matter 使用 skip_recommended_article: true 关闭 + # 不在以下文件夹文章中展示文章推荐 根目录是source/ + skip_dirs: + - wiki/ + # --------------------------------------------------------------------------------------- # Fontawesome # --------------------------------------------------------------------------------------- @@ -277,4 +296,4 @@ inject: # Please go to github to update the latest version frequently # Github: https://github.com/EvanNotFound/hexo-theme-redefine # --------------------------------------------------------------------------------------- -version: 1.1.0 \ No newline at end of file +version: 1.1.1 \ No newline at end of file diff --git a/layout/_partials/components/404-template.ejs b/layout/_partials/components/404-template.ejs new file mode 100644 index 00000000..f843b853 --- /dev/null +++ b/layout/_partials/components/404-template.ejs @@ -0,0 +1,8 @@ +
+
+

404 Page Not Found

+
+
+ Go Back +
+
\ No newline at end of file diff --git a/layout/_partials/components/first-screen.ejs b/layout/_partials/components/first-screen.ejs index 327c487d..27092afd 100755 --- a/layout/_partials/components/first-screen.ejs +++ b/layout/_partials/components/first-screen.ejs @@ -1,6 +1,8 @@
-
+
+ style="font-family: '<%- theme.style.first_screen.custom_font.font_family %>', sans-serif; !important;" + <% } %>> <%- theme.style.first_screen.description || config.description %>
<% if (theme.social_contact.enable) { %> diff --git a/layout/_partials/head.ejs b/layout/_partials/head.ejs index 4936483d..df88533e 100755 --- a/layout/_partials/head.ejs +++ b/layout/_partials/head.ejs @@ -8,6 +8,19 @@ <%- generate_seo(theme, page) %> <%- autoCanonical(config, page) %> + + + + + + + + + + + + + @@ -32,12 +45,15 @@ %> <% if (title) { %> - <%= title %> | + <%= title %> - <% } %> <%= theme.base_info.title || config.title || 'Redefine Theme' %> <%- css('css/style') %> - <%- __css('css/fonts.css') %> + <%- __css('assets/fonts.css') %> + <% if (theme.style.first_screen.custom_font.enable) { %> + + <% } %> <% if (theme.inject.enable == true) { %> <% for (let i in theme.inject.head) { %> <% if (theme.inject.head[i] !== null){ %> @@ -47,21 +63,23 @@ <%- theme.inject.head[i] %> <% } }%> <% } }%> - + <% if (theme.cdn.enable == true) { %> + + <% } %> <%- export_config() %> - <%- __css('css/fontawesome.min.css') %> - <%- __css('css/brands.min.css') %> - <%- __css('css/solid.min.css') %> - <%- __css('css/regular.min.css') %> + <%- __css('fontawesome/fontawesome.min.css') %> + <%- __css('fontawesome/brands.min.css') %> + <%- __css('fontawesome/solid.min.css') %> + <%- __css('fontawesome/regular.min.css') %> <% if (theme.fontawesome.thin == true) { %> - <%- __css('css/thin.min.css') %> + <%- __css('fontawesome/thin.min.css') %> <% } %> <% if (theme.fontawesome.light == true) { %> - <%- __css('css/light.min.css') %> + <%- __css('fontawesome/light.min.css') %> <% } %> <% if (theme.fontawesome.duotone == true) { %> - <%- __css('css/duotone.min.css') %> + <%- __css('fontawesome/duotone.min.css') %> <% } %> diff --git a/layout/_partials/scripts.ejs b/layout/_partials/scripts.ejs index c3c3ef26..2df15738 100755 --- a/layout/_partials/scripts.ejs +++ b/layout/_partials/scripts.ejs @@ -21,7 +21,7 @@ <% if (theme.footer.runtime) { %> <%- __js('js/tools/runtime.js') %> <%- __js('js/layouts/odometer.min.js') %> - <%- __css('css/odometer-theme-minimal.css') %> + <%- __css('assets/odometer-theme-minimal.css') %> <% } %>
diff --git a/layout/article-content.ejs b/layout/article-content.ejs index c8cd7232..5c99f55f 100755 --- a/layout/article-content.ejs +++ b/layout/article-content.ejs @@ -75,6 +75,8 @@ <% } %> + <%- 文章推荐生成器(page) %> + <% if (page.prev || page.next) { %>
<% if (page.prev) { %> @@ -112,6 +114,7 @@
<% } %> + <% if (theme.comment.enable === true && theme.comment.hasOwnProperty(theme.comment.use)) { %>
<%- partial('_partials/comments/comment') %> diff --git a/layout/page.ejs b/layout/page.ejs index 827a665b..de30b560 100755 --- a/layout/page.ejs +++ b/layout/page.ejs @@ -36,6 +36,9 @@ <% } else if (page.title === 'tag' || page.title === 'tags') { %> <%- partial('_partials/tools/tagcloud') %> + <% } else if (page.title === 'Page Not Found' || page.title === 'tags') { %> + <%- partial('_partials/components/404-template') %> + <% } else { %> <%- partial('_partials/page-template') %> diff --git a/package.json b/package.json index 9fd44460..d3c303c0 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "hexo-theme-redefine", - "version": "1.1.0", + "version": "1.1.1", "private": false, - "description": "\"Redefine\" hexo theme is a simple & fast & pure theme, but with no compromise.", + "description": "Redefine your writing with modern style and various functionality in 'Redefine' Hexo Theme.", "scripts": { "npm:publish": "npm publish", "format": "prettier --write ./source/js/*.js ./scripts", diff --git a/scripts/events/404.js b/scripts/events/404.js index 197a22df..b5d01e37 100755 --- a/scripts/events/404.js +++ b/scripts/events/404.js @@ -6,10 +6,10 @@ hexo.extend.generator.register('404', function(locals){ return { path: '404.html', - layout: ['page'], + layout: '404', data: { - type: '404', - top_img: false + title: 'Page Not Found', + page: locals.pages.findOne({path: '404.html'}) } } }); diff --git a/scripts/events/welcome.js b/scripts/events/welcome.js index 29447282..122676ea 100644 --- a/scripts/events/welcome.js +++ b/scripts/events/welcome.js @@ -18,7 +18,7 @@ hexo.on("ready", () => { res.on('end', () => { const jsonData = JSON.parse(data); hexo.log.info( - `\n===================================================================\n ______ __ __ ______ __ __ ______ \r\n \/\\__ _\/\\ \\_\\ \\\/\\ ___\\\/\\ \"-.\/ \\\/\\ ___\\ \r\n \\\/_\/\\ \\\\ \\ __ \\ \\ __\\\\ \\ \\-.\/\\ \\ \\ __\\ \r\n \\ \\_\\\\ \\_\\ \\_\\ \\_____\\ \\_\\ \\ \\_\\ \\_____\\ \r\n \\\/_\/ \\\/_\/\\\/_\/\\\/_____\/\\\/_\/ \\\/_\/\\\/_____\/ \r\n \r\n ______ ______ _____ ______ ______ __ __ __ ______ \r\n\/\\ == \\\/\\ ___\\\/\\ __-.\/\\ ___\\\/\\ ___\/\\ \\\/\\ \"-.\\ \\\/\\ ___\\ \r\n\\ \\ __<\\ \\ __\\\\ \\ \\\/\\ \\ \\ __\\\\ \\ __\\ \\ \\ \\ \\-. \\ \\ __\\ \r\n \\ \\_\\ \\_\\ \\_____\\ \\____-\\ \\_____\\ \\_\\ \\ \\_\\ \\_\\\\\"\\_\\ \\_____\\ \r\n \\\/_\/ \/_\/\\\/_____\/\\\/____\/ \\\/_____\/\\\/_\/ \\\/_\/\\\/_\/ \\\/_\/\\\/_____\/\r\n \r\n Github: https:\/\/github.com\/EvanNotFound\/hexo-theme-redefine\n current verison is v${version},latest version is v${jsonData["dist-tags"].latest}\n===================================================================` + `\n===================================================================\n ______ __ __ ______ __ __ ______ \r\n \/\\__ _\/\\ \\_\\ \\\/\\ ___\\\/\\ \"-.\/ \\\/\\ ___\\ \r\n \\\/_\/\\ \\\\ \\ __ \\ \\ __\\\\ \\ \\-.\/\\ \\ \\ __\\ \r\n \\ \\_\\\\ \\_\\ \\_\\ \\_____\\ \\_\\ \\ \\_\\ \\_____\\ \r\n \\\/_\/ \\\/_\/\\\/_\/\\\/_____\/\\\/_\/ \\\/_\/\\\/_____\/ \r\n \r\n ______ ______ _____ ______ ______ __ __ __ ______ \r\n\/\\ == \\\/\\ ___\\\/\\ __-.\/\\ ___\\\/\\ ___\/\\ \\\/\\ \"-.\\ \\\/\\ ___\\ \r\n\\ \\ __<\\ \\ __\\\\ \\ \\\/\\ \\ \\ __\\\\ \\ __\\ \\ \\ \\ \\-. \\ \\ __\\ \r\n \\ \\_\\ \\_\\ \\_____\\ \\____-\\ \\_____\\ \\_\\ \\ \\_\\ \\_\\\\\"\\_\\ \\_____\\ \r\n \\\/_\/ \/_\/\\\/_____\/\\\/____\/ \\\/_____\/\\\/_\/ \\\/_\/\\\/_\/ \\\/_\/\\\/_____\/\r\n \r\n Github: https:\/\/github.com\/EvanNotFound\/hexo-theme-redefine\n current version is v${version},latest version is v${jsonData["dist-tags"].latest}\n===================================================================` ); if (jsonData["dist-tags"].latest !== version) { console.log( @@ -33,7 +33,7 @@ hexo.on("ready", () => { }).on('error', (error) => { console.log(`Error: Failed to fetch package information. ${error.message}`); hexo.log.info( - `\n===================================================================\n ______ __ __ ______ __ __ ______ \r\n \/\\__ _\/\\ \\_\\ \\\/\\ ___\\\/\\ \"-.\/ \\\/\\ ___\\ \r\n \\\/_\/\\ \\\\ \\ __ \\ \\ __\\\\ \\ \\-.\/\\ \\ \\ __\\ \r\n \\ \\_\\\\ \\_\\ \\_\\ \\_____\\ \\_\\ \\ \\_\\ \\_____\\ \r\n \\\/_\/ \\\/_\/\\\/_\/\\\/_____\/\\\/_\/ \\\/_\/\\\/_____\/ \r\n \r\n ______ ______ _____ ______ ______ __ __ __ ______ \r\n\/\\ == \\\/\\ ___\\\/\\ __-.\/\\ ___\\\/\\ ___\/\\ \\\/\\ \"-.\\ \\\/\\ ___\\ \r\n\\ \\ __<\\ \\ __\\\\ \\ \\\/\\ \\ \\ __\\\\ \\ __\\ \\ \\ \\ \\-. \\ \\ __\\ \r\n \\ \\_\\ \\_\\ \\_____\\ \\____-\\ \\_____\\ \\_\\ \\ \\_\\ \\_\\\\\"\\_\\ \\_____\\ \r\n \\\/_\/ \/_\/\\\/_____\/\\\/____\/ \\\/_____\/\\\/_\/ \\\/_\/\\\/_\/ \\\/_\/\\\/_____\/\r\n \r\n Github: https:\/\/github.com\/EvanNotFound\/hexo-theme-redefine\n current verison is v${version},check latest version failed\n===================================================================` + `\n===================================================================\n ______ __ __ ______ __ __ ______ \r\n \/\\__ _\/\\ \\_\\ \\\/\\ ___\\\/\\ \"-.\/ \\\/\\ ___\\ \r\n \\\/_\/\\ \\\\ \\ __ \\ \\ __\\\\ \\ \\-.\/\\ \\ \\ __\\ \r\n \\ \\_\\\\ \\_\\ \\_\\ \\_____\\ \\_\\ \\ \\_\\ \\_____\\ \r\n \\\/_\/ \\\/_\/\\\/_\/\\\/_____\/\\\/_\/ \\\/_\/\\\/_____\/ \r\n \r\n ______ ______ _____ ______ ______ __ __ __ ______ \r\n\/\\ == \\\/\\ ___\\\/\\ __-.\/\\ ___\\\/\\ ___\/\\ \\\/\\ \"-.\\ \\\/\\ ___\\ \r\n\\ \\ __<\\ \\ __\\\\ \\ \\\/\\ \\ \\ __\\\\ \\ __\\ \\ \\ \\ \\-. \\ \\ __\\ \r\n \\ \\_\\ \\_\\ \\_____\\ \\____-\\ \\_____\\ \\_\\ \\ \\_\\ \\_\\\\\"\\_\\ \\_____\\ \r\n \\\/_\/ \/_\/\\\/_____\/\\\/____\/ \\\/_____\/\\\/_\/ \\\/_\/\\\/_\/ \\\/_\/\\\/_____\/\r\n \r\n Github: https:\/\/github.com\/EvanNotFound\/hexo-theme-redefine\n current version is v${version},check latest version failed\n===================================================================` ); // continue with code execution here diff --git a/scripts/helpers/articleRecommend.js b/scripts/helpers/articleRecommend.js new file mode 100755 index 00000000..1706d62e --- /dev/null +++ b/scripts/helpers/articleRecommend.js @@ -0,0 +1,189 @@ +/* +* transplanted from hexo-theme-volantis +* 文章推荐.js +*/ + +const 文章库 = []; +const 语料库 = []; +let 标记 = null; + +hexo.extend.filter.register('template_locals', function (本地变量) { + const cfg = hexo.theme.config.recommended_article; + if (!cfg.enable) { + return 本地变量; + } + if (!标记) { + 标记 = 1 + 获取数据(本地变量.site.posts, cfg) + 获取数据(本地变量.site.pages, cfg) + 文章推荐(cfg) + } + return 本地变量; +}); + +function 获取数据(s, cfg) { + s.each(function (p) { + if (["post", "docs"].includes(p.layout)) { + 文章库.push({ + path: p.path, + title: p.title || p.seo_title || p.short_title, + headimg: p.thumbnail || p.banner || p.cover || cfg.placeholder_img, + }) + 语料库.push(分词(p.raw)) + } + }) +} + +function 数据清洗(数据) { + const 标点符号列表 = [ + ",", ".", "?", "!", ":", ";", "、", "……", "~", "&", "@", "#", ",", "。", "?", "!", ":", ";", "·", "…", "~", "&", "@", "#", "“", "”", "‘", "’", "〝", "〞", "\"", "'", """, "'", "´", "'", "(", ")", "【", + "】", "《", "》", "<", ">", "﹝", "﹞", "<", ">", "(", ")", "[", "]", "«", "»", "‹", "›", "〔", "〕", "〈", "〉", "{", "}", "[", "]", "「", "」", "{", "}", "〖", "〗", "『", "』", "︵", "︷", "︹", "︿", "︽", "﹁", + "﹃", "︻", "︗", "/", "|", "\\", "︶", "︸", "︺", "﹀", "︾", "﹂", "﹄", "﹄", "︼", "︘", "/", "|", "\", + "_", "¯", "_", " ̄", "﹏", "﹋", "﹍", "﹉", "﹎", "﹊", "`", "ˋ", "¦", "︴", "¡", "¿", "^", "ˇ", "­", "¨", "ˊ", " ", " ", + "%", "*", "-", "+", "=", "¥", "$", "(", ")" + ] + 数据 = 数据.replace(/\s/g, " ") + 数据 = 数据.replace(/\!\[(.*?)\]\(.*?\)/g, (_a, b) => { return b }) + 数据 = 数据.replace(/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/g, " ") + for (const 标点符号 of 标点符号列表) { + 数据 = 数据.replace(new RegExp("\\" + 标点符号, "g"), " ") + } + 数据 = 数据.replace(/\d+/g, " ") + 数据 = 数据.replace(/\s/g, " ") + return 数据 +} + +function 分词(数据) { + const 结巴 = require("nodejieba"); + return 结巴.cut(数据清洗(数据), true).filter(词 => 词 !== " " && !/^[0-9]*$/.test(词)) +} + +function 余弦相似度(向量1, 向量2) { + let 分子 = 0; + let 根式1 = 0; + let 根式2 = 0; + if (向量1.length == 向量2.length) { + for (let i = 0; i < 向量1.length; i++) { + 分子 += (向量1[i] * 向量2[i]) + 根式1 += (向量1[i] * 向量1[i]) + 根式2 += (向量2[i] * 向量2[i]) + } + return 分子 / (Math.sqrt(根式1) * Math.sqrt(根式2)) + } +} + + +function 文章推荐(cfg) { + const 数据集 = {}; + const 相似度集 = {}; + const 推荐集 = {} + let 所有文章中所有的词 = []; + + for (let i = 0; i < 语料库.length; i++) { + const 分词表 = 语料库[i]; + 所有文章中所有的词 = [...new Set(所有文章中所有的词.concat(分词表))] + } + const 词库 = {} + 所有文章中所有的词.forEach(e => { + 词库[e] = 0 + }) + const 包含该词的文档数库 = JSON.parse(JSON.stringify(词库)) + for (let i = 0; i < 语料库.length; i++) { + const 文章路径 = 文章库[i].path; + const 文章中的词 = 语料库[i]; + + const 词在文章中出现的次数库 = 文章中的词.reduce((词计数对象, 词名称) => { + if (词名称 in 词计数对象) { + 词计数对象[词名称]++; + } + return 词计数对象 + }, JSON.parse(JSON.stringify(词库))) + + 数据集[文章路径] = {}; + 数据集[文章路径]["词频"] = JSON.parse(JSON.stringify(词库)); + for (const 词 of Object.keys(词库)) { + 数据集[文章路径]["词频"][词] = 词在文章中出现的次数库[词] / 文章中的词.length; + if (词在文章中出现的次数库[词]) { + 包含该词的文档数库[词]++; + } + } + } + + for (let i = 0; i < 语料库.length; i++) { + const 文章路径 = 文章库[i].path; + 数据集[文章路径]["逆文档频率"] = JSON.parse(JSON.stringify(词库)); + 数据集[文章路径]["词频-逆文档频率"] = JSON.parse(JSON.stringify(词库)); + 数据集[文章路径]["词频向量"] = [] + for (const 词 of Object.keys(词库)) { + const 逆文档频率 = Math.log(语料库.length / (包含该词的文档数库[词] + 1)) + const 词频逆文档频率 = 数据集[文章路径]["词频"][词] * 逆文档频率 + // 数据集[文章路径]["逆文档频率"][词] = 逆文档频率 + // 数据集[文章路径]["词频-逆文档频率"][词] = 词频逆文档频率 + 数据集[文章路径]["词频向量"].push(词频逆文档频率) + } + } + for (let i = 0; i < 语料库.length; i++) { + const 文章路径1 = 文章库[i].path; + 相似度集[文章路径1] = {} + for (let j = 0; j < 语料库.length; j++) { + const 文章路径2 = 文章库[j].path; + 相似度集[文章路径1][文章路径2] = 余弦相似度(数据集[文章路径1]["词频向量"], 数据集[文章路径2]["词频向量"]); + } + for (let j = 0; j < 语料库.length; j++) { + 推荐集[文章路径1] = Object.keys(相似度集[文章路径1]).sort(function (a, b) { + return 相似度集[文章路径1][b] - 相似度集[文章路径1][a]; // 降序 + }) + } + const index = 推荐集[文章路径1].indexOf(文章路径1); + if (index > -1) { + 推荐集[文章路径1].splice(index, 1); + } + 推荐集[文章路径1] = 推荐集[文章路径1].slice(0, cfg.max_count); + for (let j = 0; j < 推荐集[文章路径1].length; j++) { + const e = 推荐集[文章路径1][j]; + 推荐集[文章路径1][j] = 文章库.filter(w => w.path == e)[0] + } + } + hexo.locals.set('推荐集', function () { + return 推荐集 + }); + // console.log(hexo.locals.get('推荐集')); +} + +hexo.extend.helper.register('文章推荐生成器', function (post) { + if (!post) return ''; + const cfg = hexo.theme.config.recommended_article; + if (!cfg.enable) { + return ""; + } + for (const dir of cfg.skip_dirs) { + if (new RegExp("^" + dir, "g").test(post.path)) { + return ""; + } + } + const 推荐集 = hexo.locals.get('推荐集'); + const 推荐文章 = 推荐集[post.path]; + //console.log(post.path); + //console.log(推荐文章); + return 用户界面(推荐文章, cfg); +}); + +function 用户界面(推荐文章, cfg) { + let html = "" + for (const item of 推荐文章) { + html += Item界面(item) + } + return `
+
+ ${cfg.title} +
+
${html}
+
` +} + +function Item界面(item) { + return ` + ${item.title} + ${item.title} +` +} \ No newline at end of file diff --git a/source/css/fonts.css b/source/assets/fonts.css similarity index 100% rename from source/css/fonts.css rename to source/assets/fonts.css diff --git a/source/css/odometer-theme-minimal.css b/source/assets/odometer-theme-minimal.css similarity index 100% rename from source/css/odometer-theme-minimal.css rename to source/assets/odometer-theme-minimal.css diff --git a/source/css/common/codeblock/code-block.styl b/source/css/common/codeblock/code-block.styl index b944b767..5a3d4cbb 100755 --- a/source/css/common/codeblock/code-block.styl +++ b/source/css/common/codeblock/code-block.styl @@ -70,6 +70,20 @@ if (hexo-config('code_block.style') == 'mac') { box-shadow var(--redefine-box-shadow-flat) padding-top 20px margin-top 10px + position relative + + figcaption { + font-weight bold + font-size 16px + position absolute + top 12px + left 50% + transform translateX(-50%) + + a { + margin-left 10px + } + } &::before { position absolute @@ -119,6 +133,20 @@ if (hexo-config('code_block.style') == 'mac') { border-radius $redefine-border-radius-large padding-top 20px margin-top 10px + position relative + + figcaption { + font-weight bold + font-size 16px + position absolute + top 16px + left 50% + transform translateX(-50%) + + a { + margin-left 10px + } + } .folded { figure { diff --git a/source/css/common/codeblock/highlight.styl b/source/css/common/codeblock/highlight.styl index 2335dcf8..582d1ac3 100755 --- a/source/css/common/codeblock/highlight.styl +++ b/source/css/common/codeblock/highlight.styl @@ -41,10 +41,33 @@ pre { @extend $code-block border-radius $redefine-border-radius-large-bottom padding-bottom 5px + overflow: auto if (hexo-config('code_block.style') == 'mac') { border-top 1px solid var(--shadow-color-1) } + &:hover::-webkit-scrollbar-thumb { + border: 3px solid rgba(183, 183, 183, 0.3); + } + + &::-webkit-scrollbar { + width 6px + height 6px + transition all 0.2s ease + display block + } + + &::-webkit-scrollbar-track { + background transparent + border none + } + + &::-webkit-scrollbar-thumb { + border-radius: 20px; + border: 3px solid rgba(183, 183, 183, 0); + transition all 0.2s ease + } + pre { border none margin 0 diff --git a/source/css/layout/_partials/404.styl b/source/css/layout/_partials/404.styl new file mode 100644 index 00000000..cda05401 --- /dev/null +++ b/source/css/layout/_partials/404.styl @@ -0,0 +1,17 @@ +.nf-container{ + width 100% + text-align: center +} + +.nf-text{ + vertical-align middle +} + +.nf-text h1{ + line-height 1 + font-size 100px + vertical-align baseline + display inline-block + padding-right 12px + color var(first-text-color) +} diff --git a/source/css/layout/_partials/menu.styl b/source/css/layout/_partials/menu.styl index c46ef9e3..d1e3e77e 100755 --- a/source/css/layout/_partials/menu.styl +++ b/source/css/layout/_partials/menu.styl @@ -131,13 +131,18 @@ $logo-image-box-width = 46px .menu-item { float left - padding 5px + //padding 5px position relative margin-left 30px font-size 1rem cursor pointer color var(--default-text-color) + a { + display block + padding 5px + } + &:first-child { margin-left 0 } @@ -194,7 +199,7 @@ $logo-image-box-width = 46px -webkit-transform translate(-50%, 0) -o-transform translate(-50%, 0) transform translate(-50%, 0) - margin-top 8px + margin-top 0px width auto text-align: center; list-style:none; diff --git a/source/css/layout/_partials/toc.styl b/source/css/layout/_partials/toc.styl index 0924a3f0..8f3ee008 100755 --- a/source/css/layout/_partials/toc.styl +++ b/source/css/layout/_partials/toc.styl @@ -4,9 +4,8 @@ box-sizing border-box font-family "Noto Sans", sans-serif - - .post-toc { + .toc-title { font-size 0.8rem @@ -22,8 +21,6 @@ } ol { - - ol { border-left 2px dotted var(--shadow-color-1) diff --git a/source/css/layout/article-content.styl b/source/css/layout/article-content.styl index 832bd29c..3c4388dd 100755 --- a/source/css/layout/article-content.styl +++ b/source/css/layout/article-content.styl @@ -5,6 +5,7 @@ $article-title-font-size = 3.2rem $temp-toc-width = hexo-config('style.right_side_width') $toc-container-width = $temp-toc-width ? convert($temp-toc-width) : 210px $without-toc-container-width = calc(100% - 210px) +$gap = 30px .post-page-container{ display flex position relative @@ -16,6 +17,28 @@ $without-toc-container-width = calc(100% - 210px) &.show-toc { .toc-content-container { display block + + &:hover::-webkit-scrollbar-thumb { + border: 3px solid rgba(183, 183, 183, 0.3); + } + + &::-webkit-scrollbar { + width 6px + height 6px + transition all 0.2s ease + display block + } + + &::-webkit-scrollbar-track { + background transparent + border none + } + + &::-webkit-scrollbar-thumb { + border-radius: 20px; + border: 3px solid rgba(183, 183, 183, 0); + transition all 0.2s ease + } } .article-content-container { @@ -322,6 +345,72 @@ $without-toc-container-width = calc(100% - 210px) } } } + + .recommended-article{ + overflow: visible !important + .recommended-article-header{ + margin 2rem 0 0.8rem 0 + font-size 1.2rem + font-weight bold + } + .recommended-article-group{ + padding 10px + display: flex + flex-wrap: wrap + overflow: visible !important + @media screen and (max-width: $device-tablet){ + height: 190px + overflow: scroll + &::-webkit-scrollbar{ + width: 0 !important + } + -ms-overflow-style: none + } + .recommended-article-item{ + redefine-container(false, 0, 0, 10px, 0) + box-shadow var(--redefine-box-shadow-flat) + padding 12px !important + display: flex + flex-wrap: wrap + align-content: center; + justify-content: center; + align-items: center; + overflow: hidden + width: "calc(100%/3 - %s)" % ($gap * 0.6) + @media screen and (max-width: $device-tablet){ + width: "calc(100%/2 - %s)" % ($gap * 0.6) + } + @media screen and (max-width: $device-mobile){ + width: "calc(100% - %s)" % ($gap * 0.6) + } + max-height: 200px + margin-top: $gap * 0.5 + margin-left: $gap * 0.5 + margin-right: 0 + &:nth-child(3n+1) { + margin-left 0 !important + } + img{ + display: flex; + width: calc(100% + 24px) + height: 150px + object-fit: cover + border-radius $redefine-border-radius-medium-top + margin -12px -12px 0 -12px !important + + } + span{ + margin-top 0.5rem + display: block + display: -webkit-box + -webkit-box-orient: vertical + -webkit-line-clamp: 1; + overflow: hidden + } + } + } + + } } .toc-content-container { diff --git a/source/css/style.styl b/source/css/style.styl index 60a9999f..372d4c47 100755 --- a/source/css/style.styl +++ b/source/css/style.styl @@ -26,6 +26,7 @@ @import "layout/category-content.styl" @import "layout/tag-content.styl" @import "layout/_partials/tagcloud.styl" +@import "layout/_partials/404.styl" // modules @import "layout/_modules/notes.styl" @import "layout/_modules/folding.styl" diff --git a/source/css/all.min.css b/source/fontawesome/all.min.css similarity index 100% rename from source/css/all.min.css rename to source/fontawesome/all.min.css diff --git a/source/css/brands.min.css b/source/fontawesome/brands.min.css similarity index 100% rename from source/css/brands.min.css rename to source/fontawesome/brands.min.css diff --git a/source/css/duotone.min.css b/source/fontawesome/duotone.min.css similarity index 100% rename from source/css/duotone.min.css rename to source/fontawesome/duotone.min.css diff --git a/source/css/fontawesome.min.css b/source/fontawesome/fontawesome.min.css similarity index 100% rename from source/css/fontawesome.min.css rename to source/fontawesome/fontawesome.min.css diff --git a/source/css/light.min.css b/source/fontawesome/light.min.css similarity index 100% rename from source/css/light.min.css rename to source/fontawesome/light.min.css diff --git a/source/css/regular.min.css b/source/fontawesome/regular.min.css similarity index 100% rename from source/css/regular.min.css rename to source/fontawesome/regular.min.css diff --git a/source/css/solid.min.css b/source/fontawesome/solid.min.css similarity index 100% rename from source/css/solid.min.css rename to source/fontawesome/solid.min.css diff --git a/source/css/svg-with-js.min.css b/source/fontawesome/svg-with-js.min.css similarity index 100% rename from source/css/svg-with-js.min.css rename to source/fontawesome/svg-with-js.min.css diff --git a/source/css/thin.min.css b/source/fontawesome/thin.min.css similarity index 100% rename from source/css/thin.min.css rename to source/fontawesome/thin.min.css diff --git a/source/css/v4-font-face.min.css b/source/fontawesome/v4-font-face.min.css similarity index 100% rename from source/css/v4-font-face.min.css rename to source/fontawesome/v4-font-face.min.css diff --git a/source/css/v4-shims.min.css b/source/fontawesome/v4-shims.min.css similarity index 100% rename from source/css/v4-shims.min.css rename to source/fontawesome/v4-shims.min.css diff --git a/source/css/v5-font-face.min.css b/source/fontawesome/v5-font-face.min.css similarity index 100% rename from source/css/v5-font-face.min.css rename to source/fontawesome/v5-font-face.min.css