Org To Site Tutor

Table of Contents

→ 为什么会有这个页面呢? :)

该页面 Emacs 配置详见 init-site.el

Emacs China 中的描述,比较散乱,这里整理一下。我尽量把所有的操作步骤纳入其中,以避免不必要的跳转。

起步

这个章节中,我们会叙述如何 让项目先运行起来 ,这才是主要的,不是吗?放心,我们会在后续章节中介绍细节。

1. 克隆项目到本地家目录

# 进入家目录
# → Windows 
# C:\Users\<用户名>\AppData\Roaming\site
cd C:\Users\jack\AppData\Roaming
# → Gnu/linux & MacOS
cd ~

# 克隆项目到家目录
git clone https://github.com/loveminimal/site.git site

*2. 克隆 Emacs 配置到家目录

如果,你想直接使用自己的 Emacs 配置, 跳过这一步 即可。
如果,你想使用我的这份配置,那么,完成这一步之后,项目就可以跑起来了。

# 克隆 Emacs 配置到家目录
git clone https://github.com/loveminimal/emacs.d.git .emacs.d

注意,这是我自己在用的 Emacs 配置,你可以先使用它跑一下 Emacs ,体验一下项目效果。

2. 拷贝 Emacs 配置到你的配置中

!因为支持这个项目的配置已经单独抽离了出来 – init-site.el ,所以,可以很方便的把它拷贝到你自己的 Emacs 配置中。

另外,因为我的配置文件是用 use-package 组织管理的,如果你自己的配置不是基于它的,你就不得不安装 use-package 了,很简单,只需要贴入如下一段配置即可(并不会影响你原来的配置):

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))

只要保证上述 use-package 的安装代码,在 init-site.el 中的配置之前执行即可(你总得先安装了它,才能使用它,是吧)。

至此,所有的准备工作,都已经完成了!

启动 Emacs 后,打开 ...site/org/index.org 文件,执行 M-x preview-current-buffer-in-browser 即可看到效果。

简介

本文旨在介绍如何利用 org-publish.org 文件生成为 .html ,以及如何解决静态文件(主要是图片)的缩放问题。

Emacs 是一个强大的 “编辑器” ,或者说 “操作系统” ,它具备强大的可扩展性,拥有丰富的插件, Org Mode 便是其中的佼佼者。 Org Mode 拥有优秀的文本组织方式,并且可以输出多种文本格式,如 .md.txt.html 等。

这个站点 Virgo 的生成方式其实很简单,灵感来自于多方面。感谢 org-html-themes 项目,Virgo 的生成和组织结构都借鉴了该项目。感谢 Emacs China 社区的朋友,它们提供了许多不错的建议和指导。

文件组织方式

→ loveminimal/site

site
|
|-- org                         # .org 文件
|
|-- css                         # 样式文件,已配置
|   |-- style.css
|
|-- images                      # 图片文件
|   |-- xxx.jpg/png/gif
|
|-- js                          # 逻辑文件
|   |-- darkreader.js
|   |-- main.js
|
|-- theme-rose.setup            # 头文件
|
|-- public                      # 发布后生成的 .html 文件及静态文件
|
|-- ...

建议把 site 文件夹放在家目录:

  • GNU/Linux 、 Mac 是 ~/
  • Windows 是 C:\Users\jack\AppData\Roamingjack 是当前电脑的用户名。

这样做有什么好处呢?

在 Emacs 中比较容易跳转,并且同一份 Emacs 配置可以方便地跨平台使用。我在 Windows 上主要使用 git-bash ,直接运行 cd 命令的时候就会跳到这个目录,该目录 C:\Users\jack\AppData\Roaming 被称为漫游家目录。如此,当我切换到 Linux 上使用的时候,就免去了额外的跳转目录思考,在写一些公用脚本的时候也会方便许多。

Emacs 中的配置

目前,并没有把在 Emacs 中的配置,组织成插件,比较分散,这个主题用来介绍 Virgo 站点生成所需要的配置。

在我的 emacs.d 配置中,插件主要使用 use-package 组织管理,它同样也是 spacemacs 项目所采用的的组织方式。

htmlize

该插件用来转换并打开生成的 .html 文件。

(use-package htmlize
  :ensure t
  ;; :config
  ;; (setq htmlize-output-type 'font)
  )

ox-html

(use-package ox-html
  :config
  (setq
   ;; org-html-doctype "html5"
   ;; org-export-default-language "ch"
   user-full-name "Jack Liu"))

ox-publish

这个是 Emacs 中内置的输出功能,它也是 Virgo 站点生成的核心所在。为了不让大家感到困扰,我把 Virgo 没有用到的一些配置代码全部删除了,如果你想了解更多可以查看 init-orgs.el 文件。强烈建议按照默认的配置使用,等熟悉之后再自定义。

↑ 文件组织方式 所述,把 site 文件夹放在家目录,配置中设置 :base-directory 等时设置目录比较方便。

(use-package ox-publish
  :config

  (setq org-publish-project-alist
        '(("orgfiles"
           ;; ; Sources and destinations for files.
           :base-directory "~/site/org/"          ;; ** 源  .org 文件放置的目录
           :publishing-directory "~/site/public/" ;; ** 生成的站点文件放置的目录
           ;; ; Selecting files
           :base-extension "org"
           :recursive t
           ;; ; Publishing action
           :publishing-function org-html-publish-to-html

           ;; ;;; Options for the exporters

           ;; ; Generic properties
           :headline-levels 4
           :section-numbers nil
           :with-author "Jack Liu"                ;; ** 站点拥有者名称
           :with-priority t
           :with-toc t

           ;; ; HTML specific properties
           :html-doctype "html5"

           ;; ; Other options
           :table-of-contents t
           )

          ;; static assets
          ;; 静态文件输出设置
          ("js"
           :base-directory "~/site/js/"
           :base-extension "js"
           :publishing-directory "~/site/public/js/"
           :recursive t
           :publishing-function org-publish-attachment
           )
          ("css"
           :base-directory "~/site/css/"
           :base-extension "css"
           :publishing-directory "~/site/public/css/"
           :recursive t
           :publishing-function org-publish-attachment
           )
          ("images"
           :base-directory "~/site/images/"
           :base-extension "jpg\\|gif\\|png\\|svg\\|gif"
           :publishing-directory "~/site/public/images/"
           :recursive t
           :publishing-function org-publish-attachment
           )
          ("assets"
           :base-directory "~/site/assets/"
           :base-extension "mp3"
           :publishing-directory "~/site/public/assets/"
           :recursive t
           :publishing-function org-publish-attachment
           )

          ("website" :components ("orgfiles" "js" "css" "images"))
          ("statics" :components ("js" "css" "images" "assets"))
          )))

默认输出设置

Emacs 默认的 ox-publish 会输出一些默认格式,因为比价原生,我们把它禁止掉,只保留对于代码块的高亮。

(progn
  "Settings of `org-export'."
  (setq org-export-in-background t
        ;; Hide html built-in style and script.
        org-html-htmlize-output-type 'inline-css ;; 保留代码块高亮
        org-html-head-include-default-style nil
        org-html-head-include-scripts nil
        ))

自定义函数

保存并输出页面

为了减少频繁重复性的操作,我们对默认的输出函数进行了一些封装,如下:

(defun save-and-publish-website()
    "Save all buffers and publish."
  (interactive)
  (when (yes-or-no-p "Really save and publish current project?")
    (save-some-buffers t)
    (org-publish-project "website" t)
    (message "Site published done.")))

(defun save-and-publish-file ()
    "save current buffer and publish."
  (interactive)
  (save-buffer t)
  (org-publish-current-file t))

(defun save-and-publish-statics ()
  "Just copy statics like js, css, and image file .etc."
  (interactive)
  (org-publish-project "statics" t)
  (message "Copy statics done."))

其中:

  • save-and-publish-website 用来保存当前所有 buffer ,并转换输出所有文件;
  • save-and-publish-file 用来保存当前 buffer ,并转换输出当前文件;
  • save-and-publish-statics 只用来拷贝静态文件资源到 public 文件夹。其好处在于,当你只修改了静态文件时,无需再手动地拷贝它们,或是执行 save-and-publish-website 保存输入整个项目(当 .org 文件很多时,速度会很慢)。

建议,绑定两个函数到按键,更加方便操作。如,我使用的 evil 中它们分别被绑定到 <SPC> p p<SPC> p f 按键。

预览当前页面

(defun preview-current-buffer-in-browser ()
  "Open current buffer as html."
  (interactive)
  (let ((fileurl (concat "http://127.0.0.1:8080/" (file-name-base (buffer-name)) ".html")))
    (save-and-publish-file)
    (unless (httpd-running-p) (httpd-start))
    (browse-url fileurl)))

注意,当前函数基于 emacs-web-server 插件,下载并配置如下:

(use-package simple-httpd
  :ensure t
  :config
  (setq httpd-root "~/site/public"))    ;; Set default server directory

如此,当执行 M-x preview-current-buffer-in-brower 时,就可以在默认浏览器中该页面了。

删除 Org 及 Html

有时候,我们会对 .org 文件进行删除操作,为了使网站也删除这个页面,就需要删除其对应的 .html 文件,然而,每次都进行这样的步骤是一件令人讨厌的事。现在,我们可以使用下面这个函数,它会删除当前 .org 文件,且同时删除其生成的 .html 文件。

(defun delete-org-and-html ()
"Delete the relative html when it exists."
(interactive)
(when (yes-or-no-p "Really delete current org and the relative html?")

  (let ((fileurl (concat "~/site/public/" (file-name-base (buffer-name)) ".html")))
    (if (file-exists-p fileurl)
        (delete-file fileurl))
    (delete-file (buffer-file-name))
    (kill-this-buffer)
    (message "Delete org and the relative html done."))))

自定义模式

→ org-hugo-auto-export-mode

以前在使用 ox-hugo 的时候,接触到了 org-hugo-auto-export-mode 这个模式,它用来实现在保存当前 buffer 的时候,自动根据当前 .org 文件内容导出相应的 .md

沿着这个思路,我写了一个类似的 minor mode ,用来实现在保存当前 buffer 的时候,自动导出相应的 .html 文件。如下:

(define-minor-mode auto-save-and-publish-file-mode
  "Toggle auto save and publish current file."
  :global nil
  :lighter ""
  (if auto-save-and-publish-file-mode
      ;; When the mode is enabled
      (progn
        (add-hook 'after-save-hook #'save-and-publish-file :append :local))
    ;; When the mode is disabled
    (remove-hook 'after-save-hook #'save-and-publish-file :local)))

图片

NOTE: 这个章节只是补充,可以不了解。

静态页面的图片输出一直是个让人比较烦扰的问题,在 Windows 上输出指定大小的图片比较不易,我们可以曲线实现,在 .org 文件中插入 Html 标签,如:

#+BEGIN_EXPORT html
<img src="/images/xxx.jpg" width="60%" />
#+END_EXPORT

如此,便可以指定图片输出的宽高。为了方便,你可以使用 yasnippet 写一个快如插入的 snippet ,如:

# -*- mode: snippet -*-
# name: insert img 
# key: ii
# --
<img src="/images/$1" width="${2:6}0%" />

总结

总体来说,比较简单,也不需要下载多少额外的插件,充分利用 Emacs 本身拥有的功能。综上所述,我们来总结一下步骤:

  1. git clone https://github.com/loveminimal/site.git ~/site ,即把 site 文件夹放在家目录;
  2. ↑ Emacs 中的配置 的配置添加到 Emacs 的配置文件中;
  3. 在 Emacs 中执行封装的 ↑ 自定义函数 即可。

如此,生成的 public 文件夹中就是你的站点所需要的一切文件,把它部署到 Github 或是私人服务器即可。

Date: 2020-01-01 Wed 14:26

Author: Jack Liu

Created: 2020-02-09 Sun 20:47

Validate