RMarkdown:Python 代码块上的 knitr::purl()?

RMarkdown: knitr::purl() on Python code chunk?

我想将 RMarkdown 中的 Python 代码块导出到外部文件。 knitr::purl() 实现了这一点,但我只能让它在 R 代码块上工作。它不适用于 R 以外的任何其他语言吗?

例如,从下面将 python 代码导出到 my_script.py 文件中。

---
title: "Untitled"
output: html_document
---

## Header

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco laboris nisi ut aliquip

```{python}
x = 10
y = 20

z = x + y
print(z)
```

当前 purl 输出 non-R 代码已注释掉。所以我们需要重新定义输出函数来覆盖它。

这是一个简单的脚本,它 (1) 仅输出 python 代码,并且 (2) 剥离文档(我从 knitr 源代码中获取该函数并对其进行了修改):

library("knitr")

# New processing functions
process_tangle <- function (x) { 
    UseMethod("process_tangle", x)
}

process_tangle.block <- function (x) {
    params = opts_chunk$merge(x$params)

    # Suppress any code but python
    if (params$engine != 'python') {
        params$purl <- FALSE
    }
    if (isFALSE(params$purl)) 
        return("")
    label = params$label
    ev = params$eval
    code = if (!isFALSE(ev) && !is.null(params$child)) {
        cmds = lapply(sc_split(params$child), knit_child)
        one_string(unlist(cmds))
    }
    else knit_code$get(label)
    if (!isFALSE(ev) && length(code) && any(grepl("read_chunk\(.+\)", 
        code))) {
        eval(parse_only(unlist(stringr::str_extract_all(code, 
            "read_chunk\(([^)]+)\)"))))
    }
    code = knitr:::parse_chunk(code)
    if (isFALSE(ev)) 
        code = knitr:::comment_out(code, params$comment, newline = FALSE)
    # Output only the code, no documentation
    return(knitr:::one_string(code))
}

# Reassign functions
assignInNamespace("process_tangle.block",
                  process_tangle.block,
                  ns="knitr")

# Purl
purl("tmp.Rmd", output="tmp.py")

这是我的 tmp.Rmd 文件。请注意,它有一个 R 块,我不希望出现在结果中:

---
title: "Untitled"
output: html_document
---

## Header

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco laboris nisi ut aliquip

```{python}
#!/usr/bin/env python
# A python script
```

```{python} 
x = 10
y = 20

z = x + y
print(z)
```

```{r}
y=5
y
```

运行 Rscript extract.R 我得到 tmp.py:

#!/usr/bin/env python
# A python script

x = 10
y = 20

z = x + y
print(z)

PS 我在寻找同一问题的解决方案时发现了这个问题。由于没有人回答,我开发了自己的解决方案:)