在`knitr`中,我如何测试输出是PDF还是word? [英] In `knitr` how can I test for if the output will be PDF or word?

查看:95
本文介绍了在`knitr`中,我如何测试输出是PDF还是word?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据创建的格式包括特定的内容.在此特定示例中,我的表在MS word输出中看起来很糟糕,但是在HTML中却很棒.我想添加一些测试,以根据输出省略表.

I would like to include specific content based on which format is being created. In this specific example, my tables look terrible in MS word output, but great in HTML. I would like to add in some test to leave out the table depending on the output.

这是一些伪代码:

output.format <- opts_chunk$get("output")

if(output.format != "MS word"){
print(table1)
}

我确定这不是使用opts_chunk的正确方法,但这是我对knitr实际工作方式的理解的限制.对此进行测试的正确方法是什么?

I'm sure this is not the correct way to use opts_chunk, but this is the limit of my understanding of how knitr works under the hood. What would be the correct way to test for this?

推荐答案

简短回答

在大多数情况下,opts_knit$get("rmarkdown.pandoc.to")会提供所需的信息.

Short Answer

In most cases, opts_knit$get("rmarkdown.pandoc.to") delivers the required information.

否则,查询rmarkdown::all_output_formats(knitr::current_input())并检查返回值是否包含word_document:

Otherwise, query rmarkdown::all_output_formats(knitr::current_input()) and check if the return value contains word_document:

if ("word_document" %in% rmarkdown::all_output_formats(knitr::current_input()) {
  # Word output
}

长答案

我认为源文档是RMD,因为这是用于编织为不同输出格式(例如MS Word,PDF和HTML)的常用/最常见的输入格式.

Long answer

I assume that the source document is RMD because this is the usual/most common input format for knitting to different output formats such as MS Word, PDF and HTML.

在这种情况下,knitr选项不能用于确定最终输出格式,因为从knitr的角度来看这无关紧要:对于所有输出格式,knitr的工作是编织输入将RMD文件转换为MD文件. MD文件到YAML标头中指定的输出格式的转换在下一阶段由pandoc完成.

In this case, knitr options cannot be used to determine the final output format because it doesn't matter from the perspective of knitr: For all output formats, knitr's job is to knit the input RMD file to a MD file. The conversion of the MD file to the output format specified in the YAML header is done in the next stage, by pandoc.

因此,我们不能使用包装选项 knitr::opts_knit$get("out.format")了解最终输出格式,但我们需要解析YAML标头.

Therefore, we cannot use the package option knitr::opts_knit$get("out.format") to learn about the final output format but we need to parse the YAML header instead.

到目前为止,在理论上.现实有点不同. RStudio的编织PDF"/编织HTML"按钮会调用rmarkdown::render,而后者又会调用knit.在此之前, render一个(未记录?)包选项 rmarkdown.pandoc.to为实际输出格式.该值将分别为htmllatexdocx,具体取决于输出格式.

So far in theory. Reality is a little bit different. RStudio's "Knit PDF"/"Knit HTML" button calls rmarkdown::render which in turn calls knit. Before this happens, render sets a (undocumented?) package option rmarkdown.pandoc.to to the actual output format. The value will be html, latex or docx respectively, depending on the output format.

因此,如果(且仅当)使用RStudio的编织PDF"/编织HTML"按钮时,可以使用knitr::opts_knit$get("rmarkdown.pandoc.to")确定输出格式. 此答案该博客帖子.

Therefore, if (and only if) RStudio's "Knit PDF"/"Knit HTML" button is used, knitr::opts_knit$get("rmarkdown.pandoc.to") can be used to determine the output format. This is also described in this answer and that blog post.

对于直接调用knit的情况,问题仍然没有解决,因为随后未设置rmarkdown.pandoc.to.在这种情况下,我们可以利用rmarkdown包中的(未导出)函数parse_yaml_front_matter来解析YAML标头.

The problem remains unsolved for the case of calling knit directly because then rmarkdown.pandoc.to is not set. In this case we can exploit the (unexported) function parse_yaml_front_matter from the rmarkdown package to parse the YAML header.

[更新:自rmarkdown 0.9.6起,已添加功能all_output_formats(由于

[Update: As of rmarkdown 0.9.6, the function all_output_formats has been added (thanks to Bill Denney for pointing this out). It makes the custom function developed below obsolete – for production, use rmarkdown::all_output_formats! I leave the remainder of this answer as originally written for educational purposes.]

---
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"))的use(lesness),而使用parse_yaml_front_matter的行返回了YAML标头的输出"字段中指定的格式.

The example above demonstrates the use(lesness) of opts_knit$get("rmarkdown.pandoc.to") (opts_knit$get("out.format")), while the line employing parse_yaml_front_matter returns the format specified in the "output" field of the YAML header.

parse_yaml_front_matter的输入是源文件,它是字符向量,由readLines返回.要确定当前要编织的文件的名称,请使用此答案中建议的current_input().

The input of parse_yaml_front_matter is the source file as character vector, as returned by readLines. To determine the name of the file currently being knitted, current_input() as suggested in this answer is used.

在可以在简单的if语句中使用parse_yaml_front_matter来实现以输出格式为条件的行为之前,需要进行一些细微的改进:如果存在其他的YAML参数,则上面显示的语句可能会返回一个列表.输出如下例所示:

Before parse_yaml_front_matter can be used in a simple if statement to implement behavior that is conditional on the output format, a small refinement is required: The statement shown above may return a list if there are additional YAML parameters for the output like in this example:

---
output: 
  html_document: 
    keep_md: yes
---

以下帮助器功能应解决此问题:

The following helper function should resolve this issue:

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:

Note that getOutputFormat uses only the first output format specified, so with the following header only html_document is returned:

---
output:
  html_document: default
  pdf_document:
    keep_tex: yes
---

但是,这不是很严格.当使用RStudio的编织HTML"/编织PDF"按钮(及其旁边的下拉菜单以选择输出类型)时,RStudio会重新排列YAML标头,以使所选的输出格式 为列表中的第一种格式.多种输出格式(AFAIK)仅在将rmarkdown::renderoutput_format = "all"一起使用时才有意义.并且:在这两种情况下,都可以使用rmarkdown.pandoc.to,无论如何都更容易.

However, this is not very restrictive. When RStudio's "Knit HTML"/"Knit PDF" button is used (along with the dropdown menu next to it to select the output type), RStudio rearranges the YAML header such that the selected output format will be the first format in the list. Multiple output formats are (AFAIK) only relevant when using rmarkdown::render with output_format = "all". And: In both of these cases rmarkdown.pandoc.to can be used, which is easier anyways.

这篇关于在`knitr`中,我如何测试输出是PDF还是word?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆