Introduction

我经常使用 Emacs Org-mode 来写blog。虽然有很多其他笔记工具和方案,但我一直觉得没法取代 Org-mode,比如Org-mode里的 Babel 代码块,内嵌LaTex公式,GUI下图表预览,表格自动求值等功能,实在是很方便。Emacs Org-mode 也天然支持将众多 org 文件笔记通过链接组织成个人知识库。

不过,现有的工作流基于标准的 ox-publish 导出 HTML,样式略显陈旧,如果支持更美观的主题,需要很多手动配置。

最近对orgmode工作进行了一次升级:引入 Hugo 渲染引擎(搭配 PaperMod 主题),同时保留了纯粹的 Org-mode 创作体验。

工作流的演进

过去:Org -> HTML (ox-publish)

  • 优点:流程简单,完全受 Emacs 控制。
  • 缺点:网页样式极其基本,移动端适配差,缺乏搜索和标签功能。

现在:Org -> HTML Fragment -> Hugo (PaperMod)

  • 改进:采用 Hugo 作为渲染引擎,利用 PaperMod 提供现代化的 UI。
  • 核心逻辑:利用 Emacs 的 ox-html 将 Org 导出为纯净的 HTML 片段,再交给 Hugo 进行最终装配。

关键技术点

1. 自动化导出脚本:publish-hugo.el

这是整个流程的“心脏”。它是一个 Emacs Lisp 脚本,通过 Org 内置的 ox-html 导出器实现精准渲染,同时负责元数据注入和路径修正。

(defun pz/export-all-to-hugo ()
  (dolist (section '("notes" "quantum" "me"))
    (dolist (file (directory-files (expand-file-name section) t "\\.org$"))
      (with-current-buffer (find-file-noselect file)
        ;; 导出为 HTML 片段
        (let ((html-content (org-export-as 'html nil nil t)))
          ;; 修复资源路径
          (setq html-content (replace-regexp-in-string "\\.\\./images/" "/images/" html-content))
          ;; 写入 Hugo content 目录
          (with-temp-file dest-file
            (insert "---\n" (format "title: \"%s\"\n" title) "math: true\n---\n\n")
            (insert html-content)))))))

2. 构建与部署:build.sh & deploy.sh

实现“一键发布”的两个 Bash 脚本:

  • build.sh :在 Batch 模式下启动 Emacs 执行导出,随后调用 hugo 命令生成静态全站。
  • deploy.sh :利用 rsync 将生成的 public 目录同步到 github.io 仓库,并自动提交 Git。
# build.sh 关键片段
emacs -Q --batch -l publish-hugo.el -f pz/export-all-to-hugo
hugo --buildDrafts --buildFuture
# deploy.sh 关键片段
rsync -av --delete --exclude ".git" public/ ../your-github-repo/
cd ../your-github-repo/
git add .
git commit -m "Site updated"
# git push origin main

3. 图片管理:Hugo Mounts

利用 Hugo 的 Mounts 功能,直接将源码目录下的 images 文件夹映射到 Hugo 的静态资源目录。这意味着在写 Org 文章时,图片路径依然保持不变,且无需物理复制文件。

4. 公式渲染:MathJax 3

为了保持与原站一致的高质量数学公式显示,我们在 Hugo 中配置了 MathJax 3 渲染引擎,并同步了原本的 LaTeX 配置,完美支持复杂的量子计算矩阵。

踩过的坑

在迁移过程中,最头疼的就是 LaTeX 矩阵渲染 。最初尝试直接导出为 Markdown,但 Hugo 的解析器(Goldmark)会吞掉公式里的反斜杠 \\

经过多轮尝试,最后还是回到 “先导出 HTML 片段,再让 MathJax 在前端渲染” 的方案。

此外,Hugo在导出时似乎会自作聪明将 Quantum 这个单词自动复数化为 Quanta ,解决办法是在分类目录下创建 ../_index/ 显式定义标题。

发布流程

  1. 在 Emacs 中用 Org-mode 写文章。
  2. 运行 ./build.sh 进行本地构建。
  3. 访问 localhost:1313 验证效果。
  4. 运行 ./deploy.sh 同步到 GitHub Pages 仓库。

总结

感想:Emacs Org-mode 真好用啊!

感谢阅读!