认识 Hugo
- Hugo 是使用 Go 语言编写的高性能 Blog / 站点 框架,在全球拥有广泛的用户群和数以百计优质主题。
安装
常规安装方法
- macOS
brew install hugo
- Windows
$ choco install hugo -confirm
- Linux
$ snap install hugo
- 通过官方源安装,但这将会导致
Pandoc
和MathJax
的使用体验直线下降。 - 通常而已你会遇到这些问题:
- 如果使用默认的
Goldmark
渲染器选项- 原有 Hexo Blog 上的公式均需要以四斜杠换行,即:
\\\\
\(\to\)\\\\\\\
,这将进一步导致文章难以被其他Markdown
引擎渲染(比如你需要使用 Visual Studio Code 协同编辑你的 Blog) - 一些公式将会因为
Goldmark
极其魔幻的匹配规则被”消失“,或错位 - 一些图片将会因为
Goldmark
极不具宽容度的Markdown
语法匹配(尽管可以关闭严格模式)
- 原有 Hexo Blog 上的公式均需要以四斜杠换行,即:
- 如果你尝试使用官方支持的
Pandoc
渲染器选项- 这将会导致文章 TOC(目录)消失,
- 主题的
Markup Hook
无法使用,文章内的所有HTML
内容将为Pandoc
直出(即无任何CSS, Class
标签等)
- 如果使用默认的
主题的
Markup Hook
为 Hugov0.71.0
的新特性,目前仅支持Goldmark
渲染器
从源编译安装
因为 Hugo 几乎写死了所有渲染器的调用参数(这点真的是 Hugo 相较于 Hexo 很不成熟的一个体现),而
Pandoc
渲染器需要在调用参数添加--toc
选项为文章自动输出目录,所以我们必须魔改 Hugo 的部分代码。更重要的是,Hugo 主题使用的 TOC 显示一般是通过 Hugo 内部传参,单纯的给
Pandoc
添加--toc
参数会导致所有文章只是在输出头部,而不是以主题在侧边栏的形式,如下图所示。
- 我们找到了 Hugo Pull Request: Add
basic toc generation for pandoc #8911 用以彻底修复 Hugo 中
Pandoc
TOC 失效的问题。
- 我们为了保证 Hugo 在最新版本,将 #8911
的更新合并到了最近的 Hugo 最新版本。
- 你可以在 SDLMoe/hugo 找到我们已经合并过后的版本,但请注意,我们并不保证能实时更新 Hugo 至最新版本。
迁移 Hexo 文章至 Hugo
首先,使用
hugo new site <site-name>
创建站点,此命令会新建一个名为site-name
的文件夹,类似于在site-name
文件夹里面输入hexo init
生成结果如下
.
├── archetypes
│ └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes
- 相较于 Hexo,Hugo 的站点文件夹非常干净没有恶心人的
node_modules
,配置文件集中在config.toml
,当然你可以直接改名为更为习惯的config.yaml
配置文件
- 以下为本站的配置文件,仅作参考,隐去了部分信息
baseurl: https://sdl.moe
languageCode: zh-cn
theme: hugo-theme-stack
paginate: 5 # 每页显示多少文章
title: SDLMoe
# Set hasCJKLanguage to true if DefaultContentLanguage is in [zh-cn ja ko]
# This will make .Summary and .WordCount behave correctly for CJK languages.
hasCJKLanguage: true
permalinks:
post: /post/:filename/
page: /:filename/
# 下面是 Stack 主题的参数
params:
mainSections:
- post
featuredImageField: image
rssFullContent: true # RSS 是否开启全内容 / false 则为只有摘要
favicon: img/sdl-logo-white-cir.webp # 浏览器 Tab 页的网站图标
article:
math: false # 这里关闭是因为我们使用的是 MathJax
toc: true # TOC 默认开启
readingTime: true
license:
enabled: true
default: '<a href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener">CC BY-SA 4.0</a>'
imageProcessing:
cover:
enabled: true
content:
enabled: true
### Custom menu
### See https://docs.stack.jimmycai.com/configuration/custom-menu.html
### To remove about, archive and search page menu item, remove `menu` field from their FrontMatter
menu:
main:
- identifier: home
name: Home
url: /
weight: -100
params:
newTab: false
icon: home
- identifier: categories
name: Categories
url: /categories
weight: -85
params:
newTab: false
icon: layout-grid
- identifier: rss
name: RSS Feed
url: /index.xml
weight: -10
params:
newTab: true
icon: rss
social:
- identifier: github
name: GitHub
url: https://github.com/SDLMoe
params:
newTab: true
icon: brand-github
related:
includeNewer: true
threshold: 60
toLower: false
indices:
- name: tags
weight: 100
- name: categories
weight: 200
markup: # **Markup Section 非常重要**
defaultMarkdownHandler: pandoc # 选择 Pandoc
pandoc:
preserveTOC: false # 此选项开启则不会剔除掉 Pandoc 自己生成在文章中的 TOC,关闭则只显示 Sidebar TOC
tableOfContents:
endLevel: 5 # 从 5 结束
ordered: true
startLevel: 2 # 从 2 开始
highlight: # 代码高亮配置,对 Pandoc 而言似乎是没用的。稍后会提到如何使代码高亮
anchorLineNos: false
codeFences: true
guessSyntax: false
hl_Lines: ""
lineAnchors: ""
lineNoStart: 1
lineNos: true
lineNumbersInTable: true
noClasses: true
style: dracula
tabWidth: 4
# 使用下面的配置才能使得 Pandoc 渲染 Blog 文章
security:
enableInlineShortcodes: false
exec:
allow: ['^dart-sass-embedded$', '^go$', '^npx$', '^postcss$', '^p']
osEnv: ['(?i)^(PATH|PATHEXT|APPDATA|TMP|TEMP|TERM)$']
文件架构的差异
- 在先前的文章中提到过 Hugo 与 Hexo 文件管理的差异
Hugo 的内容管理,每篇文章独立项目文件夹
├── post (主文件夹)
│ └── operator-precedence (项目文件夹)
│ ├── index.md (文章内容)
│ └── operator-precedence (图像资源)
│ ├── c-operator-precedence.webp
│ └── tree.webp
Hexo 的内容管理,每篇文章都在
_posts
主文件夹下
_posts (主文件夹)
├── acsl (文章图像资源)
│ ├── ...
│ └── xxx.webp
├── acsl.md (文章内容)
├── ap-cal-bc
│ ├── ...
│ └── xxx.webp
├── ap-cal-bc.md
├── ap-chem
│ ├── ...
│ └── xxx.webp
└── ap-chem.md
文件头部配置 Front Matter 的差异
- 这是本文的 Front Matter
title: "如何优雅的从 Hexo 转移 Blog 到 Hugo"
date: 2022-02-17T14:47:22+08:00
lastmod:
author: WetABQ
description: '详细记录了本 Blog 从 Hexo 迁移至 Hugo 的过程。'
tags: [Hugo, Hexo, WetABQ]
categories: Blog
image: index/hexohugo.webp
license: true
toc: true
comments: true
mathjax: true
print_background: true
puppeteer:
timeout: 1000
- 其中包含如下变动
date
相较于 Hexo 更加严谨update
\(\to\)lastmod
image
为文章封面
- (针对 Stack 主题)
toc
目录开关license
协议开关comments
评论开关
slug
在 Markdown 文件头部(Front Matter)已配置时,则使用配置内的名字,否则slug
等于filename
参数即文件名具体参考 Hugo 官方文档
RSS 订阅
Hugo 默认的 RSS 地址为 /index.xml
,而 Hexo 则是
/atom.xml
Hugo 在 RSS 比 Hexo
实现更为简单,不会过滤掉文本内本身的非法字符。建议通过
XML
自动解析插件先访问一遍站点的 /index.xml
链接,检查是否能够正常解析。如果不能,通常是由于非法字符导致的,比如非常魔怔的
Unicode Character 'BACKSPACE' (U+0008)
,只要任何文章中有一处非法字符都会导致整个站点的
RSS 订阅失效。
针对 Stack 主题做的一些修改
使用 MathJax 而非 KaTeX
参考文章:Render LaTeX math expressions in Hugo with MathJax 3
在 themes/hugo-theme-stack/layouts/partials
下新建
mathjax.html
文件,内容如下:
<script>
= {
MathJax tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$','$$'], ['\\[', '\\]']],
processEscapes: true,
processEnvironments: true
,
}options: {
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre']
};
}
window.addEventListener('load', (event) => {
document.querySelectorAll("mjx-container").forEach(function(x){
.parentElement.classList += 'has-jax'})
x;
})
</script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
然后在
themes/hugo-theme-stack/layouts/partials/head/head.html
的最后加入这段代码:
if .Params.mathjax }}{{ partial "mathjax.html" . }}{{ end }} {{
高亮代码
同样地,在
themes/hugo-theme-stack/layouts/partials/head/head.html
的最后加入这段代码
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/base16/darcula.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
Light Mode 配色
Stack 原生的 Light Mode 配色实在是太瞎了
在 themes/hugo-theme-stack/assets/scss/variables.scss
进行如下修改
- 修改第
33
行#bababa
为#404040
- 修改第
73
行#bababa
为#808080
134 - 135
行
, 0, 0, 0.8);
--code-background-color: rgba(0#ffffff; --code-text-color:
141 - 142
行
--code-background-color: #4c4c4c;#dddddd; --code-text-color:
TOC 无法跟随滚动
在 themes/hugo-theme-stack/assets/ts/gallery.ts
中修改
69-77
行,在外套一个 null
值判断
if (paragraph != null) {
if (paragraph.textContent.trim() == '') {
/// Once we insert figcaption, this check no longer works
/// So we add a class to paragraph to mark it
.classList.add('no-text');
paragraph
}
let isNewLineImage = paragraph.classList.contains('no-text');
if (!isNewLineImage) continue;
}
移除 PhotoSwipe
PhotoSwipe 对 Pandoc 渲染文章的图像不太兼容,点击图像会导致全站卡死
将
themes/hugo-theme-stack/layouts/partials/article/components/photoswipe.html
内代码全部删除
移除相关文章中的彩色遮罩
这彩色遮罩实在是太丑了
直接移除
themes/hugo-theme-stack/assets/scss/partials/layout/article.scss
中 299 - 304
行代码,
&.has-image {
.article-details {
padding: 20px;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.25) 0%, rgba(0, 0, 0, 0.75) 100%);
} }
进一步移除 themes/hugo-theme-stack/assets/ts/main.ts
中
30-59
行
友情链接与归档页面中图像圆角
在
themes/hugo-theme-stack/layouts/partials/article/components/links.html
中 18 - 22
行替换为
{{ with $link.image }}<div class="article-image">
<img src="{{ . }}" style="border-radius: 50%;" loading="lazy">
</div>
{{ end }}
在
themes/hugo-theme-stack/layouts/partials/article-list/compact.html
中 29-35
行替换为
<img src="{{ $Permalink }}"
width="{{ $Width }}"
height="{{ $Height }}"
alt="{{ .Title }}"
loading="lazy" style="border-radius: 10%;">
{{ else }}<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" style="border-radius: 10%;" />
添加文章内的链接样式
因为 Pandoc 渲染不经过主题的 Markup Hook
,无法由主题对
a
类型标签自动添加 class
在 themes/hugo-theme-stack/assets/scss/style.scss
最后添加
.article-content {
a {text-decoration: none;
color: var(--accent-color);
box-shadow: 0px -2px 0px rgba(var(--link-background-color), var(--link-background-opacity)) inset;
transition: all 0.3s ease;
&:hover {
color: var(--accent-color-darker);
box-shadow: 0px -10px 0px rgba(var(--link-background-color), var(--link-background-opacity-hover)) inset;
}
} }
使用
当迁移完成后,我们可以通过 hugo server
在本地的
http://localhost:1313/
中实时预览
自动化发布与部署
SDLMoe 是通过 Cloudflare Pages 和 Gitlab 协同自动化部署
当提交 Commit 修改 Markdown 文件时,Cloudflare Pages 会自动化的拉取 Gitlab 上的仓库并运行 Hugo 进行渲染输出
这是自动化部署容器所使用的脚本 build-ci.sh
#!/bin/bash
export pandoc_ver=2.18
wget https://github.com/jgm/pandoc/releases/download/$pandoc_ver/pandoc-$pandoc_ver-linux-amd64.tar.gz
tar -xzvf pandoc-$pandoc_ver-linux-amd64.tar.gz
mv pandoc-$pandoc_ver/bin/pandoc .
curl -Lo hugo-bin https://github.com/SDLMoe/hugo/releases/latest/download/hugo
chmod +x hugo-bin
chmod +x pandoc
PATH=$(pwd):$PATH ./hugo-bin --minify --gc
本地 build-local.sh
#!/bin/bash
./hugo-bin --minify --gc