使用hugo+asciidoctor在GitHub搭建博客
为什么要使用 hugo + asciidoctor 这样的组合
hugo 对自己的介绍是 The world’s fastest framework for building websites。 GitHub 有非常多的项目主页和个人博客都是用 hugo 生成的。hugo 相对于同类竞品比如 jekyll 最大的优势是 快。
hugo 最常见的搭配是 Markdown。Markdown 差不多也是最通用的标记语言(不包括 HTML)。Markdown 使用范围比较广的有 2 个规范, CommonMark 和 GFM(GitHub Flavored Markdown)。使用最广泛的标记有如下几种
一级标题
=======
## 二级标题
段落以空白行分隔。
行末两个空格 产生换行。
文本属性:_斜体_、
**粗体**、`等款字体Monospace`。
水平线:
---
列表:
* 张三
* 李四
* 王二
编号列表:
1. 不论
2. 三七
3. 二十一
[链接](http://example.com)
![图片](Icon-pictures.png "icon")
> Markdown使用「>」來引用。
```
代码片段,GFM
```
~~删除线 GFM~~
[] 任务列表1 GFM
[] 任务列表2 GFM
[x] 已完成的任务列表 GFM
这几种标记看起来非常简单,但是在实际使用的时候,往往不遂人意。
比如希望在嵌套编号列表中插入多个段落,实现如下的排版:
-
编号 1
代码片段
编号 1 段落 2
-
嵌套列表 1.1
嵌套列表代码片段
编号 1.1 段落 2
-
嵌套列表 1.2
-
-
编号 2
用 Markdown 往往需要调试非常多次,而且不同的编辑器最终排版还会有不一样的表现。
日常的写作中,往往需要插入丰富的内容,比如插入表格,视频,公式,下标、上标等。Markdown 除了内嵌 HTML 代码并没有提供其他扩展的能力。 这就导致了每个人用 Markdown 写文档的时候,或多或少需要使用 HTML 标记。
<video id="video" controls="" preload="none" poster="http://media.w3.org/2010/05/sintel/poster.png">
<source id="mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4">
<source id="webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" type="video/webm">
<source id="ogv" src="http://media.w3.org/2010/05/sintel/trailer.ogv" type="video/ogg">
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
Markdown 本来定位是标记语言,并不与浏览器绑定,但是一旦使用 HTML,就意味着只能在浏览器里面渲染。而且由于不同的 Markdown 编辑器、渲染程序 实现功能不一样,同一份 Markdown 文档,在不同的平台使用,都需要人工做一些修改。[1] [2]
Asciidoctor 在 Markdown 的基础上,重新设计了一套根据完善的标记语言,很好地解决了 Markdown 遇到的问题。这篇文章就是用 Asciidoctor 写的。 具体的格式可以参考 Asciidoctor 官网。
只需安装好 asciidoctor 命令,hugo 就可以支持用 Asciidoctor 格式写文档。
如何自动部署 Github Pages
本地写文章的时候直接一行命令启动 hugo,就可以在浏览器预览文章。
hugo server
我们想实现:写完文章后只需要 push 到 GitHub,后面生成文章的过程全部自动化。
现在 GitHub 主流的自动化方式是使用 Github Actions。Repo 收到 push 事件后,触发 GitHub Action。由 GitHub Action 调用 hugo 生成 整个静态网站,然后将生成的所有静态文件提交到 GitHub Pages。
目前 GitHub Pages 有多种机制:
博客的 repo 名称为 gfreezy.github.io
,属于 User Pages
,只支持通过 master 的根目录访问。所以 hugo 生成的文件需要放在 repo 的
根目录。这样一来生成的文件和 hugo 原始的代码文件都混合在 repo 的目录,非常不利于长期维护。既然生成的文件位置没法修改,那我们就把 hugo
代码放在子目录 hugo
里面,根目录只放生成的文件。
这引入了一个新的问题:GitHub Action Market 里面的 hugo action 都只支持在 repo 根目录运行。找了一圈没有合适的,我们只能自己来写 action。
name: github pages
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
with:
submodules: true # Fetch Hugo themes
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- uses: actions/setup-ruby@v1 (1)
- name: Publish Site
run: make (2)
- name: Deploy
uses: stefanzweifel/git-auto-commit-action@v4.1.2 (3)
with:
commit_message: hugo publish
1 | asciidoctor 需要使用 gem 安装。需要准备好 ruby 环境 |
2 | 生成网站 |
3 | 将新生成的代码 commit,并 push 到 master |
HUGO_VERSION:="0.69.0"
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
BIN:="$(ROOT_DIR)/.bin"
ifeq ($(shell uname), Darwin) (1)
OS:="macOS"
else
OS:="Linux"
endif
.PHONY: build (2)
build: clean install (3)
cd $(ROOT_DIR)/hugo && $(BIN)/hugo
mv $(ROOT_DIR)/hugo/public/* $(ROOT_DIR)/
install: .bin/hugo
.bin/hugo: (4)
# install asciidoctor
[ $(OS) == "macOS" ] && brew install asciidoctor || gem install asciidoctor
# install hugo
mkdir -p ".bin"
[ -f hugo_extended_$(HUGO_VERSION)_$(OS)-64bit.tar.gz ] || wget https://github.com/gohugoio/hugo/releases/download/v$(HUGO_VERSION)/hugo_extended_$(HUGO_VERSION)_$(OS)-64bit.tar.gz
tar -C .bin -xzvf hugo_extended_$(HUGO_VERSION)_$(OS)-64bit.tar.gz
rm -rf hugo_extended_$(HUGO_VERSION)_$(OS)-64bit.tar.gz
clean: (4)
ls $(ROOT_DIR) | grep -v -E '^(CNAME|Makefile|hugo|README.md)$$' | xargs rm -rf || true
rm -rf $(ROOT_DIR)/hugo/public/
1 | 判断 macos 和 linux |
2 | 默认执行 build |
3 | 每次 build 前,先执行 clean。避免无效的文件影响显示效果 |
4 | 将所有生成的文件全部删除 |
完成
之后写博客,只需要新建一个 asciidoctor 文档,写完后提交并 push master,后续全部都自动化。 GitHub 是支持预览 asciidoctor 文档的,所以我们甚至可以直接在 GitHub 上在线创建和编辑。