16.6 Results of Evaluation

Org 对代码块执行结果的处理方式取决于多个共同作用的头部参数。不过,最主要的决定因素是 ‘results’ 头部参数。它支持四类选项,每个代码块在每类中只能选用一个:

Collection

用于指定如何从代码块中收集结果;

Type

用于指定代码块返回的结果类型;影响 Org 处理结果并将其插入 Org 缓冲区的方式;

Format

用于指定结果格式;影响 Org 处理结果的方式;

Handling

用于在结果完成格式化后执行插入操作。

Collection

收集选项用于指定结果,各选项互斥,只能选择其一。

value

大多数 Babel 库的默认行为157。函数式模式。Org 会将代码包裹在源块对应语言的函数定义中以获取返回值。这也是使用 ‘:results value’ 时,代码应像函数一样执行并返回值的原因。对于 Python 等语言,使用 ‘:results value’ 时必须显式使用 return 语句。结果为代码块中最后一条语句的返回值。

在会话中执行代码块时(参见 Environment of a Code Block),Org 将代码传递给以 Emacs 交互式子进程运行的解释器,并从源代码解释器的最后一条语句输出中获取值。Org 需要使用语言特定的方法获取该值,例如 Ruby 中的变量 _ ,以及 R 中的 .Last.value

output

脚本模式。Org 将代码传递给运行解释器的外部进程,并将标准输出流的内容以文本形式返回。

在会话模式下,Org 将代码传递给以 Emacs 交互式子进程运行的解释器,拼接解释器输出的所有文本并作为结果返回。

Type

类型用于指定代码块执行后预期的结果类型,各选项互斥,只能选择其一。

默认行为为自动判断结果类型。结果类型的检测依赖于代码块所用语言,具体可参考各语言的单独文档,参见 Languages

table’, ‘vector

将结果解析为 Org 表格。若结果为单个值,则创建一行一列的表格。使用示例: ‘:results value table’ 。

有时结果会在表格行之间或表头下方包含水平线(即 “hlines”)。默认值为 ‘no’ 的 ‘hlines’ 参数会从输入表格中移除此类线条。对于大多数代码而言这是合理的,否则这些 ‘hline’ 符号会引发未绑定变量错误。设置为 ‘yes’ 则保留这些线条,如下例所示。

#+NAME: many-cols
| a | b | c |
|---+---+---|
| d | e | f |
|---+---+---|
| g | h | i |

#+NAME: no-hline
#+BEGIN_SRC python :var tab=many-cols :hlines no
return tab
#+END_SRC

#+RESULTS: no-hline
| a | b | c |
| d | e | f |
| g | h | i |

#+NAME: hlines
#+BEGIN_SRC python :var tab=many-cols :hlines yes
return tab
#+END_SRC

#+RESULTS: hlines
| a | b | c |
|---+---+---|
| d | e | f |
|---+---+---|
| g | h | i |
list

将结果解析为 Org 列表。若结果为单个值,则创建只含一个元素的列表。

scalar’, ‘verbatim

按字面解析并以引用文本形式插入,不创建表格。使用示例:=:results value verbatim= 。

file

将结果解析为文件名。将代码块的执行结果保存到该文件,然后插入指向该文件的链接。可同时控制文件名和链接附带的描述。

Org 首先尝试根据 ‘file’ 头部参数的值以及 ‘output-dir’ 头部参数指定的目录生成文件名。若未指定 ‘output-dir’ ,则默认为当前目录。

#+BEGIN_SRC asymptote :results value file :file circle.pdf :output-dir img/
  size(2cm);
  draw(unitcircle);
#+END_SRC

若缺少 ‘file’ 头部参数,Org 会根据代码块名称生成输出文件的基本名,并根据 ‘file-ext’ 头部参数指定扩展名。这种情况下,名称和扩展名均为必填项。

结果也可被解析为文件路径,参见 ‘:results link’ 。

#+name: circle
#+BEGIN_SRC asymptote :results value file :file-ext pdf
  size(2cm);
  draw(unitcircle);
#+END_SRC

file-desc’ 头部参数用于定义链接的描述(参见 Link Format)。若存在 ‘file-desc’ 但未赋值,则使用 ‘file’ 的值作为链接描述;若未指定该参数,则不显示描述。若需要指定 ‘file-desc’ 但不设置描述,可传入空向量(即 :file-desc [])。

默认情况下,Org 认为写入文件的表格为制表符分隔输出。可通过 ‘sep’ 头部参数指定其他分隔符。

file-mode’ 头部参数用于设置文件权限。若要设为可执行,可使用 ‘:file-mode (identity #o755)’ 。

#+BEGIN_SRC shell :results file :file script.sh :file-mode (identity #o755)
  echo "#!/bin/bash"
  echo "echo Hello World"
#+END_SRC

Format

格式与代码块返回的结果类型相关,各选项互斥,只能选择其一。默认值由上述指定的类型决定。

raw

按原始 Org 模式解析,直接插入缓冲区。若为表格则自动对齐。使用示例: ‘:results value raw’ 。

code

将结果包裹在代码块中,便于解析。使用示例: ‘:results value code’ 。

drawer

结果与 ‘raw’ 一样直接添加到 Org 文件中,但会被包裹在 ‘RESULTS’ 抽屉或结果宏(用于行内代码块)中,方便后续脚本与自动化处理。使用示例: ‘:results value drawer’ 。

html

将结果包裹在 ‘BEGIN_EXPORT html’ 块中。使用示例: ‘:results value html’ 。

latex

将结果包裹在 ‘BEGIN_EXPORT latex’ 块中。使用示例: ‘:results value latex’ 。

link’, ‘graphics

与 ‘file’ 类型一同使用时,结果为指向 ‘:file’ 头部参数指定文件的链接。但与普通 ‘file’ 类型不同,代码块输出不会写入磁盘,代码块仅通过副作用生成该文件,如下例所示:

#+begin_src shell :results file link :file "org-mode-unicorn.svg"
  wget -c "https://orgmode.org/resources/img/org-mode-unicorn.svg"
#+end_src

#+RESULTS:
[[file:org-mode-unicorn.svg]]

若省略 ‘:file’ 头部参数,则将源块结果解析为文件路径。

org

将结果包裹在 ‘BEGIN_SRC org’ 块中。如需逗号转义,可在块内使用 TAB 或导出文件。使用示例: ‘:results value org’ 。

pp

将结果转换为美化打印的源代码并包裹在代码块中。支持的语言:Emacs Lisp、Python、Ruby。使用示例: ‘:results value pp’ 。

wrap’ 头部参数会无条件地通过向 ‘#+BEGIN_’ 和 ‘#+END_’ 追加字符串来标记结果块(值为 ‘nil’ 或 ‘no’ 时除外)。若未指定字符串,Org 会将结果包裹在 ‘#+BEGIN_results’ … ‘#+END_results’ 块中。该参数优先级高于上述 ‘results’ 取值。例如:

#+BEGIN_SRC emacs-lisp :results html :wrap EXPORT markdown
"<blink>Welcome back to the 90's</blink>"
#+END_SRC

#+RESULTS:
#+BEGIN_EXPORT markdown
<blink>Welcome back to the 90's</blink>
#+END_EXPORT

Handling

结果收集后的处理选项,各选项互斥,只能选择其一。

replace

默认行为。将结果插入 Org 缓冲区并覆盖之前的结果。使用示例: ‘:results output replace’ 。

silent

不将结果插入 Org 缓冲区,但在迷你缓冲区中回显。使用示例: ‘:results output silent’ 。

none

计算结果但不做任何处理,既不插入 Org 缓冲区也不在迷你缓冲区回显。该结果仍可被其他代码块引用使用。使用示例: ‘:results none’ 。

discard

完全忽略结果。该选项与 ‘none’ 类似,但不对返回值执行任何处理。以编程方式调用代码块(参见 How to evaluate source code)或通过引用调用(参见 Passing argumentsNoweb Reference Syntax)时始终返回 nil

append

将结果追加到 Org 缓冲区,最新结果在底部,不覆盖原有结果。使用示例: ‘:results output append’ 。

prepend

将结果前置到 Org 缓冲区,最新结果在顶部,不覆盖原有结果。使用示例: ‘:results output prepend’ 。

Post-processing

post’ 头部参数用于对代码块执行结果进行后处理。当 ‘post’ 被赋值时,Org 会将结果绑定到 *this* 变量,方便传递给 ‘var’ 头部参数(参见 Environment of a Code Block),从而使结果可被其他代码块使用,甚至可直接执行 Emacs Lisp 代码。

下面两个示例展示了 ‘post’ 头部参数的用法。第一个示例展示如何通过 ‘post’ 添加 ‘ATTR_LATEX’ 关键字。

#+NAME: attr_wrap
#+BEGIN_SRC sh :var data="" :var width="\\textwidth" :results output
  echo "#+ATTR_LATEX: :width $width"
  echo "$data"
#+END_SRC

#+HEADER: :file /tmp/it.png
#+BEGIN_SRC dot :post attr_wrap(width="5cm", data=*this*) :results drawer
  digraph{
          a -> b;
          b -> c;
          c -> a;
  }
#+end_src

#+RESULTS:
:RESULTS:
#+ATTR_LATEX :width 5cm
[[file:/tmp/it.png]]
:END:

第二个示例展示在 ‘post’ 中使用 ‘colnames’ 头部参数在代码块间传递数据。

#+NAME: round-tbl
#+BEGIN_SRC emacs-lisp :var tbl="" fmt="%.3f"
  (mapcar (lambda (row)
            (mapcar (lambda (cell)
                      (if (numberp cell)
                          (format fmt cell)
                        cell))
                    row))
          tbl)
#+end_src

#+BEGIN_SRC R :colnames yes :post round-tbl[:colnames yes](*this*)
  set.seed(42)
  data.frame(foo=rnorm(1))
#+END_SRC

#+RESULTS:
|   foo |
|-------|
| 1.371 |

Footnotes

(157)

实际上, ‘call_<name>()’ 与 ‘src_<lang>{}’ 出现在关键字中时不会被执行,参见 Summary of In-Buffer Settings