使用 ‘var’ 向源代码块传递参数。代码块中变量的具体用法因语言而异,详见各语言专属文档,但 ‘var’ 的语法对所有语言统一,包括变量声明与默认值赋值。
使用 ‘var’ 头部参数向代码块传递参数的语法格式为:
:var NAME=ASSIGN
NAME 为代码块主体中绑定的变量名。ASSIGN 可以是字面量(字符串、数字)、表格引用、列表、字面量示例、其他代码块(可带参数),或是某代码块的执行结果。ASSIGN 也可通过冒号分隔文件名与引用目标,指定外部文件中的元素。
:var NAME=FILE:REFERENCE
若 ‘FILE’ 不存在,则直接在当前文件中按原引用名称查找。因此 ‘:var table=tbl:example’ 会在当前缓冲区中查找对应表格。
以下为按引用传递值的示例:
使用 ‘NAME’ 关键字命名的表格。
#+NAME: example-table | 1 | | 2 | | 3 | | 4 | #+NAME: table-length #+BEGIN_SRC emacs-lisp :var table=example-table (length table) #+END_SRC #+RESULTS: table-length : 4
传递表格时,可对包含列名/行名的行或列进行特殊处理。
‘colnames’ 头部参数可取值 ‘yes’ 、 ‘no’ 或 ‘nil’ ,默认 ‘nil’ :若输入表格存在列名(第二行为横线),Org 会先移除列名,处理表格后再恢复列名并写入结果。取值 ‘yes’ 时,即使表格无横线,也会对首行非横线内容执行相同逻辑。取值 ‘no’ 时则完全不预处理列名。
#+NAME: less-cols | a | |---| | b | | c | #+BEGIN_SRC python :var tab=less-cols :colnames nil return [[val + '*' for val in row] for row in tab] #+END_SRC #+RESULTS: | a | |----| | b* | | c* |
同理, ‘rownames’ 头部参数可取 ‘yes’ 或 ‘no’ 。取值 ‘yes’ 时,Org 会移除首列,处理表格后恢复并写入结果;默认 ‘no’ ,即不处理首列。注意 Emacs Lisp 代码块会忽略 ‘rownames’ 参数,因其表格操作较为简便。
#+NAME: with-rownames | one | 1 | 2 | 3 | 4 | 5 | | two | 6 | 7 | 8 | 9 | 10 | #+BEGIN_SRC python :var tab=with-rownames :rownames yes return [[val + 10 for val in row] for row in tab] #+END_SRC #+RESULTS: | one | 11 | 12 | 13 | 14 | 15 | | two | 16 | 17 | 18 | 19 | 20 |
引用其他文件中的表格,可使用冒号连接文件名与表名,例如: ‘:var table=other-file.org:example-table’ 。
简单的命名列表。
#+NAME: example-list - simple - not - nested - list #+BEGIN_SRC emacs-lisp :var x=example-list (print x) #+END_SRC #+RESULTS: | simple | list |
注意仅顶层列表项会被传递,嵌套列表项会被忽略。
由 ‘NAME’ 关键字命名的代码块,后可接空括号。
#+BEGIN_SRC emacs-lisp :var length=table-length() (* 2 length) #+END_SRC #+RESULTS: : 8
由 ‘NAME’ 关键字指定的代码块名称,后接括号,并可在括号内传入可选参数。 执行该代码块时,光标会定位在其所在位置。
#+NAME: double #+BEGIN_SRC emacs-lisp :var input=8 (* 2 input) #+END_SRC #+RESULTS: double : 16 #+NAME: squared #+BEGIN_SRC emacs-lisp :var input=double(input=1) (* input input) #+END_SRC #+RESULTS: squared : 4
使用 ‘NAME’ 关键字命名的代码块或字面示例块,后接方括号(示例块可省略)。
#+NAME: literal-example #+BEGIN_EXAMPLE A literal example on two lines #+END_EXAMPLE #+NAME: read-literal-example #+BEGIN_SRC emacs-lisp :var x=literal-example[] (concatenate #'string x " for you.") #+END_SRC #+RESULTS: read-literal-example : A literal example : on two lines for you.
通过索引可引用变量的部分内容。索引从 0 开始,负数表示从末尾倒数。逗号分隔的索引对应后续维度。注意索引操作在 ‘hlines’ 、 ‘colnames’ 、 ‘rownames’ 等表格相关参数生效 之前 执行。下面示例将表格 ‘example-table’ 首行最后一个单元格赋值给变量 ‘data’ :
#+NAME: example-table | 1 | a | | 2 | b | | 3 | c | | 4 | d | #+BEGIN_SRC emacs-lisp :var data=example-table[0,-1] data #+END_SRC #+RESULTS: : a
两个整数以冒号分隔表示取值范围,包含起止位置。下面示例将 ‘example-table’ 的中间三行赋值给 ‘data’ :
#+NAME: example-table | 1 | a | | 2 | b | | 3 | c | | 4 | d | | 5 | 3 | #+BEGIN_SRC emacs-lisp :var data=example-table[1:3] data #+END_SRC #+RESULTS: | 2 | b | | 3 | c | | 4 | d |
使用空索引或单个 ‘*’ 表示选取全部范围, ‘0:-1’ 效果相同。下面示例仅引用第一列:
#+NAME: example-table | 1 | a | | 2 | b | | 3 | c | | 4 | d | #+BEGIN_SRC emacs-lisp :var data=example-table[,0] data #+END_SRC #+RESULTS: | 1 | 2 | 3 | 4 |
索引引用适用于表格与代码块,支持任意维度,逗号分隔多维索引,示例如下:
#+NAME: 3D
#+BEGIN_SRC emacs-lisp
'(((1 2 3) (4 5 6) (7 8 9))
((10 11 12) (13 14 15) (16 17 18))
((19 20 21) (22 23 24) (25 26 27)))
#+END_SRC
#+BEGIN_SRC emacs-lisp :var data=3D[1,,1]
data
#+END_SRC
#+RESULTS:
| 11 | 14 | 17 |
注意行名与列名在索引前不会被移除,即使 ‘colnames’ 或 ‘rownames’ 参数后续会处理,索引时也需将其计入位置。
Emacs Lisp 代码也可直接为变量赋值。为区分普通值与 Lisp 代码,Org 会将以 ‘(’ 、 ‘[’ 、 ‘'’ 或 ‘`’ 开头的值当作 Emacs Lisp 代码执行,执行结果赋值给变量。下面示例展示如何可靠地获取当前 Org 缓冲区文件名并传递给代码块:
#+BEGIN_SRC sh :var filename=(buffer-file-name) :exports both wc -w $filename #+END_SRC
注意从表格与列表中读取的值不会被误解析为 Emacs Lisp 代码,如下例所示:
#+NAME: table | (a b c) | #+HEADER: :var data=table[0,0] #+BEGIN_SRC perl $data #+END_SRC #+RESULTS: : (a b c)
两个代码块可共享同一运行环境。 ‘session’ 头部参数用于让多个源代码块在同一会话中运行,同名会话的代码块会在同一个解释器进程中执行。
默认值。每个代码块启动独立解释器进程,执行完毕后进程终止。
除 ‘none’ 外的任意字符串作为会话名称。例如 ‘:session STRING’ 会将会话命名为 ‘STRING’ 。若 ‘session’ 未设值,会话名由源代码语言标识符生成。后续同语言代码块复用该会话。根据语言不同,状态变量、其他块代码与整体解释环境可能共享。部分解释型语言支持通过修改会话名创建并发会话。
仅支持交互式执行的语言可使用会话功能,C、ditaa 等语言不支持。即使是 Python、Haskell 这类支持交互的语言,也对可交互式运行的语法结构有限制,Org 会话中的代码块会继承这些限制。
‘dir’ 头部参数指定代码块执行时的工作目录。未设置时使用当前缓冲区所在目录。即 ‘:dir DIRECTORY’ 的效果等价于临时执行 M-x cd RET DIRECTORY。底层实现中, ‘dir’ 仅设置 Emacs 变量 default-directory 。将 ‘mkdirp’ 设为非 nil 值可在需要时自动创建目录。
将 ‘dir’ 设为符号 attach 或字符串 "'attach" ,会自动将目录 ‘dir’ 设为 (org-attach-dir) 返回路径,并开启 ‘:mkdirp yes=;使用 =:results file’ 生成的文件路径会以 ‘attachment:’ 链接形式插入,而非普通 ‘file:’ 链接;位于附件目录外的路径仍使用 ‘file:’ 链接。
例如将绘图文件保存至主目录 ‘Work/’ 文件夹(波浪号会自动展开):
#+BEGIN_SRC R :file myplot.png :dir ~/Work matplot(matrix(rnorm(100), 10), type="l") #+END_SRC
如需在远程机器执行代码块,可使用 Tramp 格式指定远程目录,示例:
#+BEGIN_SRC R :file plot.png :dir /scp:[email protected]: plot(1:10, main=system("hostname", intern=TRUE)) #+END_SRC
Org 会先正常捕获文本结果插入 Org 文件,再借助 Emacs Tramp 插入远程文件链接,路径由 ‘dir’ 与 default-directory 组合生成:
[[file:/scp:[email protected]:/home/dand/plot.png][plot.png]]
当 ‘dir’ 与 ‘session’ 同时使用时,仅对新会话设置初始目录,不会修改已存在会话的工作目录。
请勿将 ‘dir’ 与 ‘:exports results’ 或 ‘:exports both’ 共用,避免 Org 生成错误的远程文件链接,原因是 Org 不会展开 default-directory 以规避底层兼容性问题。
‘prologue’ 头部参数用于在代码块执行前追加内容,常用于执行重置指令。例如可在 Gnuplot 代码块中使用 ‘:prologue "reset"’ ,或全局配置:
(add-to-list 'org-babel-default-header-args:gnuplot
'((:prologue . "reset")))
同理, ‘epilogue’ 头部参数的值会在代码块执行末尾追加执行。