用Hugo+码云搭建支持Markdown+LaTeX的云笔记

用Hugo+码云搭建支持Markdown+LaTeX的云笔记

2020-01-07
| 杂事 | | hugo , 码云 , typora , markdown , latex | Comment 评论

目标(配置好后的日常操作)

更新流程简单舒服,页面主题简洁,完全支持Markdown+LaTeX。

1)本地撰写内容:用Typora写基于Markdown+LaTeX的内容。

2)利用静态网站生成器Hugo生成待发布的静态文件: 执行./forgitee

  • 这个脚本实际依次执行了:1. 对所有md文件进行部分内容替换,确保站点可以完全解析; 2. 执行hugo -D,生成待发布的静态文件,生成文件夹public; 3. 执行./fortypora对所有md文件进行逆向置换复原,确保Typora打开能完全显示正常。

3) 将站点git提交码云(gitee)https://gitee.com/chaoskey/notes

  • 包括站点全部源码(相当于文档云同步)和生成的静态文件目录public

4) 部署到: https://chaoskey.gitee.io/notes

5) 一键发布的脚本./publish(注意,必须根据你自己的情况修改之),依次执行了: 1. ./forgitee; 2. 将修改过的笔记提交到master分支; 3. 将public提交到gh-pages分支; 4. 将gh-pages分支pushgiteegithub

0103.jpg


第一步:安装git

我选择的是官方winGUI版本,国内很难下载,建议翻墙下载。默认选项安装即可。

由于官方版本本来就支持shell,后面的操作主要是在git bash下进行,如果GUI更方便时就使用GUI。

第二步:安装Hugo

选择Hugo的原因,是因为配置简单、库依赖度很低。

依然选择官方win版本,翻墙下载。

我选择的是hugo_extended_0.64.1_Windows-64bit.zip,解压,设置好PATH就能用。

第三步:在码云上创建一个初始库

选择码云而不是GitHub的原因是众所周知,虽然可以翻墙,毕竟麻烦。

创建一个初始库即可,不用额外设置。

我所创建的库是:https://gitee.com/chaoskey/notes

第四步:建立初始站点

打开git bash,后同。

# 初始化本地站点
hugo new site notes
cd notes

打开git GUI, 将https://gitee.com/chaoskey/notes克隆到刚构建本地目录notes。 如果克隆时提示已存在,则先备份notes,克隆后再覆盖回去。

0020.jpg

先设置站点根目录 https://chaoskey.gitee.io/notes/

第五步:选择主题

我的目标是学习笔记,所以我找到一款简洁并适合的主题hugo-book

# 克隆主题到themes/book
git clone https://github.com/alex-shpak/hugo-book themes/book

# 复制主题范例站点和配置
cp -a themes/book/exampleSite/config.toml .
cp -a themes/book/exampleSite/content .

第六步:公式引擎配置(可选)

由于该主题已经支持katex,所以此步可选,对应的代码位置:

themes\book\layouts\shortcodes\katex.html

但原版默认只支持{{< katex [display] >}}latex{{< /katex >}}格式,所以我作了后面的改动,以支持$\latex$的格式,并且还通过配置支持katexmathjax

<!--
原始位置:
	themes\book\layouts\shortcodes\katex.html
也可以将其独立出来放在站点根目录下:
	layouts\shortcodes\katex.html
-->
{{ if not (.Page.Scratch.Get "katex") }}
  {{ if and (isset .Site.Params "katex") (eq .Site.Params "mathjax" ) }} 
    <!-- Include mathjax only first time -->
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
          showProcessingMessages: false,
          messageStyle: "none",
          extensions: ["tex2jax.js"],
          jax: ["input/TeX", "output/HTML-CSS"],
          tex2jax: {
              inlineMath:  [ ["$", "$"], ["\(", "\)"] ],
              displayMath: [ ["$\n","\n$"], ["\\[","\\]"] ],
              skipTags: ['script', 'noscript', 'style', 'textarea', 'pre','code','a'],
              ignoreClass:"comment-content"
          },
          "HTML-CSS": {
              availableFonts: ["STIX","TeX"],
              showMathMenu: false
          }
      });
      MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
    </script>
    <script src="https://cdn.bootcss.com/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
  {{ else }}
    <!-- Include katext only first time -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/KaTeX/0.11.1/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
    <script defer src="https://cdn.bootcss.com/KaTeX/0.11.1/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
    <script defer src="https://cdn.bootcss.com/KaTeX/0.11.1/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"
            onload="renderMathInElement(document.body,
                {delimiters: [{left: '$\n', right: '\n$', display: true}, {left: '$', right: '$', display: false}, 
                              {left: '\\[', right: '\\]', display: true}, {left: '\\(', right: '\\)', display: false}]});"></script>
  {{ end }}
{{ .Page.Scratch.Set "katex" true }}
{{ end }}


<span class="katex{{ with .Get "class" }} {{ . }}{{ end }}">
  {{ if in .Params "display" }}\[{{ else }}\({{ end -}}
  {{ $.Inner }}
  {{- if in .Params "display" }}\]{{ else }}\){{ end }}
</span>

然后,在config.toml中添加一段配置,默认使用katex引擎

  #######################################
  # (Optional, default none) 选择数学公式渲染引擎
  # 默认就是katex引擎,  另外的选择就是 mathjax引擎 (即使改了引擎,标签也继续沿用katex)
  # 优先使用$$作为公式界定符号
  #  1. 内联公式,比如: $a^2$
  #  2. 块公式,比如:
  #     $$
  #     a^2
  #     $$
  # 如果渲染失败时(hugo和引擎的冲突),首先作如下2个置换 
  #  1. 内联公式:\$\$(.*?\\[\\\}\{].*?)\$\$ => {{< katex >}}$1{{< /katex >}}
  #  2. 块公式:\$\$(\n.*?\\[\\\}\{].*?\n)\$\$ => {{< katex display >}}$1{{< /katex >}}
  # 如果还是失败,则修改公式。
  #######################################
  # katex = "mathjax"

第七步:Typora和Hugo站点协调

由于Hugo的Markdown解析机制和$$格式下的公式有时存在冲突,导致在Typora显示正常的公式,在Hugo解析Markdown时会错误显示或不显示公式。

为了解决这个问题,我写了两个shell脚本:

1) ./fortypora: 执行后确保用Typora打开本地md文件可以正常渲染,特别是数学公式。

#!/bin/bash

# 执行后确保用Typora打开本地md文件可以正常渲染,特别是数学公式。
# 将`{{< katex [display] >}}latex{{< /katex >}}`
# 转换成$$格式
# ./fortypora

# md文件递归
function action(){
    for file in `ls $1` 
    do
        if [ -d $1"/"$file ] 
        then
            action $1"/"$file
        elif [ "${file#*.}"x = "md"x ]
        then
            # 方便用typora阅读
            sed -i 's/{{<\s*katex\s*>}}/$/g; s/{{<\s*katex\s*display\s*>}}/$/g; s/{{<\s*\/katex\s*>}}/$$/g; s/!\[.*\](\.\.\/\.\.\/images\//![](..\/images\//g; '  $1"/"$file
        fi
    done
} 

action ./content

2)./forgitee: 执行后确保用Hugo生成的站点可以正常渲染,特别是数学公式。

#!/bin/bash

# 执行后确保用Hugo生成的站点可以正常渲染,特别是数学公式。
# 先将`$$`
# 转换成`{{< katex [display] >}}latex{{< /katex >}}`
# 再执行 hugo [servere] -D 命令
# ./forgitee       # 站点发布(生成静态文件)
# ./forgitee server  # 站点预览

# md文件递归
function action(){
    for file in `ls $1` 
    do
        if [ -d $1"/"$file ] 
        then
            action $1"/"$file
        elif [ "${file#*.}"x = "md"x ]
        then
            # 方便发布到gitee
            sed -i '/```/ { :begin1; /```.*```/! { $! { N; b begin1 }; }; n; }; /\$\$/ { :begin2; /\$\$[^$]*\$\$/! { $! { N; b begin2 }; }; }; s/\$\$\(\n[^$]*\n\)\$\$/{{< katex display >}}\1{{< \/katex >}}/g; s/\$\$\([^$]*\)\$\$/{{< katex >}}\1{{< \/katex >}}/g; s/!\[.*\](\.\.\/images\//![](..\/..\/images\//g;'  $1"/"$file
        fi
    done
} 

action ./content

if [ "$1"x = "server"x ] 
then
    # 本地预览
    hugo server --disableFastRender -D
else
    rm -rf public 
    # 生成待发布的静态文件,生成的目录 public
    hugo -D
    # 方便用typora阅读
    ./fortypora
fi