内容提要
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() 会根据第一个代码块的语言决定输出脚本的语言,并丢弃其他语言的代码块。目前不支持在同一个提取输出文件中混合多种语言。