这是基于 Hugo 系列主题第一篇文章,因为之前是在 Jekyll 上进行渲染,故而 Hello World也有更新

为啥变动

那么为啥从 Jekyll 变到 Hugo 呢?原因其实有几点:

  1. 之前用的主题看着不好看,感觉很拥挤,之前想改没空,想要个简洁干净,专注于内容的主题
  2. Jekyll 在服务器端的渲染速度实在是不快(本地却很快,不懂)
  3. Hugo 的设计更符合我的直觉,而且方便自定义好玩的功能,比如 shortcode 功能

主要是被另一位博主 Li’s Blog 用的主题吸引,就立马换成了新的主题 PaperMod,然而这个主题虽然简洁,但是少了一些我认为必须得有的功能,比如渲染公式,侧边目录等。于是任着喜欢「折腾」的性子,从零开始学 Hugo 的语法,然后四处借鉴学习,花了两天时间添加了一些功能,当然,这篇文章主要介绍相关的 feature,不会涉及到具体的实现

没有一个主题能完全满足个人的需求,还是从底层原理出发,这样才能「自由自在」地进行更改

支持features

基于的主题 PaperMod 的相关 features 便不在继续介绍,介绍一些我加入的特性

  1. 公式渲染:这个主题一开始是没有公式渲染功能的,我通过引入 MathJax 来完成这一点,行内公式如:$a+b=c$,行间公式效果如下:

    $$ e^{\pi i} + 1 = 0 $$

    然而,Hugo 是先将markdown渲染成HTML,接着才会轮到Mathjax进行渲染,这就导致很多公式就渲染不出,想了两种办法:- 将公式用div标签套起来,这样就不会被误判,然而这会增加平时写公式的负担,用shortcode来完成,还是有点臃肿 - 将公式用代码的样式包裹起来,再写一点js来保留原来公式的部分,比如公式(公式依旧带美元符号),这个更简便

    从平时的 markdown 公式书写转到带有代码样式包裹的公式可用下列代码:

    def inline_replace(line):
        new_line = ''
        patterns = line.split('$')
        for (idx, l) in enumerate(patterns):
            tex = '`$' if idx % 2 == 0 else '$`'
            if idx == len(patterns)-1 and tex == '`$':
                tex = ''
            new_line += l + tex
        return new_line
    
    
    path = 'content/posts/Determinantal-Point-Process.md'
    lines = [line.rstrip() for line in open(path, encoding='utf-8')]
    
    count = 0
    new_lines = []
    for line in lines:
        if line == '':
            new_lines[-1] += '\n'
            continue
        if line == '$$':
            if count % 2 == 0:
                new_lines.append('`$$')
            else:
                new_lines.append('$$`')
            count += 1
            continue
        new_lines.append(inline_replace(line))
    
    
    with open(path, 'w', encoding='utf-8') as w:
        for line in new_lines:
            w.write(line + '\n')
    
  2. 伪代码的书写:引入伪代码图片实在是丑得难以接受,我通过引入额外的js来实现这一点,本身是以HTML形式书写的,为了减轻负担,立马改成了shortcode,示例如下:

        \begin{algorithm}
        \caption{Quicksort}
        \begin{algorithmic}
        \PROCEDURE{Quicksort}{$A, p, r$}
        \IF{$p < r$}
        \STATE $q = $ \CALL{Partition}{$A, p, r$}
                \STATE \CALL{Quicksort}{$A, p, q - 1$}
                \STATE \CALL{Quicksort}{$A, q + 1, r$}
            \ENDIF
        \ENDPROCEDURE
        \PROCEDURE{Partition}{$A, p, r$}
            \STATE $x = A[r]$
        \STATE $i = p - 1$
        \FOR{$j = p$ \TO $r - 1$}
        \IF{$A[j] < x$}
        \STATE $i = i + 1$
        \STATE exchange
        $A[i]$ with $A[j]$
        \ENDIF
        \STATE exchange $A[i]$ with $A[r]$
        \ENDFOR
        \ENDPROCEDURE
        \end{algorithmic}
        \end{algorithm}
        

  3. 评论功能:这个功能我在之前的主题也实现过,不同于各种基于 github 的评论系统,需要账号,waline 不需要账户,十分方便,而且可以加入很多有趣的表情,可以在页面最底部输入试试看

  4. 侧边目录:原主题对目录的设置是将目录固定放在文章顶部,这样不利于对于长文整体的把握,故而将目录移动到了侧边,并且修改了一些 css 设置,自动高亮当前目录并且给它添加下划线,这样可以清楚地发现此时的章节

  5. MarginNote:以往 markdown 都是仅支持脚注,这样不利于文章的阅读,查看相关引用信息需要移至页面底部再返回,而 MarginNote 则给了作者更多自由的空间和方便读者阅读 The Elements of Typographic Style, 2004 而且移动至相关的标注会自动高亮对应的 MarginNote,更加方便读者阅读;同时过长会自动转行,方便进行较长的标注 Sidenotes give more life and variety to the page and are the easiest of all to find and read, If carefully designed, they need not enlarge either the page or the cost of printing it. 不过为了保持设计的简便性,没有对移动端优化(谁在手机端看文章的啊,雾)

  6. 代码渲染:原先 PaperMod 对代码的渲染真是一言难尽,属实是丑到我了,于是乎,重新自定义了相关主题,主体是用了 a11y-light.min.css 在其之上又自定义了一些颜色:

    示例代码
    class Model(nn.Module):
        # Our model
        def __init__(self, input_size, output_size):
            super(Model, self).__init__()
            # for convenience
            self.fc = nn.Linear(input_size, output_size)
    
        def forward(self, input):
            output = self.fc(input)
            print("\tIn Model: input size", input.size(),
                "output size", output.size())
            return output
    

  7. 更新时间:原先主题根本没有更新时间的设置,这样不利于读者查看文章最新的时间,文章的开头便有更新的时间,可以查看

  8. 著作权声明:现在网上各种抄袭成风,需要对自己的文章进行声明,添加至文章末尾,例如本文用的是CC BY-NC-SA 4.0. Attribution-NonCommercial-ShareAlike 4.0 International

  9. 字体:原来的字体看着有点不舒服,这里将中文换成了霞鹜文楷,观感很不错,英文的话是在几个字体中选一个:-apple-system, BlinkMacSystemFont, segoe ui, Roboto, Oxygen, Ubuntu, Cantarell 这样看起来也很舒服,选取Lorem Ipsum 进行测试 Dummy text to test the appearance

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.

  1. 中英文空白:汉学家称中文和英文之间的空白字元为「盘古之白」,大抵是因为劈开了全形字和半形字之间的混沌。在书写时适当地留白会提升观感,这个是通过盘古的js来实现的,手敲空格噼里啪啦的,倒不是很方便

  2. notice:通过shortcode 添加了各种的提示框,看起来很不错,比如:

一生疏狂尽余欢,半剖肝胆入剑寒。 剑至高危如蜀道,生逢穷途行路难。

一生疏狂尽余欢,半剖肝胆入剑寒。 剑至高危如蜀道,生逢穷途行路难。

一生疏狂尽余欢,半剖肝胆入剑寒。 剑至高危如蜀道,生逢穷途行路难。

  1. 友链:添加了友链功能,这样方便添加别人的博客,加强朋友之间的联系,可查看主页的 Friends

  2. 对于 markdown 引用的改进,原来的引用比较丑,下面是改进后的引用:

    Basically, I’m not interested in doing research and I never have been… I’m interested in understanding, which is quite a different thing. And often to understand something you have to work it out yourself because no one else has done it. — David Blackwell

  3. 点击图片进行放大,对于图片大,缩放多的情况,点击放大是很有必要的,不妨试试看:

致谢

搭建自己的主题借鉴了很多别人的经验,这里列出进行致谢:

  1. PaperMod,这是一开始基于的主题,感谢作者的开源

  2. 评论系统的支持,感谢 Waline,做的很干净

  3. 关于对代码主题的更改,主要借鉴了 HightLight.js 官方的demo

  4. 公式的渲染方面 MathJax 做的很nice

  5. 伪代码的书写主要借鉴了Pseudocode.js的官方教程,必须加鸡腿

  6. 侧边目录和一些 shortcode 的实现借鉴了 Sulv’s Blog以及 Guan Qirui

  7. 字体还得感谢 霞骛文楷,比那些收费的丑字体好太多了

  8. 盘古之白是通过pangu.js实现的,点赞

  9. MarginNote 的实现借鉴了 kennethfriedmanscripter

  10. 图片放大主要用了fancybox的功能,用起来也比较方便

秉持着开源的精神,我的网站源码也抽离出来放在这里,欢迎使用或者PR