使用 Emacs Org-mode 构建笔记系统

记录一下从 Quiver 迁移到 Emacs Org-mode 时的思考,以及这两个月使用 Org-mode 构建笔记系统的心得。

我的笔记系统

在 Mac 上使用 Quiver 管理笔记半年后,总觉得差了点什么,最终还是狠下心来一头栽进 Org-mode 的坑里,幸运地找到了基本令我满意的笔记系统。

从 Evernote,静态博客,Confluence,Quiver 到现在的 Org-mode,每次迁移都看似理由充分,实际上还是缺乏对自己想要之物的清楚认识。 曾以为 Quiver 已经足够优秀,但折腾了 Org-mode 后才总结出我所找寻的笔记系统的特性,并在针对特性上进行一些对比:

  • 源载体为标记语言而非所见即所得的纯文本或富文本,写作时专注于内容本身而非排版格式:支持 mark down 或 Org-mode 的软件都能满足
  • 基于笔记、笔记本和标签的管理方式:时下主流的笔记软件都是这种模式而且做得不错
  • 搜索功能:Tag 搜索比较完善。全文搜索则令人失望,搜索出来的结果往往只有整个笔记,再配合关键词高亮,无法知道关键词在文中的位置,筛选起来不直观。
  • vi mode 的编辑方式:支持 vi mode 是 Quiver 的亮点之一,然而功能残缺严重,只能说差强人意。
  • 代码块编辑:只有号称程序员笔记本的 Quiver 做好了这点
  • 用于写公式的简单 LaTex:Quiver 的 Mathjax 做得不错,不过在高亮上有些问题。
  • 表格和图片:表格的对齐,简单的公式填充、图片的预览,大小控制,markdown 在这两点上功能不足
  • 预览功能:markdown 的预览工具各式各样,而 Org-mode 的预览工具比较少,因为 Emacs 上的 Org-mode 不需要渲染可读性也很高
  • 版本管理:笔记软件基本都有自己的一套数据格式,无法使用 git 这种基于文件的版本系统进行管理。
  • 发布到其他平台:发布时如果对笔记进行预处理或者上传图片到图床的功能虽然有软件提供,但仅适用于部分场景

    以上列举的特性,都能通过 Org-mode 在一定配置后实现。

用 Org-mode 构建笔记系统

接下来的配置代码具体可参见 我的 spacemacs 配置

笔记管理结构

  1. 文件结构

    path-to-project
    |-- notes
    |   |-- Notebook1
    |   |-- Notebook2
    |   |   |-- Note1.org
    |   |   `-- Note2.org
    |   `-- Notebook3
    `-- static
        `-- img
            |-- Note1
            `-- Note2

    每个文件夹是一个笔记本,笔记本可以无穷嵌套,org 格式的笔记存放于笔记本中,每篇笔记的图片存放于 path-to-project/static/img/note-name 文件夹下。

  2. Tag 管理

    Org-agenda 提供了筛选 org 文件的功能,通过给每个 org 笔记的一级标题设置 Tag,便可实现 Tag 搜索功能。

    Org-agenda Tag
    Org-agenda Tag

    让 agenda 索引所有笔记的配置代码:

    1
    2
    (load-library "find-lisp")
    (setq org-agenda-files (find-lisp-find-files "path-to-project/notes" "\.org$"))
  3. 搜索

    以下三种方式可以满足绝大多数搜索笔记的需求:

    • 利用 Org-agenda 实现的 Tag 搜索
    • 利用 fzf 的 emacs 前端,执行 (fzf-directory "path-to-project/notes") 按文件名搜索
    • 通过添加 git 版本管理的方式将 path-to-project 作为工程根目录,用 helm-ag-project-root 全文搜索

笔记编辑和预览

笔记编辑熟悉一下 Org-mode 即可,需要配置的是插入图片的功能。为了方便插入和管理笔记所用到的图片,我找到了一个用于 emacs 拖拽插入图片的代码并进行了修改。这段代码会将拖拽的图片拷贝到 path-to-project/static/img/current-file-basename 下,并提供输入标注的功能: my-dnd-func , define-key

插入图片后执行 org-toggle-inline-images 即可切换显示本地图片

关于预览功能,实际上 Emacs 自身对 Org-mode 的渲染已经非常适合阅读,如果实在需要渲染成 html 查看,可以通过以下几种方式:

  • 直接 org-export-as-html 导出到 buffer,在用 browse-url-of-buffer 在浏览器中打开 buffer
  • org-preview-html 在 eww 中预览
  • 配置 impatient-mode ,在浏览器中实时渲染,不过性能不是很好。代码见下
1
2
3
4
5
6
7
8
9
10
11
(defun my-imp-org-to-html-filter (buffer)
(let ((output-buffer (current-buffer))
(log-message-max nil))
(with-current-buffer buffer
(let ((output (org-export-as 'html)))
(with-current-buffer output-buffer (insert output))))))
(defun my-impatient-mode-hook()
(progn (imp-set-user-filter 'my-imp-org-to-html-filter)
(message "My org-imp-mode hook trigger")))
(add-hook 'impatient-mode-hook 'my-impatient-mode-hook)

笔记发布

hexo 等静态博客提供的写作功能容易让人把写笔记和写博文分开。实际上博文完全可以视作笔记的一种,要发布到博客的笔记通过一些预处理,导出成能够被渲染的格式发布即可。

比如我使用 hexo 作为静态博客引擎,导出笔记的过程是: \[ org \xrightarrow{将本地图片链接替换成七牛链接} html \xrightarrow{添加 hexo 渲染用的 metadata} 博客 post 文件夹下的 html \]

上述过程的配置代码参见 ;; blog post 之后的代码

hexo generate/deploy 以及七牛上传的功能也可以通过 prodigy 在 Emacs 中完成:我的 prodigy 配置

最后

希望我的这篇文章能够给厌烦了现有笔记软件的你带来一些想法。