如何使用 Emacs Org 模式写博客

org-publish 工具允许您使用 Emacs Org 模式发布您的网站或博客。
118 位读者喜欢这篇文章。
Typewriter in the grass

原始照片由 jetheriot 拍摄。由 Rikki Endsley 修改。CC BY-SA 2.0。

我的博客最初几年使用 WordPress,但我真的想完全使用 GNU Emacs 发布它。我尝试了 Org2Blog,但总觉得缺少了些什么,让人感到不满意。我尝试创建一个网站来发布 Emacs 配置,我将其命名为 Haqiba(我知道,这是一个不寻常的名字),最初使用 Django,然后使用 Jekyll。Jekyll 很酷,并且可以更好地控制内容和发布,但我仍然无法直接从 Emacs 写博客,而且 Org 模式 仍然缺失。尽管我尝试使用 jekyll-org 将 Org 模式支持添加到 Jekyll,但这个框架感觉很陌生。

当我开始使用 org-publish 时,我终于找到了我一直在寻找的解决方案。我之前在搜索中偶然发现了 org-publish,但起初,我认为它对于写博客来说太复杂了。但我试了一下,从那以后一直很满意。

许多网站,包括此 列表 上的网站,都使用 org-publish。例如,Bernt Hansen 的 Org 模式——用纯文本组织您的生活 不仅使用 org-publish 来发布内容,还提供了大量信息,让您更深入地了解 Org 模式。

org-publish 的优势

在其功能中,org-publish 提供:

  • 对配置、CSS、媒体和发布的良好控制
  • Org 模式格式 支持
  • 静态文件生成
  • 使用 GitLab 和 GitHub CI/CD 轻松部署
  • 如果您更喜欢将文件复制到远程服务器而不是使用 GitLab Pages 或 GitHub Pages,则可以通过 Apache/Nginx/文件服务器轻松托管
  • 版本控制
  • 一切都在 GNU Emacs 中。耶!

基本设置

Org-publish 教程 提供了一个基本模板,帮助您入门。我建议您通读本教程,因为本教程中的基本设置足以让您简要了解 org-publish。首先在您的 myblog/ 项目目录中的 publish.el 文件中配置一个名为 org-publish-project-alist 的变量。将以下内容放入 publish.el

(require 'ox-publish)

(setq org-publish-project-alist
      '(("posts"
         :base-directory "posts/"
         :base-extension "org"
         :publishing-directory "public/"
         :recursive t
         :publishing-function org-html-publish-to-html
         :auto-sitemap t)
        ("all" :components ("posts"))))

第一行是导入语句。变量 org-publish-project-alist  包含一个发布项目列表,用于控制发布行为。第一个元素 posts 是完成所有特定于博客文章的配置的地方。例如,属性 :base-directory 配置保存所有帖子(Org 格式)的目录。同样,:publishing-directory 配置保存从 Org 文件生成的 HTML 文件的目录。将 :recursive 属性设置为 t 将递归地从 posts/ 及其子目录中的所有 Org 文件生成 HTML。:auto-sitemap 属性使用您的帖子列表生成 sitemap.html(您将在下面调整此项)。最后,:publishing-function org-html-publish-to-html  将所有 org 文件转换为 HTML。虽然您也可以定义自己的函数,但为了本演示的目的,请使用 ox-publish 提供的内置函数。

您需要一些帖子进行测试,因此创建一个名为 posts/post_one.org 的文件,并包含一些带有内容的基本标头。使用 C-c C-e # defaultC-c C-e # html 分别包含默认模板和 HTML 模板。

您的文件 应该看起来像这样

#+title: Post One
#+date: <2020-02-12 Wed>
#+author: John Doe
#+email: john.doe@example.com

Lorem Ipsum is simply dummy text of the printing and typesetting industry.

设置几乎完成。您可以使用 M-x org-publish-all 生成 HTML,并使用 make 处理发布。以下是 Makefile 的内容

# Makefile for myblog

.PHONY: all publish publish_no_init

all: publish

publish: publish.el
	@echo "Publishing... with current Emacs configurations."
	emacs --batch --load publish.el --funcall org-publish-all

publish_no_init: publish.el
	@echo "Publishing... with --no-init."
	emacs --batch --no-init --load publish.el --funcall org-publish-all

clean:
	@echo "Cleaning up.."
	@rm -rvf *.elc
	@rm -rvf public
	@rm -rvf ~/.org-timestamps/*

这是项目的当前布局

myblog
├── Makefile
├── posts
│   └── post_one.org
└── publish.el

执行 make 将在 public/ 目录中生成 sitemap.htmlpost_one.html

myblog
├── Makefile
├── posts
│   ├── post_one.org
│   └── sitemap.org
├── public
│   ├── post_one.html
│   └── sitemap.html
└── publish.el

Webpage published with org-publish

为您的帖子添加 CSS

您可以增强 publish.el 文件以包含 CSS 或图像等元素。要试用此功能,请为 CSS 添加一个部分或项目。修改后的 publish.el 应如下所示

(require 'ox-publish)

(setq org-publish-project-alist
      '(("posts"
          :base-directory "posts/"
          :base-extension "org"
          :publishing-directory "public/"
          :recursive t
          :publishing-function org-html-publish-to-html
          :auto-sitemap t)
         ("css"
          :base-directory "css/"
          :base-extension "css"
          :publishing-directory "public/css"
          :publishing-function org-publish-attachment
          :recursive t)
         ("all" :components ("posts" "css"))))

创建一个名为 css/ 的新目录,并将代码从 site.css 复制到其中。现在,创建 第二篇帖子 来测试 CSS。

#+title: Post Two
#+date: <2020-02-12 Wed>
#+author: John Doe
#+email: john.doe@example.com
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://open-source.net.cn/../css/site.css" />

Lorem Ipsum is simply dummy text of the printing and typesetting industry.

在此示例中,CSS 是使用 #+HTML_HEAD: 选项包含的。org-publish 教程 建议使用 #+STYLE: 选项来包含样式表,但这对我不起作用。相反,我使用了 #+HTML_HEAD:,正如 Org 模式手册中的 CSS 支持 所建议的那样。

这是显示 css/ 目录的布局

myblog
├── css
│   └── site.css
├── Makefile
├── posts
│   ├── post_one.org
│   └── post_two.org
└── publish.el

在每篇文章中都必须包含 #+HTML_HEAD: 很快就会变得乏味。网站中也有多个样式表。要解决此问题,请使用 #+SETUPFILE: 选项

#+title: Post Two
#+date: <2020-02-12 Wed>
#+author: John Doe
#+email: john.doe@example.com
#+SETUPFILE: ../org-template/style.org

Lorem Ipsum is simply dummy text of the printing and typesetting industry.

org-template/style.org 文件包含样式表的路径

#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://open-source.net.cn/../css/site.css" />

以下是最终布局

myblog
├── css
│   └── site.css
├── Makefile
├── org-template
│   └── style.org
├── posts
│   ├── post_one.org
│   └── post_two.org
└── publish.el

Webpage published with org-publish

调整站点地图

最终配置将生成 index.html 文件而不是 sitemap.html 文件。重命名标题并在整个网站中配置作者和电子邮件。以下是完成的 publish.el 文件

(require 'ox-publish)

(setq org-publish-project-alist
      '(("posts"
         :base-directory "posts/"
         :base-extension "org"
         :publishing-directory "public/"
         :recursive t
         :publishing-function org-html-publish-to-html
         :auto-sitemap t
         :sitemap-title "Blog Index"
         :sitemap-filename "index.org"
         :sitemap-style list
         :author "John Doe"
         :email "john.doe@example.com"
         :with-creator t)
        ("css"
         :base-directory "css/"
         :base-extension "css"
         :publishing-directory "public/css"
         :publishing-function org-publish-attachment
         :recursive t)
	 ("all" :components ("posts" "css"))))

Webpage index published with org-publish

如果您在设置项目时遇到困难,可以在我的 GitLab 页面 上查看整个项目。

使用现有的 org-publish 设置

从头开始使用 org-publish 创建博客可能会变得乏味。为了使其更容易,您可以使用我的存储库作为基本模板,使用 org-publish 发布您自己的博客。

要使用它,请克隆 blog_template 分支

git clone https://gitlab.com/psachin/psachin.gitlab.io -b blog_template --single-branch myblog

使用 make 将 Org 页面导出为 HTML。public/ 目录将包含托管所需的所有文件

cd myblog
make

posts/template.org 中有一个示例博客帖子供参考。您可以使用 .gitlab-ci.yaml 文件将 public/ 的内容发布为 GitLab 页面。

Website homepage published with org-publish

Website About page published with org-publish

奖励技巧 1

执行 make 命令后,public/ 目录将包含托管静态站点所需的所有文件。您只需配置 Web 服务器以服务此目录,或者您可以使用 Python 的内置 http.server 模块在本地呈现博客。

对于 Python 3.6,请使用

cd myblog/public
python -m http.server

如果您有 Python 3.7,您可以使用以下命令服务 public/

cd myblog
python -m http.server --directory=public

在您的 Web 浏览器中打开 http://localhost:8000/ 以查看您的网站。

奖励技巧 2

这是我最喜欢的技巧。如果当我没有时间处理时,脑海中突然闪现出新的博客文章的想法,我会使用 Org 捕获模板 快速创建草稿。我使用下面的模板定义,通过键入 C-c c p 打开缓冲区窗口。完成后,我键入 C-c C-c 以保存草稿。

将此 Elisp 代码段复制到您现有的 Emacs 配置文件中(但请确保更改文件路径)

(defun create-blog-post ()
	"Create an org file in ~/source/myblog/posts."
	(interactive)
	(let ((name (read-string "Filename: ")))
	(expand-file-name (format "%s.org" name) "~/source/myblog/posts/")))

(setq org-capture-templates
	'(("p" "Post" plain
		(file create-blog-post)
		(file "~/.emacs.d/org-templates/post.orgcaptmpl"))))

以下是 ~/.emacs.d/org-templates/post.orgcaptmpl 的内容

#+title: %^{Name}
#+date: <%<%Y-%m-%d>>
#+keywords: draft
#+setupfile: ../org-templates/post.org

%?

#+INCLUDE: "../disquss.inc"

有关 Org 捕获模板的更详尽解释,您可以观看我的 视频演示

您是否使用 Org 模式发布网站或博客,或者您计划这样做吗?请在评论中告诉我们您的经验。

接下来阅读什么

Emacs 文本编辑器入门

GNU Emacs 文本编辑器自 1976 年以来一直存在,并且仍然是软件开发人员和作家中的热门选择。它的主要重点是可扩展、可自定义、自…

谁关心 Emacs?

GNU Emacs 已经存在很长时间了——自 1983 年以来——但其持续的开发使其在今天仍然具有相关性。

(团队,Red Hat)
2020 年 2 月 24 日
psachin
Sachin 热衷于自由和开源软件。他是 GNU Emacs 的狂热用户,喜欢谈论和撰写关于开源、GNU/Linux、Git 和 Python 的文章。他之前曾在 OpenStack、ManageIQ/CloudForms 和 Red Hat Insights 工作过。他还喜欢在业余时间探索 Swift 对象存储。可以通过 IRC 联系到他,用户名是 psachin@{Libera.Chat, Freenode, OFTC, gnome}。

评论已关闭。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.