在 Org-mode 语法文档的开头,它将 Org-mode 文本格式称为一种简单,但用途广泛的纯文本格式,既易于使用又能够表示复杂的文档。与 Markdown 破碎的生态相比,Org-mode 的语法非常统一。这大概是由于它内置的功能强于 Markdown 从而足以用于大多数目的,而不用像 Markdown 一样使用 HTML 标签或发明新东西。
首先,Org-mode 语法的组成可以分为对象(object)和元素(element)两类,如果以段落(paragraph)为基准,那么 元素 就是层次大于等于 段落 的组件,也就是不能被段落容纳; 对象 则是比 段落 层次小的东西,可以被段落容纳。这里的段落会在 ox-html 后端中被导出为 <p> 标签。
更进一步,元素可以从大到小分为 heading, section, greater element 和 lesser element 。元素确定了特定的语法环境,在所有元素中只有 heading, section, property drawer 和 planning line 是上下文无关的,其他的语法成分只能存在于特定的环境中。
在所有这些元素中, lesser element 不能容纳其他的元素。比如,段落可被认为是一个小元素,它的里面就不能包含另一个段落。 greater element 可以包含它们自己,以及其他的 greater element 和 lesser element 。 section 可以包含 greater element 和 lesser element , heading 可以包含 section 和其他的 heading 。
变量 org-element-all-elements 提供了完整的元素列表:
( babel-call center-block clock comment comment-block diary-sexp drawer
dynamic-block example-block export-block fixed-width footnote-definition
headline horizontal-rule inlinetask item keyword latex-environment node-property
paragraph plain-list planning property-drawer quote-block section
special-block src-block table table-row verse-block)
(length org-element-all-elements) => 30按照语法文档的分类,上面这些元素可以分为:
- 最大的
headline和section,共 2 个 - greater element ,包括
center-block,quote-block,special-block,drawer,property-drawer,dynamic-block,footnote-definition,inlinetask,item,plain-list,table,共 11 个 - lesser element ,包括
comment-block,example-block,export-block,src-block,verse-block,clock,diary-sexp,planning,comment,fixed-width,horizontal-rule,keyword,babel-call,latex-environment,node-property,paragraph,table-row,共 17 个
变量 org-element-all-objects 提供了完整的对象列表:
( bold citation citation-reference code entity export-snippet footnote-reference
inline-babel-call inline-src-block italic line-break latex-fragment link macro
radio-target statistics-cookie strike-through subscript superscript table-cell
target timestamp underline verbatim)
(length org-element-all-objects) => 24在 Org-mode 语法中,对象的分类不如元素那样细致,不过文档中给出了所谓的最小对象集合和标准对象集合,分别是:
- minimal set of objects:
plain-text,text-markup,entity,latex-fragment,subscript,superscript. 其中text-markup包括bold,italic,underline,verbatim,code和strike-through. 共 11 个 - standard set of objects: 除了
citation和table-cell外的所有对象,共 22 个
Org-mode 本身最高支持无限级别的 headline ,在导出时最高的 headline 导出级别取决于 org-export-headline-levels ,它的默认值为 3 。在 ox-w3ctr 中我使用 org-w3ctr-headline-levels 覆盖了该选项,且将默认值设置为 5 ,这是因为在 ox-html 中 #+TITLE 会被导出为 <H1> 标题,一级 headline 到五级 headline 分别被导出为 <H2> 到 <H6> ,这就是 HTML 支持的所有标题级别了。实际使用中我们很少会用到 3 级以上的 headline 。
以下是不同级别的 headline 例子:
在 Org-mode 中, headline 是一个无缩进的如下结构,Org-mode 语法文档中对 headline 的描述如下:
headline 由级数 STARS ,GTD 关键字 KEYWORDS ,优先级 PRIORITY ,注释标志 COMMENT ,标题内容 TITLE 和标签 TAGS 组成,除 STARS 外其他都是可选项。其中:
STARS包含一个或多个星号*,并带有空格字符SPC后缀。星号的数量决定了headline的级别。因为
headline要求以*开头且与行首之间不能有空格,我们也就不能直接在段落的开头使用*。要解决在一行的开头使用*这个问题,直接的方法是添加空格或零宽空格,不过正确做法是使用,转义,即,*。如果用户加载了
org-inlinetask且*的数量大于等于org-inlinetask-min-level(默认值为 15),那么它会成为一个inlinetask而不是headlineKEYWORD为org-todo-keywords-1中的一个字符串,它被叫做“todo keyword”标准的
org-todo-keywords-1为("TODO" "DONE"),即默认可用的KEYWORD为"TODO"和"DONE"。读者可以参考 Org-mode 文档的 TODO Extensions 一节来扩展关键字。PRIORITY为以#为前缀的带中括号单字符(比如[#A]和[#1]),它被叫做“priority cookie”PRIORITY可以用来记录headline的优先级,默认情况下 Org-mode 支持[#A],[#B]和[#C],不写PRIORITY则默认为[#B]优先级。优先级的使用可以参考 Priorities。COMMENT是字符串"COMMENT",表示headline被注释了,导出时该headline会被忽略TITLE为来自标准对象集合的对象,且不为断行对象TAGS为一系列由:分隔的 token,token 可包含[a-z-A-Z0-9_@#%]TAGS没什么好说的,需要注意的是 tag 名不能包含-字符。TAGS的用法可以参考 Tags。
以下是一些和 headline 操作相关的命令:
TAB(org-cycle),切换headline的显示 Global and local cyclingheadline间的移动命令 MotionC-c C-n(org-next-visible-heading)C-c C-p(org-previous-visible-heading)C-c C-f(org-forward-heading-same-level)C-c C-b(org-backward-heading-same-level)C-c C-u(outline-up-heading)C-c C-j(org-goto)
- 作用于 headline 的编辑命令 Structure Editing
M-LEFT(org-do-promote),M-RIGHT(org-do-demote)M-S-LEFT(org-promote-subtree),M-S-RIGHT(org-demote-subtree)M-UP(org-move-subtree-up),M-DOWN(org-move-subtree-down)
- 设置
headline的TAGSC-c C-c(org-set-tags-command)Setting Tags - 切换
headline的COMMENT状态C-;(org-toggle-comment) - 切换
headline的ARCHIVE标签状态C-c C-x a(org-toggle-archive-tag)
section 包含一个或多个非 heading 元素。粗略来说, section 就是位于 headline 之间的内容。文档中给出的例子如下:
上面内容对应的 AST 为:
在第一个 headline 之前的内容构成的 section 被叫做 zeroth section ,它与普通 section 的区别在于可以直接包含 property drawer 元素,但不能含有 planning 元素,也就是说它允许如下结构:
其中 BLANK-LINES 和 COMMENT 不是必须的。
在这一节中我们会介绍所有二十八个元素,加上上面的 headline 和 section 一共三十个。
greater blocks 之所以 greater 自然是要与 lesser blocks 相对,它们允许包含其他的 greater element 。所有的(就 3 种) greater block 都具有如下结构(其中的 BEGIN 也可为小写):
其中, NAME 是不含空格的字符串,可以为任意不属于 lesser block 的名字; PARAMETERS 是可选的参数,是不含换行的字符串; CONTENTS 为不含 #+END_NAME 行的任意内容。最后一条规则也就注定了它们不能自我嵌套(不过可以相互嵌套)。这些块结构用的最多的时候也许是导出时根据不同后端生成具有相同语义的产物。
在编写 Org-mode 导出后端时,也许我们可以考虑利用这些 block (特别是 special block )以及它们的 PARAMETERS 参数来实现更加丰富的语义。
center-block 就是让其中内容居中的 block,不过在 Org-mode buffer 中并不会居中显示。以下是一个 center block 例子(来自 Paragraphs):
其中 \\ 表示段落内换行,它的效果如下:
Everything should be made as simple as possible,
but not any simpler
类似地, quote block 具有语义上的引用义:
#+BEGIN_QUOTE
你说的对,但是《原神》是由米哈游自主研发的一款全新开放世界冒险游戏。游戏发生在一个被称作「提瓦特」的幻想世界,在这里,被神选中的人将被授予「神之眼」,导引元素之力。你将扮演一位名为「旅行者」的神秘角色,在自由的旅行中邂逅性格各异、能力独特的同伴们,和他们一起击败强敌,找回失散的亲人——同时,逐步发掘「原神」的真相。
你说得对,但是这就是奎桑提,HP 4700,护甲 329,魔抗 201 的英雄。有不可阻挡,有护盾,还能过墙。有控制,甚至冷却时间只有 1 秒,只要 15 点蓝。转换姿态时甚至可以刷新 W 的 cd,还有真实伤害。然后,护甲和魔抗提升后还能获得技能加速,缩短 Q 的 cd,还缩短释放时间,然后还有攻击力。W 就啊啊啊啊啊啊!!!
#+END_QUOTE你说的对,但是《原神》是由米哈游自主研发的一款全新开放世界冒险游戏。游戏发生在一个被称作「提瓦特」的幻想世界,在这里,被神选中的人将被授予「神之眼」,导引元素之力。你将扮演一位名为「旅行者」的神秘角色,在自由的旅行中邂逅性格各异、能力独特的同伴们,和他们一起击败强敌,找回失散的亲人——同时,逐步发掘「原神」的真相。
你说得对,但是这就是奎桑提,HP 4700,护甲 329,魔抗 201 的英雄。有不可阻挡,有护盾,还能过墙。有控制,甚至冷却时间只有 1 秒,只要 15 点蓝。转换姿态时甚至可以刷新 W 的 cd,还有真实伤害。然后,护甲和魔抗提升后还能获得技能加速,缩短 Q 的 cd,还缩短释放时间,然后还有攻击力。W 就啊啊啊啊啊啊!!!
special block 相对特殊一些,它的 NAME 可以为任意非 lesser block 以及 quote 和 center 的名字,比如 #+begin_aside 。它的意义取决于导出后端想要赋予它什么意义:
drawer 具有如下结构:
在 Org-mode Manual 的 Drawers 一节是这样描述它的:
Sometimes you want to keep information associated with an entry, but you normally do not want to see it. For this, Org mode has drawers. They can contain anything but a headline and another drawer.
简单来说, drawer 提供了一种非 headline 的折叠展开内容方法。我们可以通过 C-c C-x d(org-inser-drawer) 插入 drawer 。当某个 region 被选中时,调用该命令会将当前 region 中的内容插入到 drawer 中;当带有前缀参时,该命令会调用 org-insert-property-drawer 来在当前 headline 插入 PROPERTIES drawer 。
如果使用 #+caption: 作为 <details> 中的 <summary> 的话, drawer 将会非常适合作为 details 的对应物,就像这样:
This is a details
Contents are hidden
#include <stdio.h>
int main(void)
{
print("hello world\n");
return 0;
}
property drawer 必须紧接着 headline 或 inlinetask ,作用是为它们提供属性信息:
相比一般 drawer , property drawer 的要求更严格一些,它的 NAME 必须为 PROPERTIES ,而且 CONTENTS 中不能含空行,只能是 node property 。以下是一个例子:
本节的标题 property drawer 就具有一个 CUSTOM_ID 属性,读者可以查看本 HTML 页面的源代码找到它的 ID。
dynamic block 结构如下:
其中 NAME 是不含空格的字符串; PARAMETERS 是可选的参数字符串,不含换行符; CONTENTS 是除 dynamic block 外的零个或多个其他元素。
在 dynamic block 的文档 Dyanmci Block 中对参数结构有更精细的描述,它应为 :parameter1 value1 :parameter2 value2 ... ,不过也不是非得这样,使用 (org-element-property :arguments dynamic-block) 获取到的参数就是一整个字符串。
根据文档的说法, dynamic block 可以根据用户函数对块中的内容进行自动更新。我们可以通过 C-c C-x x(org-dynamic-block-insert-dblock) 来在当前位置插入 dynamic block ,并通过 C-c C-x u(org-dblock-update) 来更新块的内容。我们可以添加 org-update-all-dblocks 到某些 hook 中来在必要时触发所有 dynamic block 的更新。读者可以阅读文档以及 org-dblock-write:clocktable 来学习如何编写生成和更新 dynamic block 的函数。
footnote definition 是脚注的定义部分,它和 headline 一样必须顶格,它的结构如下:
其中 LABEL 是数字或由 [[:word:]-_] 组成的字符串,用来标识对应的脚注, CONTENTS 为脚注的内容,它在下一个 footnote definition 之前结束,或者是下一个 headline 、两个连续的换行、或 buffer 的末尾。这是一些例子,注意在第二个脚注中,隔了一行的字符串仍属于该脚注:
Org-mode 支持三种形式的脚注,具体的用法可以参考 Creating Footnotes。
下面是一段来自维基百科的内容,我改成了 Org-mode 格式:
Wikipe-tan (Japanese[fn:Japanese]: ウィキペたん) is a personification of Wikipedia[fn:Wikipedia] created in January 2006 by Japanese editor Kasuga[fn:Kasuga] She is an unofficial mascot of Wikipedia and is used at several WikiProjects. The -tan in "Wikipe-tan" is an affectionate suffix, in the form of a Japanese honorific. Like the OS-tans, she is a product of moe anthropomorphism.
[fn:Japanese] Janapanese 的 wiki 链接:https://en.wikipedia.org/wiki/Japanese_language
[fn:Wikipedia] Wikipedia 的链接:https://en.wikipedia.org/wiki/Wikipedia
[fn:Kasuga] In the aftermath of the unified login finalization, the user now going by Kasuga on Commons and on English Wikipedia is a different person. The accounts of the creator of Wikipe-tan were renamed Kasuga~enwiki, Kasuga~jawiki and Kasuga~commonswiki.Wikipe-tan (Japanese[Japanese]: ウィキペたん) is a personification of Wikipedia[Wikipedia] created in January 2006 by Japanese editor Kasuga[Kasuga] She is an unofficial mascot of Wikipedia and is used at several WikiProjects. The -tan in "Wikipe-tan" is an affectionate suffix, in the form of a Japanese honorific. Like the OS-tans, she is a product of moe anthropomorphism.
请点击脚注链接跳转到定义部分。
除了上述标准脚注外,Org-mode 还支持匿名脚注和内联脚注,它们的导出效果如下:
当 headline 的星号数量大于等于 org-inlinetask-min-level 时,它就成了 inlinetask ,不过仅在 org-inlinetask 加载后才会有 inlinetask 。这个功能我从来没用使用过。下面是一个例子:
*************** TODO some tiny task
This is a paragraph, it lies outside the inlinetask above.
*************** TODO some small task
DEADLINE: <2009-03-30 Mon>
:PROPERTIES:
:SOMETHING: or other
:END:
And here is some extra text
*************** END
我在 Org-mode Manual 中居然没有找到 inlinetask 的章节。
item 是单个列表项,它在内部可以嵌套 item ,结构如下:
其中:
BULLET是表头符号,对无序列表可以是*,-或+注意顶格的
*不能作为item开头,因为它会被识别为headline;对有序列表需要是一个数字或单个a-z的字符加上.或),比如1.和a)COUNTER-SET指定有序列表的序号值,格式为[@COUNTER]CHECK-BOX选择框,可以为[ ],[X]或[-]TAG格式为TAG-TEXT ::,其中TAG-TEXT会作为标准集合对象解析CONTENTS为零个或多个元素,并在遇到以下情况时结束- 下一个
item - 相比起始行具有更浅或相同缩进的行,这不计算其他非段落元素或 inlinetask 边界内的行
- 两个连续的换行
- 下一个
下面是文档中给出的例子:
- item
3. [@3] set to three
+ [-] tag :: item contents
* item, note whitespace in front
* not an item, but heading - heading takes precedence
Org-mode Manual 的 Plain Lists 一节对列表进行了更为细致的描述。上面提到的 TAG 用于生成所谓的 description list ,在 HTML 导出后端中,它会使用不同于 ol 和 ul 的标签。
这是一个无序列表例子:
- 第一项
- 第二项
- 第三项
这是一个有序列表的例子:
- いいよ,こいよ
- 伊已逝,吾亦逝
- 意易失,吾亦逝
- 逸一时,误一世
- 疑一时,误一世
- こめいじ こいし
这是一个描述性列表的例子:
- 你好
- 今日は
- 再见
- また明日
plain list 就是一系列具有相同缩进的连续 item 。文档中给出了一个 plain list 对应的 AST:
(ordered-plain-list
(item
(paragraph))
(item
(paragraph)
(descriptive-plain-list
(item
(paragraph)))))Org-mode Manual 在 Plain Lists 一节给出了一些方便的命令,这里简单列出部分:
S-UPS-DOWN,移动到当前列表的下一个/上一个itemM-UPM-DOWN,将当前item上移/下移一位M-LEFTM-RIGHT,减少/增加当前item的缩进,不处理子itemC-c C-c,切换Checkbox的状态
Org-mode 支持两种表格,一种来自 Org-mode 自己,另一种来自 Emacs 的 table.el,这两种表格的性状略有不同。Org-mode 表格以 | 开头而 tabel.el 以 +- 开头。以下代码展示了两者的不同之处:
表格由一行行的 lesser element table row 组成,我们会在后文介绍它。以下是一个表格例子:
| Name | Phone | Age |
|---|---|---|
| Peter | 1234 | 24 |
| Anna | 4321 | 25 |
Org-mode 的表格功能非常强大,支持一定程度的运算功能,可以看作是“穷人的 Excel”。 table 的具体用法可以参考 Org-mode Manual 的 Tables 一章。
(从 block 开始就是 lesser block 了,因此我加粗了标题)
lesser block 具有与 greater block 相似的结构:
其中, NAME 只能为以下各小节标题其中之一, DATA 同样是一个不含断行的字符串, CONTENTS 不含 #+END_NAME 。关于各 lesser block 的文档如下列表所示:
comment block 即注释块。在导出时它们不会被导出。
example block 通常用于显示代码或文字的样例,它会保留原始样式,包括空格和换行,以便准确显示内容。
我们可以通过 export block 指定一段内容针对特定导出后端的内容,这允许在同一文档中为不同的导出格式定制内容。对 HTML 后端来说,我们可以有如下做法:
以下代码可以导出颜色为红色的 hello world :
src block 算是 Org-mode 的重量级特性,在 Org-mode Manual 中专门有一章介绍它的用法。在 src block 中, DATA 的格式如下:
其中 LANGUAGE 是源代码块的语言,为一无空格字符串; SWITCHES 是由空格分隔的任意数量 SWITCH 模式;最后的 ARGUMENTS 为无折行字符串。其中 SWITCH 的写法可以参考上面给出的 Literal Examples 文档,而 ARGUMENTS 参数可以参考 Using Header Arguments。
和导出相关的 ARGUMENTS 为 :exports ,可以指定 code, results, both 和 none 四种选项。其中 code 为默认选项,即导出代码, results 为导出代码的执行结果, both 为导出两者, none 则不导出代码块。
以下是一个 src block 例子:
#+begin_src emacs-lisp
"This string
* has "*" escaped.
Otherwise, '* has "*" escaped.' would be treated as a heading (which
is context-free)."
"#+ lines may or may not need to be escaped:
#+end_src if not escaped, would be this source block.
However,
#+keyword: does not interfere with code block end and may be left as is.
#+keyword may be escaped as well, optionally - parser removes all the
commas in ,* and ,#+ lines."
#+end_src
我们可以使用 org-export-use-babel 来控制代码导出时是否使用 babel 处理代码,我发现设置它为 nil 能缩短不少的时间,因此我用 org-w3ctr-use-babel 覆盖了这个选项,并设置其默认值为 nil 。
verse block 的功能非常简单,就是保持文本的结构,但它没有 example block 那么强,除了换行和缩进外它不会改变其他对象的格式。在以下例子中,若代码块环境为 example ,那么 = 内容在 HTML 导出中会直接显示等于号,而不是生成 <code> 标签:
#+BEGIN_VERSE
Great clouds overhead
Tiny black birds rise and fall
Snow covers Emacs
---AlexSchroeder, =hello=
#+END_VERSE
Great clouds overhead
Tiny black birds rise and fall
Snow covers Emacs
—AlexSchroeder, hello
clock 元素的形状如下:
其中的 INACTIVE-TIMESTAMP 和 INACTIVE-TIMESTAMP-RANGE 都是 timestamp 对象(下文会介绍)。 DURATION 的格式为 HH:MM 。一个简单的例子如下:
diary sexp 是一个无缩进的如下结构:
例子如下:
diary-sexp 的具体用法可以参考 Sexp Entries and the Fancy Diary Display。
planning 元素具有如下结构:
其中 PALNNING 一行包含一个或多个 KEYWORD: TIMESTAMP 模式, KEYWORD 可为 DEADLINE, SCHEDULED 或 CLOSED , TIMESTAMP 为一个 timestamp 对象。 planning 必须紧随 heading ,两者之间不能有空行。
文档给出的例子如下:
除了上面提到的 comment block ,Org-mode 也支持单行注释,只需要一个顶格 # 加上空格即可:
自然,注释是不会导出的。
以 : 加空格开头的行将成为单行 example block ,不过在 ox-html 中我们无法通过 attr_html 为其添加其他 HTML 属性。
This is a fixed width.
如果一行以 - 开头且至少有 5 个连续的 - 符号,那么它会成为一个 horizontal rule ,在 ox-html 中它导出为 <hr> 标签,在 ox-w3ctr 中同样也是。
keywords 的形式如下:
其中:
KEY- 一个除
call外含无空格字符的字符串 VALUE- 不含换行符的任意字符串
当 KEY 是 org-element-parsed-keywords 中的任一成员时, VALUE 可以包含除 footnote reference 的任意标准对象(第一节提到的标准对象集合)。 org-element-parsed-keywords 的值如下所示:
在 ox-html 中, org-html-keyword 实现为可以导出 HTML 和 TOC 关键字,前者用于导出 HTML 代码片段,后者用于导出局部目录。
如果 KEY 为 call 那么 keywords 就是 babel call ,它具有以下几种可能的形式:
#+call: NAME(ARGUMENTS)
#+call: NAME[HEADER1](ARGUMENTS)
#+call: NAME(ARGUMENTS)[HEADER2]
#+call: NAME[HEADER1](ARGUMENTS)[HEADER2]
其中, NAME 是不含换行符和 []() 的任意字符串; ARGUMENTS 是可选的参数,包含任意非换行符字符,不过开括号和回括号必须配平; HEADER1 和 HEADER2 是可选的参数,同样它们由非换行符组成,且要求括号配平。
我几乎没有使用过 Org-mode 的 babel 功能,此处不详细展开。
所谓的 affiliated keyword (关联关键字)可以依附于某个元素来提供一些额外的信息,比如 #+attr_html 可以为某个元素提供一些 HTML 属性。 affiliated keywords 具有如下结构:
其中, KEY 是一个位于 org-element-affiliated-keywords 中的成员; BACKEND 是一个由 [a-zA-Z0-9-_] 组成的字符串,对 HTML 后端就是 html ; OPTVAL 是不含换行符的字符串,且括号必须配平,它仅在 KEY 属于 org-element-dual-keywords 时有效; VALUE 是不含换行符的字符串,不过当 KEY 属于 org-element-parsed-keywords 时有例外可以换行。
org-element-affiliated-keyword 给出了可用的 affiliated 关键字:
(defconst org-element-affiliated-keywords
'("CAPTION" "DATA" "HEADER" "HEADERS" "LABEL" "NAME" "PLOT" "RESNAME" "RESULT"
"RESULTS" "SOURCE" "SRCNAME" "TBLNAME"))
(defconst org-element-dual-keywords '("CAPTION" "RESULTS")
"List of affiliated keywords which can have a secondary value.
In Org syntax, they can be written with optional square brackets
before the colons. For example, RESULTS keyword can be
associated to a hash value with the following:
#+RESULTS[hash-string]: some-source
This list is checked after translations have been applied. See
`org-element-keyword-translation-alist'.")需要注意的是,某些关键字已经过时了:
(defconst org-element-keyword-translation-alist
'(("DATA" . "NAME") ("LABEL" . "NAME") ("RESNAME" . "NAME")
("SOURCE" . "NAME") ("SRCNAME" . "NAME") ("TBLNAME" . "NAME")
("RESULT" . "RESULTS") ("HEADERS" . "HEADER")))根据翻译表,现在推荐使用的 affiliated 关键字有:
- CAPTION (dual)
- NAME
- HEADER
- PLOT
- RESULTS (dual)
除了 comments, clocks, headings, inlinetasks, items, node properties, planning, property drawers, sections 和 table rows 外,其他的元素都可以被赋予 affiliated keyword 。
在一个元素上重复使用某个 affiliated keyword 将会导致先前的值被最后一个值覆盖。唯一的例外是 header :
The sole exception to this is
#+header: keywords, where in the case of multiple:opt valdeclarations the last declaration on the first line it occurs on has priority.唯一的例外是
#+header:关键字,在存在多个:opt val声明的情况下,优先考虑首次出现的行上的最后一个声明。
此外,如果 KEY 属于 org-element-dual-keywords 或 KEY 为 #+attr_BACKEND ,那么多个 VALUE 会被连接起来得到最终的 VALUE 。文档给出了这样的例子:
latex environment 具有以下结构:
其中, NAME 是一个包含字母数字或 * 的字符串, EXTRA 是不含 \end{NAME} 内容的字符串, CONTENTS 是不含 \end{NAME} 的字符串。以下是一个简单的例子:
node property 只能存在于 property drawer 中,它具有如下结构:
其中, NAME 是不含空白字符且不以 + 结尾的字符串, VALUE 是不含换行符的字符串。
和 babel call 一样,我基本上没有用过。
paragraph 是默认的元素,空行和其他元素会终止段落。
table row 由 | 跟着以下情况组成:
- 任意数量的
table cell - 一个
-,表示这是一行“规则”行
table row 只能存在于 table 中。
对象可以出现在以下元素中:
keyword的VALUES中,要求KEY属于org-element-parsed-keywordsheadline的TITLEinlinetask的TTILEitem的TAGclock的INACTIVE-TIMESTAMP和INACTIVE-TIMESTAMP-RANGE,不过只能包含 inactive timestampplanning的TIMESTAMP,只能是 timestampparagraphtable celltable row,只能是table cell对象verse block
在 Org-mode 中, entity 具有如下结构:
其中, NAME 是一个存在于 org-entities 或 org-entities-user alist 中的键; POST 是一个非字母(non-alphabetic)字符, SPACES 是一个或多个空格。以下是文档给出的例子:
1¢. 1.5em space: here, all three spaces in = = constitute the entity name.
org-entities 和 org-entities-user 的值分别如下:
org-entities =>
("* Letters" "** Latin" ("Agrave" "\\`{A}" nil "À" "A" "À" "À")
("agrave" "\\`{a}" nil "à" "a" "à" "à") ("Aacute" "\\'{A}" nil "Á" "A" "Á" "Á")
("aacute" "\\'{a}" nil "á" "a" "á" "á") ("Acirc" "\\^{A}" nil "Â" "A" "Â" "Â")
("acirc" "\\^{a}" nil "â" "a" "â" "â") ("Amacr" "\\={A}" nil "Ā" "A" "Ã" "Ã")
("amacr" "\\={a}" nil "ā" "a" "ã" "ã") ("Atilde" "\\~{A}" nil "Ã" "A" "Ã" "Ã")
("atilde" "\\~{a}" nil "ã" "a" "ã" "ã") ...)
(length org-entities) => 435
org-entities-user => nil在 Org-mode 语法文档的附录给出了完整的 entry 列表,这里用几个可能比较常用的作为示例:
\alpha \beta \gamma \delta \epsion \eta \theta \lambda \pi \phi \omega \dots \laquo \raquo \lsaquo \rsaquo \vert \S \copy \trade \pm \times \div \frac12
\larr \lArr \uarr \uArr \rarr \rArr \darr \dArr \harr \hArr \crarr \oplus \otimes \checkα β γ δ \epsion η θ λ π φ ω … « » ‹ › | § © ™ ± × ÷ ½
← ⇐ ↑ ⇑ → ⇒ ↓ ⇓ ↔ ⇔ ↵ ⊕ ⊗ ✓
我们也可以直接使用 C-x 8 RET 来选择并输入 Unicode 字符。
LaTex fragment 具有如下结构:
其中, NAME 是不存在于 org-entites 和 org-entites-user alist 的字符串, BRACKETS 是以下结构,它与 NAME 间不能存在空格:
CONTENTS1 不能包含 {}[] 和换行符, CONTENTS2 不能包含 {} 和换行符。以下是一些例子:
但是,这种 LaTeX fragment 似乎在 LaTeX 后端会更加有用,在 HTML 后端中它们保持了原样。
对于第二种和第三种 LaTeX fragment , CONTENTS 是可以包含任意字符的字符串,不过第二种不能包含 \) ,第三种不能包含 \] ,以下是两个简单的例子:
\[\left(\begin{matrix}y_0\\y_1\\y_2\\\vdots\\y_{N-1}\end{matrix}\right) = \left(\begin{matrix}1&1&1&\dots&1\\1&W_N^1&W_N^2&\dots&W_N^{N-1}\\1&W_N^2&W_N^4&\dots&W_N^{2(N-1)}\\\vdots&\vdots&\vdots&\cdots&\vdots\\1&W_N^{N-1}&W_N^{2(N-1)}&\dots&W_N^{(N-1)^2}\end{matrix}\right) \left(\begin{matrix}x_0\\x_1\\x_2\\\vdots\\x_{N-1}\end{matrix}\right)\]
\(x_n = \frac1N \sum\limits_{k=0}^{N-1}e^{2\pi ik\frac nN}y_k \quad (n=0, 1, 2, \dots, N-1)\)\[\left(\begin{matrix}y_0\\y_1\\y_2\\\vdots\\y_{N-1}\end{matrix}\right) = \left(\begin{matrix}1&1&1&\dots&1\\1&W_N^1&W_N^2&\dots&W_N^{N-1}\\1&W_N^2&W_N^4&\dots&W_N^{2(N-1)}\\\vdots&\vdots&\vdots&\cdots&\vdots\\1&W_N^{N-1}&W_N^{2(N-1)}&\dots&W_N^{(N-1)^2}\end{matrix}\right) \left(\begin{matrix}x_0\\x_1\\x_2\\\vdots\\x_{N-1}\end{matrix}\right)\]
\(x_n = \frac1N \sum\limits_{k=0}^{N-1}e^{2\pi ik\frac nN}y_k \quad (n=0, 1, 2, \dots, N-1)\)
除了上面几种形式,Org-mode 也支持 TeX 风格的 LaTeX fragment :
其中:
- PRE
- 一行的开头或任意非
$符号的字符 - CHAR
- 不是
.,?;"的非空白字符 - POST
- 任何标点符号(包括括号和引号)、空格字符或行尾
- BORDER1
- 不是
.,;$的非空白字符 - BODY
- 不含
$的任意字符串 - BORDER2
- 不是
.,;$的非空白字符
export snippet 具有如下结构:
其中 BACKEND 是某导出后端的名字, VALUE 是不含 @@ 的任意字符串。简单的例子如下:
我是插入标签 我是删除标签
footnote reference 具有如下结构:
其中, LABEL 是一个不含空格的字符串,可包含 -_ ; DEFINITION 是标准对象,我们已经在 footnote definition 对这种对象进行了简单的举例,此处不再赘述。
citation 具有如下结构:
[cite CITESTYLE: REFERENCES]
[cite CITESTYLE: GLOBALPREFIX;REFERENCES]
[cite CITESTYLE: REFERENCES;GLOBALSUFFIX]
[cite CITESTYLE: GLOBALPREFIX;REFERENCES;GLOBALSUFFIX]文档中给出了如下例子:
ox-html 没有导出 citation 。
citation reference 只能存在于 citation 中,且具有如下结构:
文档给出了如下例子:
[cite:@key]
[cite/t:see;@foo p. 7;@bar pp. 4;by foo]
[cite/a/f:c.f.;the very important @@atkey @ once;the crucial @baz vol. 3]
同样, ox-html 不导出 citation reference 。
inline babel call 具有如下结构:
call_NAME(ARGUMENTS)
call_NAME[HEADER1](ARGUMENTS)
call_NAME(ARGUMENTS)[HEADER2]
call_NAME[HEADER1](ARGUMENTS)[HEADER2]
其中, NAME 是包含除 []() 字符外任意字符的字符串, ARGUMENTS, HEADER1 和 HEADER2 是不含换行符的字符串,且括号必须配平。
inline source block 具有如下结构:
其中, LANG 是不含空格和 [{ 的字符串,表示块中的语言; HEADERS 和 BODY 是不含换行符的字符串, HEADER 中的方括号要求配平, BODY 中的大括号要求配平。
以下是一段简单的 C 代码例子:
int a = 114514; printf("%d\n", a);
line break 即换行符,它具有以下结构:
其中, PRE 是除 \ 外的任意东西, SPACE 是 0 个或多个 TAB 或 SPACE 字符。以下是一个简单的例子:
1
2
3
在 ox-html 中, line break 实现为 <br> 标签。
在 Org-mode 中 link 的种类很多,包括 radio, angle, plain 和 regular 。
radio link 具有如下结构:
其中 PRE 是非字母字符, RADIO 是一个或多个由 radio target 匹配的对象,它只能是最小对象(见第一节对最小对象的描述), POST 是非字母字符。下面是一个简单的例子:
This is some <<<*important* information>>> which we refer to lots.
Make sure you remember the *important* information.This is some important information which we refer to lots. Make sure you remember the important information. 读者可打开 HTML 源代码查看链接及标签的 id 属性。
在 ox-html 中,若 :html-prefer-user-labels 在导出过程中的值非 nil ,那么 radio target 的 id 会使用它的字符串内容,但是标准 HTML id 要求满足 [a-zA-Z][a-zA-Z0-9-_]* 正则匹配,生成的 id 可能不合规范。
plain link 具有如下结构:
其中, PRE 是一个不组成 word 的字符, LINKTYPE 是 org-link-parameters 中的一种链接类型, PATHPLAIN 是链接, POST 和 PRE 同理。以下是一个简单的例子:
Be sure to look at https://orgmode.org.
angle link 可以用来消除 plain link 与周围文本的歧义,具有如下结构:
其中的 LINKTYPE 和 PATHANGLE 和 plain link 具有相同含义。我几乎从来没有使用过它。
regular link 具有以下两种形式:
其中, PATHREG 可以是以下形式:
FILENAME ("file" type)
LINKTYPE:PATHINNER ("LINKTYPE" type)
LINKTYPE://PATHINNER ("LINKTYPE" type)
id:ID ("id" type)
#CUSTOM-ID ("custom-id" type)
(CODEREF) ("coderef" type)
FUZZY ("fuzzy" type)以下是一些例子:
macro 调用具有以下两种形式:
其中, NAME 是宏的名字,满足正则 [a-zA-Z0-9-_] , ARGUMENTS 是宏参数。以下是一些例子:
target 具有如下形式:
其中 TARGET 不能包含 <> 和换行符,且不能以空白字符起始或结尾。
radio target 具有以下形式:
其中的 CONTENTS 必须来自最小对象集合,且不含 <> 和换行符。
以下是 target 和 radio target 的两个简单例子,读者可以打开 HTML 源代码查看其 id 以及标签:
statistics cookie 具有如下结构:
它可以用来统计完成情况,比如如下列表:
- Hello
[2/3][66%]- ☑ one
- ☑ two
- ☐ three
在 ox-html 中它实现为 <code> 标签包围的文本。
subscript 和 superscript 的结构如下:
其中 CHAR 为任意非空格字符, SCRIPT 可以是如下情况:
- 单个
*号 - 使用大括号包围的表达式,表达式本身应该是大括号配平的,且属于标准对象集合
如下形式:
其中
SIGN可以是+或-或空字符串,CHARS由任意数量的[a-zA-Z0-9],,,\和.组成,FINAL是一个[a-zA-Z0-9]字符
table cell 为如下形式:
其中 CONTENTS 不能包含 | 字符,且必须只能包含最小对象集合内的对象加上 citation, export snippet, footnote reference, link, macro, radio target, target 和 timestamp 。
timestamp 可以是如下形式:
<%%(SEXP)> (diary)
<DATE TIME REPEATER-OR-DELAY> (active)
[DATE TIME REPEATER-OR-DELAY] (inactive)
<DATE TIME REPEATER-OR-DELAY>--<DATE TIME REPEATER-OR-DELAY> (active range)
<DATE TIME-TIME REPEATER-OR-DELAY> (active range)
[DATE TIME REPEATER-OR-DELAY]--[DATE TIME REPEATER-OR-DELAY] (inactive range)
[DATE TIME-TIME REPEATER-OR-DELAY] (inactive range)*, a bold object, 粗体/, an italic object, 斜体_, an underline object, 下划线=, a verbatim object,引述~, a code object,代码+, a strike-through object.删除线
什么对象也不是的对象就是 plain text 。
本文差不多就是把 Org-mode 的语法文档翻译了一下,想要查看更加严谨描述的同学可以看看原文去。我在今年 4 月份写完了 ox-w3ctr 这个 Org-mode 的导出后端以及这篇测试文档,现在总算是有时间改改之前的代码,顺便加加文档了。