matery主题的代码块问题解决


一、 问题描述

Hexo的matery主题中的代码块出现代码大小不一代码键复制无法高亮等BUG。

二、 问题解决

大部分采取http://luckyzmj.cn/posts/1b9a9e28.html该博客的方法,但出现了2个BUG

一键复制的图标不显示代码块中的{}不解析

本文解决了两个问题

1. 安装代码块插件
npm i -S hexo-prism-plugin
2. 配置Hexo根目录的.config.yml

注意是Hexo的根目录,不是主题目录

highlight:
  enable: false # 关闭原有的高亮代码

# 添加prism_plugin配置项
prism_plugin:
  mode: 'preprocess'    # realtime/preprocess
  theme: 'tomorrow'
  line_number: true    # default false
  custom_css: 
3. 配置Matery根目录的.config
code:
  lang: true # 代码块是否显示名称
  copy: true # 代码块是否可复制
  shrink: true # 代码块是否可以收缩
  break: false # 代码是否折行
4. 修改代码块css

打开themes\source\css\matery.css,大概在100到200行左右,修改代码块CSS样式如下

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,添加如下代码

<!-- 代码块功能依赖 -->
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeBlockFuction.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文件,并添加如下代码

// 代码块功能依赖
$(function () {
    $('pre').wrap('<div class="code-area" style="position: relative"></div>');
});

themes\matery\source\libs\codeBlock目录下新建codeCopy.js文件,并添加如下代码

:此处和Lucky Me大佬的不同,他的代码在我这里运行复制的图标不显示,估计是缺失,将他代码中的2处fa-files-o改为fa-copy即可。

// 代码块一键复制
$(function () {
    var $copyIcon = $('<i class="fa fa-copy 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-copy').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文件,并添加如下代码

// 代码块语言识别
$(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文件,并添加如下代码

// 代码块收缩
$(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');
    }
  });
});

优化完成,运行,又发现问题代码块中的{}无法解析

三、 代码块中的{}无法解析问题解决

node_modules/hexo-prism-plugin/src/index.js文件中map里未支持大括号,补上以下内容后发现有效,即在map中加上对应字符即可:

const map = {
  '&#39;': '\'',
  '&amp;': '&',
  '&gt;': '>',
  '&lt;': '<',
  '&quot;': '"',
  '&#123;': '{',    //添加的代码
  '&#125;': '}'        //添加的代码
};

  目录