Orgmode基础

Org mode是Emacs下写文档的一个主模式,非常适用于记笔记、写TODO、制定项目计划等。自从接触Orgmode之后,我便没有离开过,因为她给我带来了太多的便利。

从观感上看,她是一个非常紧凑的标记语言,相比于RST看起来不是那么稀疏。即便是不导出为文档或者页面,也能很好的阅读和跳转。

在书写上,她提供了一组很自然的快捷键,很多文字对象具有相似的结构,在快捷键上也很好的保持一致,如章节和列表的很多快捷键是相同的,功能则完全能够类比。

作为程序员,文学编程让我十分着迷。在文档里引用一段代码,一个简单的按键就能计算结果,这是多么优美的设计。比如可以直接在文档中写一段Python,验证一个小的算法,也可以写一段plantuml,直接接绘制流程图,还可以用表格直接绘制gnuplot图形,其他的很多语言如C语言、R语言等等都是能够直接运行的,你根本不需要去写Makefile,也不需要输入冗长的编译命令,而只需要一个简单的按键。

另外不得不提的就是其优秀的时间管理能力,很大的提高了我的工作效率。

章节操作

快捷键 功能
TAB 展开/折叠章节内容
S-TAB 展开/折叠全文
C-c C-[np] 跳转到前/后一章节
C-c C-[fb] 跳转到前/后同层次章节
C-c C-u 跳转到上一层章节
C-c C-c 设置章节TAG
M-RET 插入新章节
M-S-RET 插入新TODO章节
M-LEFT/M-RIGHT 提升/降低章节层次
M-S-LEFT/M-S-RIGHT 提升/降低子树层次
M-UP/M-DOWN 将子树向上/向下移动
C-c * 将本行切换为标题/正文
C-c ^ 章节排序
C-c @ 选中子树

这些快捷操作都很常用,个人比较喜欢的是全文折叠循环、子树移动、章节排序。

TODO 章节

我倾向于把TODO项作为特殊章节,所以将其放置于章节操作之下。另外我自己定义了一组TODO关键字:

(setq org-todo-keywords
      (quote ((sequence "TODO(t!)" "WORK(k!)" "|" "DONE(d!)")
              (sequence "STOP(p!)" "XFER(x!)" "|" "UNDO(u!)"))))
快捷键 功能
M-S-RET 插入TODO项
C-c C-c 插入标签
C-c C-t 插入TODO状态
S-LEFT/S-RIGHT 轮换TODO状态
C-c / t 查看稀疏树,仅显示未完成项
C-c , 设置优先级,优先级从A到C
S-UP/S-DOWN 提升/降低优先级

快捷键C-c /用于显示稀疏树,通过不同的字符来选择具体显示那种稀疏树:

/ or r Show entries matching a regular expression.
t      Show all TODO entries.
T      Show entries with a specific TODO keyword.
m      Show entries selected by a tags/property match.
p      Enter a property name and its value (both with completion on existing
       names/values) and show entries with that property.
b      Show deadlines and scheduled items before a date.
a      Show deadlines and scheduled items after a date.
d      Show deadlines due within `org-deadline-warning-days'.
D      Show deadlines and scheduled items between a date range.

TODO操作可以通过跟踪子项完成情况来计算进度,只需要在TODO章节行尾插入[/][%],然后执行C-c C-c就能自动计算。这里子项通常是子TODO项,也可以是checkbox列表。

列表操作

无序的列表用减号开头,有序的列表以数字开头,描述列表也是减号开头,用::分割项目和描述。

列表的操作快捷键和章节操作非常类似,如折叠、插入、层次升降、子树移动和排序都是完全对应的。此外TODO章节和checkbox列表对应,章节TAG和checkbox列表的状态对应。

表格操作

表格功能比较遗憾的是不支持多行表格,另外需要注意的一点是,竖线被用来做表格分割符,如果确实需要在表格中输入竖线,则要用\vert来表示。

插图和表格都可以设置名字,格式如下所示,CAPTION用于显示,NAME用于引用。

#+CAPTION: table or figure caption
#+NAME: tbl:tblname
快捷键 功能
C-c C-c 表格自动对齐
TAB/S-TAB 移动到下一格/上一格
M-LEFT/M-RIGHT 将当前列左移/右移
M-S-LEFT 删除当前列
M-S-RIGHT 在左侧插入一列
M-UP/M-DOWN 当前行上/下移
M-S-UP 删除当前行
M-S-DOWN 在当前行上方插入一行
M-a/M-e 移动光标到单元格开始/结尾
C-c - 在下方插入分割线
C-c RET 在下方插入分割线,并跳到下一行
C-c ^ 排序
C-c ' 编辑公式
C-c + 求和
C-c = 执行公式

表格分组

表格在导出时并不显示竖线,竖线仅用于分组,同样横线默认也是不显示的,只有存在行分割线时才会导出横线。列属性需要在属性行上指定,首个单元内容为/的行作为属性行。以<作为组起始符,以>作为组结束符。如下例所示:

| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   < |     |   > |         < |            > |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |   4 |   8 |  16 |    1.4142 |       1.1892 |
| 3 |   9 |  27 |  81 |    1.7321 |       1.3161 |
|---+-----+-----+-----+-----------+--------------|
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt(($1)))

插图操作

插图方法很简单,直接写入图片地址即可,如:

file:fig/logo.png

在导出pdf文档时,通常还需要做一些基本的属性调整,请参考 LaTeX specific attributes 。在表格和图片中都可以使用属性设置,由于图片设置较多,所以将其放于此处。

属性 功能 常用值
float 浮动环境 t nil
placement 浮动位置 H
width 设置宽度 8cm0.8\textwidth
height 设置高度  
align 对齐样式,用于表格  
option 其他选项 angle=90

重点需要说明一下placement选项,其常用值含义如下:

含义
! 忽略浮动对象限制
h here: 置于当前
t top: 页面顶部
b bottom: 页面底部
p page: 置于仅包含浮动对象的页面
H 强制置于此处

源码操作

如果问我最喜欢Orgmode的什么,我会选择源码环境,在这里可以实现优美的文学编程。在编辑文档时,随便插入一段代码,执行C-c C-c就能看到结果,这是非常美好的一件事情。

输入<?TAB就能开启一个引用区,问号用具体的环境标识符替代。其中可以开启的环境类型如下表所示。

快捷键 源码区
s BEGIN_SRC … END_SRC
e BEGIN_EXAMPLE … END_EXAMPLE
q BEGIN_QUOTE … END_QUOTE
v BEGIN_VERSE … END_VERSE
c BEGIN_CENTER … END_CENTER
l BEGIN_LaTeX … END_LaTeX
h BEGIN_HTML … END_HTML
a BEGIN_ASCII … END_ASCII
H HTML
L LaTeX
A ASCII
i INDEX
I INCLUDE

源码环境中常用快捷键如下:

快捷键 功能
C-c ' 编辑源码,即便在INCLUDE指令处也可使用
C-c C-c 对源代码求值

源码环境

源代码环境包括引用名、语言、选项、参数等设定,格式如下。

#+NAME: <refname>
#+BEGIN_SRC <language> <switches> <header arguments>
  <body>
#+END_SRC

如果源码很短,可以用内敛写法:

src_<language>[<header arguments>]{<body>}

同理,如果源码太长,可以将其放置到文件中,用插入的方式引入源码:

#+INCLUDE: <file> src <language>

#+INCLUDE: "~/.emacs" :lines "5-10"   Include lines 5 to 10, 10 excluded
#+INCLUDE: "~/.emacs" :lines "-10"    Include lines 1 to 10, 10 excluded
#+INCLUDE: "~/.emacs" :lines "10-"    Include lines from 10 to EOF

引用名用于交叉引用,一般很少用到,但是它比一般的交叉引用高明的地方是可以直接调用。 Orgmode支持很多语言,请参考 Languages 。最常用选项是行号控制:-n显示行号,+n接着上一个代码区计算行号。

而参数设定相对就比较复杂,常用的是指定变量,输出路径等,请参考 Header arguments

参数 取值 功能
exports code 仅导出源码
  results 导出计算结果
  both 导出源码和结果
  none 都不导出
results value 仅对最后一行语句求值
  output 结果中包含打印输出
  silent 不将计算结果插入到缓冲区
session   指定交互式会话
var   指定变量的值

调用源码块的格式为:

#+CALL: <name>[<inside header arguments>](<arguments>) <end header arguments>

其它环境

EXAMPLE排版风格类似SRC,没有额外语法高亮修饰。 QUOTE会自动断行,不会在每一行按照原样换行。 VERSE会按照原样换行,行首的空白视为缩进,行中的多个空白会被合并,长行会自动换行。 CENTER类似QUOTE,只不过文字居中排版。

语法高亮

导出pdf文档我选择用minted环境,导出html用的是相对本地化的环境。 minted环境使用的其实是Python的Pygmentize语法高亮,可以用如下命令查看语言及风格。

pygmentize -L styles            # 支持的高亮风格
pygmentize -L lexers            # 支持的语言

用minted环境时,编译生成pdf时需要加选项-shell-escape,在风格上,文档我选用bw风格,幻灯片选用vs风格。编译生成html时我采用的是一套自定义白色主题。

交叉引用

快捷键 功能
C-c C-l 插入链接
C-c C-o 打开链接

链接格式分为描述链接和无描述链接:

[[link][description]]                       description link
[[link]]                                    bare link

对于其中的链接,可以分为内部链接和外部链接,内部链接就是文档中定义的交叉引用。外部链接有很多形式,如下所示:

http://www.astro.uva.nl/~dominik            on the web
doi:10.1000/182                             DOI for an electronic resource
file:/home/dominik/images/jupiter.jpg       file, absolute path
/home/dominik/images/jupiter.jpg            same as above
file:papers/last.pdf                        file, relative path
./papers/last.pdf                           same as above
file:/myself@some.where:papers/last.pdf     file, path on remote machine
/myself@some.where:papers/last.pdf          same as above
file:sometextfile::NNN                      file, jump to line number
file:projects.org                           another Org file
file:projects.org::some words               search: <<some words>>, some words
file:projects.org::*task title              search heading: task title
file+sys:/path/to/file                      open via OS, like double-click
file+emacs:/path/to/file                    force opening by Emacs
docview:papers/last.pdf::NNN                open in doc-view mode at page
id:B7423F4D-2E8A-471B-8810-C40F074717E9     Link to heading by ID
news:comp.emacs                             Usenet link
mailto:adent@galaxy.net                     Mail link
mhe:folder                                  MH-E folder link
mhe:folder#id                               MH-E message link
rmail:folder                                RMAIL folder link
rmail:folder#id                             RMAIL message link
gnus:group                                  Gnus group link
gnus:group#id                               Gnus article link
bbdb:R.*Stallman                            BBDB link (with regexp)
irc:/irc.com/#emacs/bob                     IRC link
info:org#External links                     Info node or index link
shell:ls *.org                              A shell command
elisp:org-agenda                            Interactive Elisp command
elisp:(find-file-other-frame "Elisp.org")   Elisp form to evaluate

脚注操作

脚注大体有如下几种格式:

命名脚注[fn:note_1]
内敛命名脚注[fn:note_2: This is footnote 2]
内敛匿名脚注[fn:: This is nanonymous footnote]
[fn:note_1] This is footnote 1.
快捷键 功能
C-c C-c 在定义和引用间跳转
C-c ' 打开窗口编辑脚注

脚注我很少使用,大多数情况下并不需要使用脚注这种功能。

时间管理

和时间操作紧密相关的是TODO章节,因此这部分可以视为对TODO章节的扩展和补充。

快捷键 功能
C-c . 插入日期
C-u C-c . 插入日期和时间
S-LEFT/RIGHT/UP/DOWN 在日历表移动光标
C-c C-d 设置截止日期
C-c C-s 设置调度日期

此外比较贴心的设计了重复任务表示方法,在截至日期上稍作修改,使用+ny/w/m/d/h来设置重复周期。比较有意思的是通过C-c C-t无法直接将其设置为DONE,需要用快捷键C-- 1 C-c C-t才能标记重复任务彻底结束,也就是需要给org-todo传递参数-1。但是不幸的是我已将C--绑定到redo按键上,所以需要用另外的方法:C-u - 1 C-c C-t

字符字号

Table 1: Latex字号表
字号名字 10pt 11pt 12pt
tiny 5 6 6
scriptsize 7 8 8
footnotesize 8 9 10
small 9 10 10.95
normalsize 10 10.95 12
large 12 12 14.4
Large 14.4 14.4 17.28
LARGE 17.28 17.28 20.74
huge 20.74 20.74 24.88
Huge 24.88 24.88 24.88