Argument keep_md not inherited by custom output format that extends html_document() · Issue #1558 · rstudio/rmarkdown (original) (raw)
By filing an issue to this repo, I promise that
- I have fully read the issue guide at https://yihui.name/issue/.
- I have provided the necessary information about my issue.
- If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
- If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included
xfun::session_info('rmarkdown')
. I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version:remotes::install_github('rstudio/rmarkdown')
. - If I have posted the same issue elsewhere, I have also mentioned it in this issue.
- I have learned the Github Markdown syntax, and formatted my issue correctly.
Note: Sorry for the strange line wrapping below. I used the output formatgithub_document()
, but apparently GitHub markdown now respects line breaks. I manually fixed a few of the more egregious breaks below.
I have created a custom output format that extends html_document()
. I
noticed that the argument keep_md
is not properly inherited.
My first thought was that both the arguments keep_md
and df_print
might have issues since they are arguments for both output_format()
and html_document()
, but somehow df_print
is properly inherited.
intersect(names(formals(rmarkdown::output_format)), names(formals(rmarkdown::html_document)))
## [1] "keep_md" "df_print"
Here is a minimal example to demonstrate the issue. The function below
is a trivial output format that wraps html_document()
, but doesn’t
change anything.
A trivial wrapper for html_document()
html_wrap <- function(...) { rmarkdown::output_format(knitr = rmarkdown::knitr_options(), pandoc = rmarkdown::pandoc_options(to = "html"), base_format = rmarkdown::html_document(...)) }
If a user runs render()
on an R Markdown file with the following YAML
header:
---
output: html_wrap
---
then this would result in the following call tocreate_output_format()
:
o1 <- rmarkdown:::create_output_format(name = "html_wrap", options = list())
This inherits the default values from html_document()
as expected:
environment(environment(o1[["pre_knit"]])[["overlay"]])[["toc"]]
environment(environment(o1[["pre_knit"]])[["overlay"]])[["keep_md"]]
environment(environment(o1[["pre_knit"]])[["overlay"]])[["df_print"]]
However, if a user runs render()
on an R Markdown file with the
following YAML header:
---
output:
html_wrap:
toc: true
keep_md: TRUE
df_print: "kable"
---
then this would result in the following call to create_output_format()
(line 378):
o2 <- rmarkdown:::create_output_format(name = "html_wrap", options = list(toc = TRUE, keep_md = TRUE, df_print = "kable"))
toc
is inherited as expected:
environment(environment(o2[["pre_knit"]])[["overlay"]])[["toc"]]
df_print
is inherited not only in the environment of the pre_knit()
function, but the value of the output format is also inherited:
environment(environment(o2[["pre_knit"]])[["overlay"]])[["df_print"]]
Unfortunately, keep_md
is only updated in the environment of thepre_knit()
function, where it has no effect.
environment(environment(o2[["pre_knit"]])[["overlay"]])[["keep_md"]]
When render()
adds rmarkdown.keep_md
to knitr::opts_knit
, it usesoutput_format$keep_md
(line 500).
When render()
decides to keep the md file, it again usesoutput_format$keep_md
(line 869).
Potentially related Issues include #842 and #928.
Note that bookdown::html_document2() does not have this issue.
rmarkdown:::create_output_format(name = "bookdown::html_document2", options = list(keep_md = TRUE))$keep_md
But it is unclear to me what part of its code would change the
inheritance of keep_md
.
## function (..., number_sections = TRUE, pandoc_args = NULL, base_format = rmarkdown::html_document)
## {
## base_format = get_base_format(base_format)
## config = base_format(..., number_sections = number_sections,
## pandoc_args = pandoc_args2(pandoc_args))
## post = config$post_processor
## config$post_processor = function(metadata, input, output,
## clean, verbose) {
## if (is.function(post))
## output = post(metadata, input, output, clean, verbose)
## x = read_utf8(output)
## x = restore_appendix_html(x, remove = FALSE)
## x = restore_part_html(x, remove = FALSE)
## x = resolve_refs_html(x, global = !number_sections)
## x = clean_pandoc2_highlight_tags(x)
## write_utf8(x, output)
## output
## }
## config$bookdown_output_format = "html"
## config = set_opts_knit(config)
## config
## }
## <bytecode: 0x558e41c8af40>
## <environment: namespace:bookdown>
It appears to be directly editing the base output format instead of
inheriting from it using output_format(base_format = )
, which is what
the documentation recommends.
What is the recommended method for passing all arguments provided to a
custom output format to the base output format that it extends?
I realize that I could hard-code a work-around for the custom output
format to handle keep_md
, but this is fragile. If a future release of
rmarkdown added a new argument to output_format()
/html_document()
, I
would have to update my code and also put a restriction on the minimum
version of rmarkdown that is compatible.
html_wrap2 <- function(...) {
opts <- list(...)
if (!is.null(opts$keep_md)) keep_md <- opts$keep_md else keep_md <- FALSE
rmarkdown::output_format(knitr = rmarkdown::knitr_options(), pandoc = rmarkdown::pandoc_options(to = "html"), keep_md = keep_md, base_format = rmarkdown::html_document(...)) } rmarkdown:::create_output_format(name = "html_wrap2", options = list(keep_md = TRUE))$keep_md