在rmarkdown和knitr中打印自定义对象(PDF和HTML)

时间:2016-03-16 18:56:01

标签: r knitr r-markdown

假设我有一个包含返回S3对象的函数的包:

new_myclass <- function() {
  return(structure(list(a=1, b=2), class = "myclass"))
}

我还有两个函数接受myclass对象,并分别返回HTML表示和对象的LaTeX表示。

myclass2html <- function(obj) { return("<p>MyClass object</p>")}
myclass2latex <- function(obj) { return("\begin{em}MyClass\end{em} object $x$")}

我应该定义哪些功能/方法以提供一致且透明的knitrrmarkdown支持?我想支持.Rmd个文件和.R文件,标题如下:

#'---
#' title: My document
#' output: pdf_output
#'---

到目前为止,我的方法是通过knit_print方法:

knit_print.myclass <- function(x, ...) {
  rmarkdown_fmt <- rmarkdown::metadata$output
  knitr_fmt <- knitr::opts_knit$get("out.format")
  # should I use these heuristics with both variables?
  if (rmarkdownfmt == "pdf_document") {
    return(knitr::asis_output(myclass2latex(x)))
  }
  if (knitr_fmt %in% c("html", "markdown")) {
    return(knitr::asis_output(myclass2html(x)))
  } else {
    stop("Format not supported!")
  }
}

我的主要问题是可能有两个变量rmarkdown::metadata$outputknitr::opts_knit$get("out.format"),可能会也可能不会定义(取决于是否使用rmarkdown)。我发现这令人困惑。

  • knit_print是否为此目的自定义了正确的方法?
  • 了解输出格式的正确方法是什么?是否有get_output_format函数告诉我输出格式?

要将问题放在上下文中,我正在使用condformat包,它允许使用条件格式规则可视化DataFrame。

编辑:到目前为止,我一直在做自己的伏都教来检测输出格式:

#' @importFrom rmarkdown metadata
#' @importFrom knitr opts_knit
guess_output_format <- function() {
  rmd_output <- tryCatch({rmarkdown::metadata$output},
                         error = function(e) {NULL})
  if (is.null(rmd_output)) {
    rmd_output = ""
  }
  if (is.list(rmd_output)) {
    rmd_output <- names(rmd_output)[1]
  }
  if (rmd_output == "pdf_document") {
    return("latex")
  } else if (rmd_output %in% c("html_document", "html_vignette")) {
    return("html")
  } else if (rmd_output != "") {
    stop("Unsupported rmarkdown output format:", rmd_output)
  }
  # No rmarkdown, let's try with knitr:
  format <- knitr::opts_knit$get("out.format")
  if (format %in% c("html", "markdown")) {
    return("html")
  } else if (format %in% c("latex")) {
    return("latex")
  } else {
    stop("Format not supported!")
  }
}

编辑:在此进一步讨论:https://github.com/rstudio/rmarkdown/issues/649

1 个答案:

答案 0 :(得分:2)

使用knitr 1.18,这更简单:

guess_output_format <- function() {
  if (knitr::is_html_output()) {
    return("html")
  } else if (knitr::is_latex_output()) {
    return("latex")
  } else {
    return("unsupported")
 }
}

相关问题:https://github.com/rstudio/rmarkdown/issues/649