我想根据正在创建的格式包含特定内容。在这个具体的例子中,我的表在MS word
输出中看起来很糟糕,但在HTML
中表现很好。我想添加一些测试,根据输出省略表。
这是一些伪代码:
output.format <- opts_chunk$get("output")
if(output.format != "MS word"){
print(table1)
}
我确定这不是使用opts_chunk
的正确方法,但这是我对knitr
如何在幕后工作的理解的限制。测试这个的正确方法是什么?
答案 0 :(得分:40)
在大多数情况下,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
是job是将输入RMD文件编织到MD文件。 MD文件到YAML标头中指定的输出格式的转换将在下一阶段由pandoc
完成。
因此,我们无法使用package option knitr::opts_knit$get("out.format")
来了解最终输出格式,但我们需要解析YAML标头。
理论上到目前为止。现实有点不同。 RStudio的“Knit PDF”/“Knit HTML”按钮调用rmarkdown::render
,然后调用knit
。在此之前,render
sets (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
。在这种情况下,我们可以利用parse_yaml_front_matter
包中的(未导出的)函数rmarkdown
来解析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")
)的使用(lesness),而使用parse_yaml_front_matter
的行返回了YAML标头的“output”字段中指定的格式。
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
,这样更容易。
答案 1 :(得分:9)
自knitr
1.18起,您可以使用这两个函数
knitr::is_html_output()
和
knitr::is_latex_output()
答案 2 :(得分:3)
我想在这里添加一些说明,因为我经常将相同的Rmarkdown文件(* .Rmd)渲染成多种格式(* .html,* .pdf,* .docx),所以不想知道是否感兴趣的格式列在前面的yaml(即"word_document" %in% rmarkdown::all_output_formats(knitr::current_input()
)中指定的格式中,我想知道当前呈现的格式。要做到这一点,你可以:
获取前面列出的格式的第一个元素:rmarkdown::all_output_formats(knitr::current_input()[1]
;或
获取默认输出格式名称:rmarkdown::default_output_format(knitr::current_input())$name
例如......
---
title: "check format"
output:
html_document: default
pdf_document: default
word_document: default
---
```{r}
rmarkdown::all_output_formats(knitr::current_input())[1]
```
```{r}
rmarkdown::default_output_format(knitr::current_input())$name
```
```{r}
fmt <- rmarkdown::default_output_format(knitr::current_input())$name
if (fmt == "pdf_document"){
#...
}
if (fmt == "word_document"){
#...
}
```
答案 3 :(得分:2)
还有一点:上述答案不适用于html_notebook
,因为代码直接在那里执行且knitr::current_input()
没有响应。如果您知道文档名称,则可以如上所述调用all_output_formats
,明确指定名称。我不知道是否有另一种方法可以做到这一点。
答案 4 :(得分:1)
这是我用的
library(stringr)
first_output_format <-
names(rmarkdown::metadata[["output"]])[1]
if (!is.null(first_output_format)) {
my_output <- str_split(first_output_format,"_")[[1]][1]
} else {
my_output = "unknown"
}