#' Output filters for code blocks in markdown
#'
#' @param code character vector containing the code of the code block
#' @param language the language in which the code is written (as specified in
#' the markdown file).
#' @param id the identifier of the code block.
#' @param ... additional arguments specified as arguments in the code block are
#' passed on to the filter function. Often these are ignored, or they are
#' passed on to other functions (see 'Details').
#' @param echo the code in \code{code} is repeated in the output.
#' @param results include the results of running the code in the output. The
#' output of code that explicitly writes to standard output is always
#' included.
#' @param drop_empty do not include any output if the resulting code block
#' would be empty.
#' @param eval if FALSE do not run the code and just include the code in the
#' output.
#' @param cmd the command to use in the \code{\link{system2}} call. Only needed
#' when different than the language.
#' @param comment_char string prepended to output of commands run by
#' \code{output_shell}.
#' @param formatter function that will format the R-code and resulting output
#' (if requested). See \code{\link{format_traditional}} for possible options.
#' @param capture_warnings include warnings in the output.
#' @param capture_messages include messages in the output.
#' @param muffle_warnings do not show warnings in the console.
#' @param muffle_messages do not show messages in the console.
#'
#' @details
#' The filter functions \code{output_table} and \code{output_figure} call
#' \code{\link{md_table}} and \code{\link{md_figure}} respectively; additional
#' arguments are passed on to those functions. Other filter functions ignore the
#' additional arguments.
#'
#' It is also possible to write custom output filter. An output filter should have
#' \code{code}, \code{language} and \code{id} as its first three arguments. It
#' should either return a character vector containing the markdown that should be
#' included in the resulting markdown file or an object that can be directly
#' included in the pandoc parse tree. If the function does not return a character
#' vector it is assumed the latter is returned. \code{simplermarkdown} defines a
#' small number of valid object constructors: \code{\link{raw_block}} and
#' \code{\link{markdown_block}}.
#'
#' The custom function should be available when running the markdown document
#' through pandoc. The easiest way is to \code{\link{source}} or define the
#' function in the markdown document before using it.
#'
#' The filter function \code{output_shell} can be used to process chunks of code
#' from other languages than R. These chunks of code are written to a temporary
#' file which is then ran using the \code{cmd} using a call to
#' \code{\link{system2}}. The output of that is captured and when \code{results
#' = TRUE} included in the output. The output lines are prepended by
#' \code{comment_char}. When \code{echo = TRUE} the code is also included before
#' the output.
#'
#' @return
#' The functions either return a character vector with markdown,
#' or return a list with the correct structure to include in the pandoc parse
#' tree.
#'
#' @rdname output_fun
#' @export
#'
output_table <- function(code, language = "R", id = "", ...) {
tab <- source(exprs = str2expression(code), echo = FALSE, keep.source = TRUE)
md_table(tab$value, as_character = TRUE, ...)
}
#' @rdname output_fun
#' @export
#'
output_figure <- function(code, language = "R", id = "", ...) {
md_figure(code, as_character = TRUE, id = id, ...)
}
#' @rdname output_fun
#' @export
#'
output_eval <- function(code, language = "R", id = "", echo = TRUE,
results = TRUE, drop_empty = TRUE, eval = TRUE,
formatter = getOption("md_formatter", default = format_traditional),
capture_warnings = FALSE, capture_messages = results,
muffle_warnings = FALSE, muffle_messages = TRUE,
...) {
if (eval == FALSE) return(markdown_block(code, language, id, ...))
res <- run_and_capture(code, results = results, echo = echo,
capture_warnings = capture_warnings, capture_messages = capture_messages,
muffle_warnings = muffle_warnings, muffle_messages = muffle_messages)
res <- formatter(res)
res <- paste0(res, collapse="\n")
if (drop_empty) {
# Check if we have only empty lines or no lines at all; in that case
# return empty markdown
empty_output <- (length(res) == 0) || all((grepl("^[[:blank:]]*$", res)))
if (empty_output) return(raw_block(""))
}
markdown_block(res, language, id, ...)
}
#' @rdname output_fun
#' @export
#'
output_raw <- function(code, language = "R", id = "", ...) {
res <- utils::capture.output(
source(exprs = str2expression(code), echo = FALSE, keep.source = TRUE)
)
res <- paste0(res, collapse="\n")
raw_block(res)
}
#' @rdname output_fun
#' @export
#'
output_str <- function(code, language = "R", id = "", ...) {
res <- source(exprs = str2expression(code), echo = FALSE, keep.source = TRUE)
res <- paste0(as.character(res$value), collapse="\n")
str_block(res)
}
#' @rdname output_fun
#' @export
#'
output_shell <- function(code, language, id = "", cmd = language,
echo = TRUE, results = TRUE, comment_char = "# ", ...) {
fn <- tempfile()
writeLines(code, fn)
on.exit(file.remove(fn))
res <- system2(cmd, fn, stdout = TRUE, stderr = TRUE)
input <- if (echo) paste0(code, collapse = "\n") else NULL
output <- if (results) paste0("# ", res, collapse = "\n") else NULL
markdown_block(paste0(c(input, output), collapse = "\n\n"), language, ...)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.