Org To Site Tutor

Table of Contents

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

如果你是第一次访问这个页面,强烈建议先跳转至附录的 网站功能图示 ↓ 章节,浏览一下站点的功能使用概要(!tip. 页面图片点击可全屏查看哦) :)

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

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

更新日志

1. 预计更新

  • [ ] 本地全局搜索功能;
  • [ ] 添加 RSS 、sitemap 、robots.txt

2. 过往更新

  • 新增执行脚本 copy.sh ,用来在 Emacs 外部同步拷贝图片、JS、CSS 等资源文件,避免修改样式后手动拷贝部署(2020-05-29 Fri 21:04)
  • 新增一个执行脚本 update.sh ,原因详见 关于执行脚本 ↓ (2020-05-26 Tue 16:45);
  • 双击代码块开始复制,10s 后自动恢复行号(原来的悬浮隐藏有的体验不好)(2020-05-17 Sun 13:04)
  • 激活毛玻璃风格(总看纯白色,有点腻歪了……)(2020-05-16 Sat 21:05)
  • 对带行号代码块的处理(复制时隐藏行号,确保复制内容只含代码)(2020-04-17 Fri 15:04)
  • 添加私人 导航页 ← ,包括导航和书签 (2020-04-11 Sat 12:11)
  • 激活 Card 风格主题,如你现在所看到的,如果想恢复到原来的风格,只需要注释 ~/site/js/main.js 中该行代码 (2020-04-06 Mon 16:52)
  • 调整 IDEA 页面 ← 样式,详见 代码实现 (2020-04-04 Sat 02:36)
  • 本地化依赖库,实现点击查看页面全屏尺寸图片(代码实现) (2020-04-03 Fri 21:58)
  • 显示当前代码块类型,详见 代码实现 (2020-04-02 Thu 15:02)
  • 添加 网站功能图示 ↓ (2020-03-27 Fri 19:49)
  • 录制 删除当前文章的宏 ↓ (2020-03-22 Sun 18:55)
  • 视频闲聊这个项目 (2020-03-04 Wed 22:46)

起步

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

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

1: # 进入家目录
2: # → Windows
3: # C:\Users\<用户名>\AppData\Roaming\site
4: cd C:\Users\jack\AppData\Roaming
5: # → Gnu/linux & MacOS
6: cd ~
7: 
8: # 克隆项目到家目录
9: git clone https://github.com/loveminimal/site.git site

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

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

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

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

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

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

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

1: (unless (package-installed-p 'use-package)
2:   (package-refresh-contents)
3:   (package-install 'use-package))
4: 
5: (eval-when-compile
6:   (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 文件。

1: (use-package htmlize
2:   :ensure t
3:   ;; :config
4:   ;; (setq htmlize-output-type 'font)
5:   )

ox-html

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

ox-publish

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

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

 1: (use-package ox-publish
 2:   :config
 3: 
 4:   (setq org-publish-project-alist
 5:         '(("orgfiles"
 6:            ;; ; Sources and destinations for files.
 7:            :base-directory "~/site/org/"          ;; ** 源  .org 文件放置的目录
 8:            :publishing-directory "~/site/public/" ;; ** 生成的站点文件放置的目录
 9:            ;; ; Selecting files
10:            :base-extension "org"
11:            :recursive t
12:            ;; ; Publishing action
13:            :publishing-function org-html-publish-to-html
14: 
15:            ;; ;;; Options for the exporters
16: 
17:            ;; ; Generic properties
18:            :headline-levels 4
19:            :section-numbers nil
20:            :with-author "Jack Liu"                ;; ** 站点拥有者名称
21:            :with-priority t
22:            :with-toc t
23: 
24:            ;; ; HTML specific properties
25:            :html-doctype "html5"
26: 
27:            ;; ; Other options
28:            :table-of-contents t
29:            )
30: 
31:           ;; static assets
32:           ;; 静态文件输出设置
33:           ("js"
34:            :base-directory "~/site/js/"
35:            :base-extension "js"
36:            :publishing-directory "~/site/public/js/"
37:            :recursive t
38:            :publishing-function org-publish-attachment
39:            )
40:           ("css"
41:            :base-directory "~/site/css/"
42:            :base-extension "css"
43:            :publishing-directory "~/site/public/css/"
44:            :recursive t
45:            :publishing-function org-publish-attachment
46:            )
47:           ("images"
48:            :base-directory "~/site/images/"
49:            :base-extension "jpg\\|gif\\|png\\|svg\\|gif"
50:            :publishing-directory "~/site/public/images/"
51:            :recursive t
52:            :publishing-function org-publish-attachment
53:            )
54:           ("assets"
55:            :base-directory "~/site/assets/"
56:            :base-extension "mp3"
57:            :publishing-directory "~/site/public/assets/"
58:            :recursive t
59:            :publishing-function org-publish-attachment
60:            )
61: 
62:           ("website" :components ("orgfiles" "js" "css" "images"))
63:           ("statics" :components ("js" "css" "images" "assets"))
64:           )))

默认输出设置

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

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

自定义函数

保存并输出页面

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

 1: (defun save-and-publish-website()
 2:     "Save all buffers and publish."
 3:   (interactive)
 4:   (when (yes-or-no-p "Really save and publish current project?")
 5:     (save-some-buffers t)
 6:     (org-publish-project "website" t)
 7:     (message "Site published done.")))
 8: 
 9: (defun save-and-publish-file ()
10:     "save current buffer and publish."
11:   (interactive)
12:   (save-buffer t)
13:   (org-publish-current-file t))
14: 
15: (defun save-and-publish-statics ()
16:   "Just copy statics like js, css, and image file .etc."
17:   (interactive)
18:   (org-publish-project "statics" t)
19:   (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 w<SPC> p f<SPC> p s 按键。

预览当前页面

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

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

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

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

删除 Org 及 Html

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

 1: (defun delete-org-and-html ()
 2: "Delete the relative html when it exists."
 3: (interactive)
 4: (when (yes-or-no-p "Really delete current org and the relative html?")
 5: 
 6:   (let ((fileurl (concat "~/site/public/" (file-name-base (buffer-name)) ".html")))
 7:     (if (file-exists-p fileurl)
 8:         (delete-file fileurl))
 9:     (delete-file (buffer-file-name))
10:     (kill-this-buffer)
11:     (message "Delete org and the relative html done."))))

自定义宏

删除当前文章

目前,我们在 ./index.org 的列表 Table 中管理所有的文章。通过执行这个宏 mc/delete-this-post ,可以同时删除当前光标下的 .org 文件及其对应的 .html 文件。

1: (fset 'mc/delete-this-post
2:    " fo pdydd")

注:这个宏依赖于 delete-org-and-html ↑ 这个函数。

宏,会让人变“懒”。

如, mc/delete-this-post 这个宏其实就是录制了一系列的操作:

  • <SPC> fo ,执行打开光标下的连接;
  • <SPC> pd ,执行 delete-org-and-html 函数;
  • y ,确定执行 delelte-org-and-html 函数;
  • dd ,删除所在光标所在行,即当前文章在主页中的行。

自定义模式

→ org-hugo-auto-export-mode

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

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

 1: (define-minor-mode auto-save-and-publish-file-mode
 2:   "Toggle auto save and publish current file."
 3:   :global nil
 4:   :lighter ""
 5:   (if auto-save-and-publish-file-mode
 6:       ;; When the mode is enabled
 7:       (progn
 8:         (add-hook 'after-save-hook #'save-and-publish-file :append :local))
 9:     ;; When the mode is disabled
10:     (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 或是私人服务器即可。

附录

网站功能图示

1. 文章列表

所有文章在主页列表中管理、分类,光标移入/移出表头,用来切换其内容(文章标题)的显示/隐藏。

2. 主题切换

站点提供了亮/暗两种主题模式,所有页面点击文章标题,即可切换。

3. 目录显隐

光标移入/移出页面左侧(移动端点击页面顶部),用来切换目录的显示/隐藏。

4. 页面锚点

文章中带 上下两种箭头的链接,表示当前页面内锚点,带 左箭头的链接表示站内其它页面的锚点,点击会跳转至相应位置。

5. 返回主页和回到顶部

右下角,包含两个功能按钮 - IDX ← (返回主页)和 TOP ↑ (返回页面顶部,且滚动时显示当前页面滚动百分比)。

关于执行脚本

为什么会有这个脚本?我们来看这样一种场景。

小伙伴甲表示,他正在愉快地写博客,发现“无聊的 Jack”又提交更新了一些东东……

看看提交日志,完全是其个人的一些文章的更新,不用管!(嫌弃 -_||)

看看提交日志,更新了一些小功能还不错,BUT 一但拉取了更新,自己的文章就会被覆盖…… 不更新吧,这次更新的小东西好像还有那么点意思 !_!

这个执行脚本主要解决上述问题,它会保持你的文章状态,在拉取更新后自动恢复它,避免每次手动拷贝 ^_^

已经完工了 ^_^

1. 添加当前 Repo 为新的远程库

  • 执行 git remote -v ,展示当前仓库已经连接的远程库;
  • 执行 git remote add virgo https://github.com/loveminimal/site.git ,添加该远程库;
  • 再次执行 git remore -v ,检查是否添加成功。

2. 在 bash 终端执行脚本

在 Unix/Linux/Mac 下,就是在终端喽,至于 Windows ,你应该在 git-bash 中执行这个脚本(真心不想写 Powershell 脚本了…)。

如果想拉取最近的更新,只需要执行:

1: # 在 site 站点目录下,执行
2: ./update.sh

放心,它会保存你的文章状态,并在拉取更新后恢复它。

Date: 2020-01-01 Wed 14:26

Author: Jack Liu

Created: 2020-05-29 Fri 21:04

Validate