简答
在大多数情况下,opts_knit$get("rmarkdown.pandoc.to") 会提供所需的信息。
否则,查询rmarkdown::all_output_formats(knitr::current_input()),检查返回值是否包含word_document:
if ("word_document" %in% rmarkdown::all_output_formats(knitr::current_input()) {
# Word output
}
长答案
我假设源文档是 RMD,因为这是编织成不同输出格式(如 MS Word、PDF 和 HTML)的常用/最常见的输入格式。
在这种情况下,knitr 选项不能用于确定最终的输出格式,因为从knitr 的角度来看这并不重要:对于所有输出格式,knitr 的工作是编织输入RMD 文件转换为 MD 文件。 MD 文件到 YAML 标头中指定的输出格式的转换在下一阶段由pandoc 完成。
因此,我们不能使用 package option knitr::opts_knit$get("out.format") 来了解最终输出格式,而是需要解析 YAML 标头。
目前为止在理论上。现实有点不同。 RStudio 的“Knit PDF”/“Knit HTML”按钮调用rmarkdown::render,后者又调用knit。在这发生之前,render sets a (undocumented?) package option rmarkdown.pandoc.to 为实际输出格式。该值将分别为html、latex 或docx,具体取决于输出格式。
因此,如果(且仅当)使用 RStudio 的“Knit PDF”/“Knit HTML”按钮,knitr::opts_knit$get("rmarkdown.pandoc.to") 可用于确定输出格式。这也在this answer 和that blog post 中有所描述。
对于直接调用knit 的情况,问题仍未解决,因为没有设置rmarkdown.pandoc.to。在这种情况下,我们可以利用 rmarkdown 包中的(未导出的)函数 parse_yaml_front_matter 来解析 YAML 标头。
[更新:从rmarkdown 0.9.6 开始,已添加函数all_output_formats(感谢Bill Denney 指出这一点)。它使下面开发的自定义函数过时了——对于生产,使用rmarkdown::all_output_formats!我将这个答案的其余部分保留为最初为教育目的而编写的。]
---
output: html_document
---
```{r}
knitr::opts_knit$get("out.format") # Not informative.
knitr::opts_knit$get("rmarkdown.pandoc.to") # Works only if knit() is called via render(), i.e. when using the button in RStudio.
rmarkdown:::parse_yaml_front_matter(
readLines(knitr::current_input())
)$output
```
上面的例子演示了opts_knit$get("rmarkdown.pandoc.to") (opts_knit$get("out.format")) 的使用(少),而使用parse_yaml_front_matter 的行返回YAML 标头的“输出”字段中指定的格式。
parse_yaml_front_matter 的输入是作为字符向量的源文件,由readLines 返回。要确定当前正在编织的文件的名称,请使用this answer 中建议的current_input()。
在parse_yaml_front_matter 可以在简单的if 语句中使用以实现以输出格式为条件的行为之前,需要进行一些小改进:如果有额外的 YAML 参数,上面显示的语句可能会返回一个列表像这个例子中的输出:
---
output:
html_document:
keep_md: yes
---
下面的辅助函数应该可以解决这个问题:
getOutputFormat <- function() {
output <- rmarkdown:::parse_yaml_front_matter(
readLines(knitr::current_input())
)$output
if (is.list(output)){
return(names(output)[1])
} else {
return(output[1])
}
}
可以用在诸如
之类的结构中
if(getOutputFormat() == 'html_document') {
# do something
}
请注意,getOutputFormat 仅使用指定的第一个输出格式,因此使用以下标头仅返回 html_document:
---
output:
html_document: default
pdf_document:
keep_tex: yes
---
但是,这不是很严格。当使用 RStudio 的“Knit HTML”/“Knit PDF”按钮(以及旁边的下拉菜单以选择输出类型)时,RStudio 会重新排列 YAML 标头,以便选择的输出格式 为列表中的第一种格式。多种输出格式(AFAIK)仅在使用 rmarkdown::render 和 output_format = "all" 时相关。并且:在这两种情况下,rmarkdown.pandoc.to 都可以使用,无论如何这更容易。