knitr 中的代码提取变得更智能

knitr 中的代码提取变得更智能

💡 原文英文,约900词,阅读约需3分钟。
📝

内容提要

knitr 的 purl() 功能获得多项改进:支持 Python 等非 R 语言,输出对应脚本并以 #%% 标记代码单元;read_chunk() 可从 .Rmd 等源文档按标签借用代码块;opts_hooks 钩子在 tangle 时生效,可动态筛选代码块;comment 选项可控制 eval=FALSE 代码是否注释。

🔎

延伸解读

多语言支持的实际影响

purl() 现在能根据文档首个代码块的语言,将整个文档提取为对应语言的脚本,例如 Python 文档生成 .py 文件。代码块头部会转换为 #%% 标记,方便 VS Code 和 Jupyter 识别。但需注意,同一输出文件仍不能混合多种语言,其他语言的代码块会被丢弃。若需不同扩展名,可使用 output 参数指定。

跨文档借用代码块

read_chunk() 不再局限于纯 R 脚本,现在可以直接从 .Rmd、.Rnw 等 knitr 源文档中按标签提取代码块。标签可来自块头(如 {r fit-model})或 #| label: 选项。这一改进适合教学材料和论文,能展示大型分析中的精选子集,避免复制粘贴导致代码不同步。

动态筛选与注释控制

opts_hooks 钩子现在在 tangle 时也会运行,允许根据任意块选项动态决定哪些代码块进入提取脚本。例如,通过 label 钩子可只提取以 -solution 结尾的块。此外,comment 选项可控制 eval=FALSE 的代码是否被注释:设为空字符串或 NA 可保持代码可运行,反之也可为已求值的块添加注释前缀。

Q&A

knitr 的 purl() 现在支持哪些非 R 语言?

purl() 现在支持 Python、Julia、SQL 等十几种引擎。如果文档的第一个代码块使用非 R 语言,purl() 会将整个文档提取为对应语言的脚本,例如 Python 文档会生成 .py 文件。

purl() 提取非 R 语言代码时,输出文件中的代码单元是如何标记的?

代码块头部会转换为 #%% 单元格标记,这是 VS Code 和 Jupyter 认可的代码单元约定。

read_chunk() 现在可以从哪些类型的文件中借用代码块?

read_chunk() 现在可以从任何 knitr 源文档(如 .Rmd、.Rnw 等)中借用带标签的代码块,而不再局限于纯 R 脚本。

如何使用 opts_hooks 在 tangle 时动态筛选要提取的代码块?

通过 opts_hooks$set() 注册钩子,钩子函数可以基于任意代码块选项决定是否提取。例如,设置 label 钩子,用 grepl("-solution$", options$label) 将 purl 选项设为 TRUE,从而只提取标签以 -solution 结尾的代码块。

purl() 如何处理 eval=FALSE 的代码块?如何控制其是否被注释?

默认情况下,purl() 会将 eval=FALSE 的代码块注释掉。但可以通过 comment 选项控制:设置 comment = '' 或 NA 可保持代码不被注释,使其在脚本中仍可运行;反之,对已求值的代码块设置注释前缀,其代码会被注释掉。

purl() 提取代码时,如果文档中包含多种语言的代码块,会如何处理?

purl() 会根据第一个代码块的语言决定输出脚本的语言,并丢弃其他语言的代码块。目前不支持在同一个提取输出文件中混合多种语言。

🏷️

标签

➡️

继续阅读