在 rmarkdown 和 knitr 中打印自定义 object(PDF 和 HTML)
Print custom object in rmarkdown and knitr (PDF and HTML)
假设我有一个功能包 returnS3 object:
new_myclass <- function() {
return(structure(list(a=1, b=2), class = "myclass"))
}
我还有两个函数,分别采用 myclass
object 和 return 的 HTML 表示和 object 的 LaTeX 表示。
myclass2html <- function(obj) { return("<p>MyClass object</p>")}
myclass2latex <- function(obj) { return("\begin{em}MyClass\end{em} object $x$")}
我应该定义什么 functions/methods 来提供一致和透明的 knitr
和 rmarkdown
支持?我想同时支持 .Rmd
文件和带有 header 的 .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$output
和 knitr::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!")
}
}
使用 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")
}
}
假设我有一个功能包 returnS3 object:
new_myclass <- function() {
return(structure(list(a=1, b=2), class = "myclass"))
}
我还有两个函数,分别采用 myclass
object 和 return 的 HTML 表示和 object 的 LaTeX 表示。
myclass2html <- function(obj) { return("<p>MyClass object</p>")}
myclass2latex <- function(obj) { return("\begin{em}MyClass\end{em} object $x$")}
我应该定义什么 functions/methods 来提供一致和透明的 knitr
和 rmarkdown
支持?我想同时支持 .Rmd
文件和带有 header 的 .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$output
和 knitr::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!")
}
}
使用 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")
}
}