Hexo-Fluid实现mac panel风格代码块

本文最后更新于:2 年前

前言


一直以来看别人博客都觉的Mac风格的代码块很炫酷,这几天尝试自己搭建博客,选中了Fluid这个主题,但是仅限于支持设定的两种风格。

# 实现高亮的库,对应下面的设置
# Options: highlightjs | prismjs
lib: "highlightjs"

highlightjs:
# 在链接中挑选 style 填入
# See: https://highlightjs.org/static/demo/
style: "Monokai Sublime"

# 是否根据 style 改变代码背景色(如果 style 是深色背景别忘了开启此项)
bg_color: true

prismjs:
# 在下方链接页面右侧的圆形按钮挑选 style 填入,也可以直接填入 css 链接
# See: https://prismjs.com/
style: "default"

# 设为 true 高亮将本地静态生成(并只支持部分 prismjs 插件),设为 false 高亮将在浏览器通过 js 生成
preprocess: true

这就让人很为难了,因为也看过一些教程,大多是next怎么做的。找了半天发现了相关为Yilia主题代码块添加Mac Panel效果的一篇教程。[1]所以就跟着弄了一下,也踩了一些坑,花了半天时间终于搞定了。哈哈~记录一下。

需要的条件


需要有一点点的css和JavaScript基础以及找寻代码判断相关性的能力。

大致思想及流程


  1. 自动更改样式。首先得大致知道hexo是如何把markdown的代码渲染出来的,在这个过程之后又怎样匹配出来了自己在ymal中定义的样式呢?

根据highlightjs和prismjs作为关键字,通过一番查找找到了/fluid/scripts/events/lib/highlights.js,该js函数调用了hexo的生命周期在恰当的时间点博客中代码块内容进行替换,从而使得原有的代码块样式能够被替换指定的风格块。

  1. 找到了之后如何做呢?首先需要分析代码做了哪些工作。
if (config.code.highlight.lib === 'highlightjs') {
    hexo.config.prismjs = objUtil.merge({}, hexo.config.prismjs, {
        enable: false
    });
    hexo.config.highlight = objUtil.merge({}, hexo.config.highlight, {
        enable     : true,
        hljs       : true,
        wrap       : false,
        auto_detect: true,
        line_number: config.code.highlight.line_number || false
    });
    hexo.extend.filter.register('after_post_render', (page) => {
        if (config.code.highlight.highlightjs.bg_color) {
            page.content = page.content.replace(/(?<!<div class="hljs code-wrapper">)(<pre.+?<\/pre>)/gims, (str, p1) => {
                if (/<code[^>]+?mermaid[^>]+?>/ims.test(p1)) {
                    return str.replace(/(class=".*?)hljs(.*?")/gims, '$1$2');
                }
                return `<div class="hljs code-wrapper">${p1}</div>`;
            });
            page.content = page.content.replace(/<td class="gutter/gims, '<td class="gutter hljs');
        } else if (!hexo.config.highlight.line_number) {
            page.content = page.content.replace(/(?<!<div class="code-wrapper">)(<pre.+?<\/pre>)/gims, (str, p1) => {
                if (/<code[^>]+?mermaid[^>]+?>/ims.test(p1)) {
                    return str.replace(/(class=".*?)hljs(.*?")/gims, '$1$2');
                }
                return `<div class="code-wrapper">${p1}</div>`;
            });
        }
        if (hexo.config.highlight.line_number) {
            // Mermaid block adaptation
            page.content = page.content.replace(/<figure.+?<td class="code">.*?(<pre.+?<\/pre>).+?<\/figure>/gims, (str, p1) => {
                if (/<code[^>]+?mermaid[^>]+?>/ims.test(p1)) {
                    return p1.replace(/(class=".*?)hljs(.*?")/gims, '$1$2').replace(/<br>/gims, '\n');
                }
                return str;
            });
        }
        return page;
    });

好长的一段啊,但是大概是说禁用prismjs,然后根据yaml设置highlightjs的相关参数生成高亮配置参数。然后注入了一个渲染后的事件,传入渲染后的页面进行一些正则替换,主要是改变class,然后把替换好的代码包裹在一个div里边,注意,div的class为code-wrapper

  1. 实施替换

看到教程中提到的某段话:

添加了自动更换样式的脚本后,我们将需要替换到代码块的样式放入主题的css文件夹中,以便于浏览器能够正常渲染。在Yilia主题路径\source-src\css下,新建css文件,文件名为code-block.css。并复制以下代码blablabla……

也就是说这个class就是我们后期渲染的关键。我们再找找Fluid是怎么渲染的呢?又是一段查找,.styl文件用于存放css样式,所以顺藤摸瓜找到了主题source目录下的css目录,一番折腾发现存放于该目录下_page下的rewrite.styl中。\fluid\source\css_pages_base

根据关键字code-wrapper我们找到了定义的样式:

& > .code-wrapper
  position relative
  border-radius 3px

这么简单嘛?那么我们就注释掉这段开始自定义样式咯,参照教程在新建在css目录下新建_custom目录,创建macpanel.styl。并在main.styl中引入。

.code-wrapper{
  position: relative;
  overflow: hidden;
  border-radius: 5px;
  box-shadow: 0 10px 10px 0px rgba(0, 0, 0, 0.4);
  margin: 30px 0;
  ::-webkit-scrollbar {
    height: 10px;
  }
  ::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
    border-radius: 10px;
  }

  ::-webkit-scrollbar-thumb {
    border-radius: 10px;
    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
  }
  &::before {
    color: white;
    content: attr(data-rel);
    height: 30px;
    line-height: 30px;
    background: #21252b;
    color: #fff;
    font-size: 16px;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    font-family: 'Source Sans Pro', sans-serif;
    font-weight: bold;
    padding: 0px 80px;
    text-indent: 15px;
    float: left;
  }
  &::after {
    content: ' ';
    position: absolute;
    -webkit-border-radius: 50%;
    border-radius: 50%;
    background: #fc625d;
    width: 12px;
    height: 12px;
    top: 0;
    left: 20px;
    margin-top: 13px;
    -webkit-box-shadow: 20px 0px #fdbc40, 40px 0px #35cd4b;
    box-shadow: 20px 0px #fdbc40, 40px 0px #35cd4b;
    z-index: 3;
  }
}

.code-wrapper > pre {
	margin-bottom 0
}

可能我还动了一些地方的css样式,但是大概都是调位置之类的[2],掌握沙盒模型然后调节rewrite和自定义的macpanel两个样式文件就可以了。效果就是你们看到的这样啦~

总结


不折腾不痛快,所以需要一颗爱折腾的心……



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!