前言
在官方最新版本的Matery主题版本中已经优化了代码块的问题,但在旧版本Hexo主题Matery中对hexo-prism-plugin只支持高亮显示,而且存在着许多的BUG。比如新版本的hexo-prism-plugin已经支持了代码块的一键复制和收缩功能,如果不手动对旧版本Matery原有的代码做改动,则代码块显示会存在一些问题。
代码块优化
1. 安装代码块插件
1
| npm i -S hexo-prism-plugin
|
2. Hexo根目录配置
打开Hexo根目录的配置文件_config.yml
,修改并添加如下代码
1 2 3 4 5 6 7 8 9
| highlight: enable: false
prism_plugin: mode: 'preprocess' theme: 'tomorrow' line_number: true custom_css:
|
3. Matery主题根目录
打开Matery主题的配置文件themes\matery\_config.yml
,添加如下代码
1 2 3 4 5
| code: lang: true copy: true shrink: true break: false
|
4. 代码块CSS优化
打开themes\source\css\matery.css
,大概在100到200行左右,修改代码块CSS样式如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| pre { padding: 1.5rem 1.5rem 1.5rem 3.3rem !important; margin: 1rem 0 !important; background: #272822; overflow: auto; border-radius: 0.35rem; tab-size: 4; } .code-area::after { content: " "; position: absolute; border-radius: 50%; background: #ff5f56; width: 12px; height: 12px; top: 0; left: 12px; margin-top: 12px; -webkit-box-shadow: 20px 0 #ffbd2e, 40px 0 #27c93f; box-shadow: 20px 0 #ffbd2e, 40px 0 #27c93f; } code { padding: 1px 5px; top: 13px !important; font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace; font-size: 0.91rem; color: #e96900; background-color: #f8f8f8; border-radius: 2px; } .code_copy { position: absolute; top: 0.7rem; right: 25px; z-index: 1; filter: invert(50%); cursor: pointer; } .codecopy_notice { position: absolute; top: 0.7rem; right: 6px; z-index: 1; filter: invert(50%); opacity: 0; } .code_lang { position: absolute; top: 1.2rem; right: 46px; line-height: 0; font-weight: bold; font-family: normal; z-index: 1; filter: invert(50%); cursor: pointer; }
.code-expand { position: absolute; top: 4px; right: 0px; filter: invert(50%); padding: 7px; z-index: 999 !important; cursor: pointer; transition: all .3s; transform: rotate(0deg); }
.code-closed .code-expand { transform: rotate(-180deg) !important; transition: all .3s; }
.code-closed pre::before { height: 0px; }
pre code { padding: 0; color: #e8eaf6; background-color: #272822; }
pre[class*="language-"] { padding: 1.2em; margin: .5em 0; }
code[class*="language-"], pre[class*="language-"] { color: #e8eaf6; white-space: pre-wrap !important; }
.line-numbers-rows { border-right-width: 0px !important; }
.line-numbers { padding: 1.5rem 1.5rem 1.5rem 3.2rem !important; margin: 1rem 0 !important; background: #272822; overflow: auto; border-radius: 0.35rem; tab-size: 4; }
|
5. 文章代码块添加
打开themes\matery\layout\_partial\post-detail.ejs
,添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeBlockFunction.js') %>"></script>
<% if (theme.code.lang) { %> <script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeLang.js') %>"></script> <% } %>
<% if (theme.code.copy) { %> <script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeCopy.js') %>"></script> <% } %>
<% if (theme.code.shrink) { %> <script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeShrink.js') %>"></script> <% } %>
<% if (!theme.code.break) { %> <style type="text/css"> code[class*="language-"], pre[class*="language-"] { white-space: pre !important; } </style> <% } %>
|
6. 代码块JS添加
打开目录themes\matery\source\libs
,新建一个名字为codeBlock
的目录,然后打开该目录。
在themes\matery\source\libs\codeBlock
目录下新建codeBlockFunction.js
文件,并添加如下代码
1 2 3 4
| // 代码块功能依赖 $(function () { $('pre').wrap('<div class="code-area" style="position: relative"></div>'); });
|
在themes\matery\source\libs\codeBlock
目录下新建codeCopy.js
文件,并添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| // 代码块一键复制 $(function () { var $copyIcon = $('<i class="fa fa-files-o code_copy" title="复制代码" aria-hidden="true"></i>') var $notice = $('<div class="codecopy_notice"></div>') $('.code-area').prepend($copyIcon) $('.code-area').prepend($notice) // “复制成功”字出现 function copy(text, ctx) { if (document.queryCommandSupported && document.queryCommandSupported('copy')) { try { document.execCommand('copy') // Security exception may be thrown by some browsers. $(ctx).prev('.codecopy_notice') .text("复制成功") .animate({ opacity: 1, top: 30 }, 450, function () { setTimeout(function () { $(ctx).prev('.codecopy_notice').animate({ opacity: 0, top: 0 }, 650) }, 400) }) } catch (ex) { $(ctx).prev('.codecopy_notice') .text("复制失败") .animate({ opacity: 1, top: 30 }, 650, function () { setTimeout(function () { $(ctx).prev('.codecopy_notice').animate({ opacity: 0, top: 0 }, 650) }, 400) }) return false } } else { $(ctx).prev('.codecopy_notice').text("浏览器不支持复制") } } // 复制 $('.code-area .fa-files-o').on('click', function () { var selection = window.getSelection() var range = document.createRange() range.selectNodeContents($(this).siblings('pre').find('code')[0]) selection.removeAllRanges() selection.addRange(range) var text = selection.toString() copy(text, this) selection.removeAllRanges() }) });
|
在themes\matery\source\libs\codeBlock
目录下新建codeLang.js
文件,并添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // 代码块语言识别 $(function () { var $highlight_lang = $('<div class="code_lang" title="代码语言"></div>');
$('pre').before($highlight_lang); $('pre').each(function () { var code_language = $(this).attr('class');
if (!code_language) { return true; }; var lang_name = code_language.replace("line-numbers", "").trim().replace("language-", "").trim();
// 首字母大写 // lang_name = lang_name.slice(0, 1).toUpperCase() + lang_name.slice(1); $(this).siblings(".code_lang").text(lang_name); }); });
|
在themes\matery\source\libs\codeBlock
目录下新建codeShrink.js
文件,并添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 代码块收缩 $(function () { var $code_expand = $('<i class="fa fa-angle-down code-expand" aria-hidden="true"></i>');
$('.code-area').prepend($code_expand); $('.code-expand').on('click', function () { if ($(this).parent().hasClass('code-closed')) { $(this).siblings('pre').find('code').show(); $(this).parent().removeClass('code-closed'); } else { $(this).siblings('pre').find('code').hide(); $(this).parent().addClass('code-closed'); } }); });
|
7. 解决代码块复制内容不换行问题
Matery主题在开启复制版权且添加了版权信息后,会导致复制的所有内容换行失效,以下将解决这个问题。
在themes\matery\layout\_partial\post-detail.ejs
文件中,大约在222行左右找到 selection.getRangeAt(0).commonAncestorContainer.nodeName
,将原先if
条件中的的PRE
修改为CODE
即可。
1 2 3
| if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'CODE') { newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>"; }
|
至此,代码块的优化已经全部完成。