从代码块中提取源代码是文学编程的基础任务,Org 提供了便捷的实现方式。在文学编程术语中,文档在创作时将代码与文档 编织(woven) 在一起,导出时则将代码 缠绕(tangled) 分离以供计算机执行。Org 支持编织与缠绕操作,便于创建、维护、共享与导出文学编程文档,并提供丰富的自定义选项用于提取源代码。
Org 在缠绕代码块时会对其展开、合并与转换,再根据选项配置重新组合为一个或多个独立文件。在此缠绕过程中,Org 会展开源代码中的变量,并解析所有 noweb 风格引用(参见 Noweb Reference Syntax)。
‘tangle’ 头参数用于指定是否将代码块导出到源码文件。
将代码块导出到源码文件。源码文件名由当前 Org 文件名派生,文件扩展名由代码语言标识符决定。 示例: ‘:tangle yes’ 。
默认值。不将代码提取到源码文件中。 示例: ‘:tangle no’ 。
将代码块导出到文件名由 ‘tangle’ 头参数值指定的源码文件。文件名路径相对于当前 Org 文件所在目录解析,若指定了 ‘tangle-directory’ ,则相对于该目录。
FILENAME 支持以下几种形式:
示例: ‘:tangle script.py’ 。
将代码块导出到多个文件。示例: ‘:tangle '("src/main.py" "src/utils.py")’ 。
求值后得到目标文件名。示例: ‘:tangle 'tangle-targets’ 或 ‘:tangle (get-tangle-targets)’ 。
当同时指定 ‘:tangle-directory’ 和多个 ‘:tangle’ 文件时,代码块会导出到所有目录与文件的组合路径。
Example:
#+begin_src emacs-lisp :tangle '("config.el" "backup.el") :tangle-directory '("~/.config" "/backup")
(message "Tangling to multiple targets specified by :tangle and :tangle-directory")
#+end_src
该代码块会导出到四个文件:
‘tangle-directory’ 头参数用于指定一个或多个基础目录,作为 tangle 相对路径的根目录。用法与 ‘tangle’ 类似,支持相同类型的值。
此外,位于注释子树内的代码块(见 Comment Lines)永远不会被导出。
‘mkdirp’ 头参数用于在导出文件时自动创建不存在的父目录。 ‘yes’ 表示启用创建, ‘no’ 表示禁用。
‘comments’ 头参数用于控制在导出文件中插入额外注释,这些注释独立于代码块本身已有的注释。
默认值。导出时不插入任何额外注释。
用注释包裹代码块,并添加指向 Org 文件中对应代码位置的链接。
注意 Org 会使用 org-store-link (Handling Links)生成指向代码块的链接。如果父标题重复或在导出后被修改,该链接可能不唯一。建议将 org-id-link-to-org-use-id 设为 t,确保链接指向正确标题。
为兼容旧版本保留,效果与 ‘link’ 相同。
将 Org 文件中最近的标题文本作为注释插入,具体文本取自代码块所在的上层上下文。
同时启用 ‘link’ 和 ‘org’ 两种注释。
启用 ‘link’ 功能,展开 noweb 引用(见 Noweb Reference Syntax),并在代码块内部用链接注释包裹展开内容。
‘padline’ 头参数用于控制是否在导出文件中为代码块前后添加空行。
默认值。在导出文件中每个代码块前后各插入一个空行。
不为导出的代码块添加空行。
‘shebang’ 头参数可将导出结果转为可执行脚本文件。将其设为字符串,例如 ‘:shebang "#!/bin/bash"’ ,Org 会将该字符串作为导出文件的第一行,并自动为文件添加可执行权限。
‘tangle-mode’ 头参数通过 set-file-modes 指定导出文件的权限。权限使用八进制值表示,可通过对 Elisp 八进制值调用 identity 函数传入。例如,创建只读文件可写为 ‘:tangle-mode (identity #o444)’ 。为简化写法,支持八进制简写 ‘oXXX’ (o 代表 octal),因此只读示例可简写为 ‘:tangle-mode o444’ 。省略 ‘o’ 前缀会将数值当作整数解析,可能导致意外结果( ‘444’ 等价于 ‘o674’ )。
另外还支持两种简写格式:类似 ls 的权限字符串 ‘rw-r--r--’ ,以及类似 chmod 的权限写法 ‘g+w’ 。
注意 chmod 风格权限基于 org-babel-tangle-default-file-mode ,其默认值为 ‘#o644’ 。
当同时指定 ‘:tangle-mode’ 和 ‘:shebang’ 时, ‘:tangle-mode’ 指定的权限会覆盖 ‘:shebang’ 带来的权限。若多个代码块导出到同一文件且 ‘:tangle-mode’ 冲突,Org 的行为未定义。
默认情况下 Org 在导出时会展开代码块。 ‘no-expand’ 头参数可关闭该展开行为。注意 org-babel-expand-src-block 的展开副作用之一是会为变量赋值(见 Environment of a Code Block),展开也会替换 noweb 引用为目标内容(见 Noweb Reference Syntax)。部分展开可能导致提前赋值,因此提供该选项。该选项仅对导出生效,对导出无影响,因为执行用的代码块必须展开。
org-babel-tangle ¶导出当前文件。快捷键绑定为 C-c C-v t。
带前缀参数时仅导出当前代码块。
org-babel-tangle-file ¶选择一个文件进行导出。快捷键绑定为 C-c C-v f。
org-babel-pre-tangle-hook ¶该钩子在导出流程开始前运行,当前缓冲区即为待导出的缓冲区。
org-babel-tangle-body-hook ¶该钩子在临时缓冲区中运行,缓冲区内容为每个已展开的代码块。钩子可按需修改展开后的代码,修改后的内容将作为最终代码使用。
org-babel-post-tangle-hook ¶该钩子在由 org-babel-tangle 导出的代码文件内部运行,适用于对导出文件进行后处理、编译或执行。
org-babel-tangle-finished-hook ¶该钩子在 post-tangle 钩子之后运行,环境为原始 Org 缓冲区。
调试器通常会将错误信息关联到源码文件。但对导出文件,我们希望关联到 Org 文件而非导出后的源码文件。为实现这一跳转,Org 使用 org-babel-tangle-jump-to-org 函数,并依赖两个额外代码块头参数: