R/preprocessor.R

Defines functions make_preknitter

Documented in make_preknitter

#' Generate a function to run prior to knitting
#'
#' @description **redoc** modifies R Markdown documents prior to knitting to
#' capture and store document elements that will need to be restored later.  It
#' does this via a function passed to the `pre_knit` argument of
#' [rmarkdown::output_format()].  `make_preknitter` generates this function from
#' a list of [wrapper functions][make_wrapper()].
#'
#' @param wrappers a list of [wrapper functions][make_wrapper()].
#'
#' @details **rmarkdown** does not provide a mechanism to modify the file prior
#' to knitting, so **redoc** accomplishes this by reaching up the call stack and
#' modifying the environment in the [rmarkdown::render()] function.  The
#' function generated by `make_preknitter` will do this by generating the
#' pre-processed R Markdown file and associated list of code chunks, adding these
#' the list of intermediates for cleanup, and switching the document input to
#' this pre-processed document.
#'
#' @return A function to be used in `output_format(pre_knit = ...)``
#' @importFrom yaml write_yaml
#' @export
#' @examples
#'
#' make_preknitter(wrappers = list(htmlcommentwrap, latexwrap))
make_preknitter <- function(wrappers = list()) {
  pre_knit <- function(input, ...) {
    render_env <- get_parent_env_with("knit_input")
    pre_knit_input <- get("knit_input", envir = render_env)
    intermediates_loc <- get("intermediates_loc", envir = render_env)

    rmd_text <- normalize_newlines(readfile(input))
    rmd <- wrap_code(rmd_text, wrappers = wrappers)

    codefile <- intermediates_loc(
      file_with_meta_ext(basename(input), "codelist", "yml")
    )

    preprocessed_rmd_file <- intermediates_loc(
      file_with_meta_ext(pre_knit_input, "preprocessed")
    )
    write_yaml(rmd$code, codefile)
    cat(rmd$text, file = preprocessed_rmd_file)
    assign("knit_input", preprocessed_rmd_file, envir = render_env)
    add_intermediates(c(codefile, preprocessed_rmd_file))
  }
  return(pre_knit)
}
noamross/redoc documentation built on Aug. 7, 2022, 7:22 a.m.