Overview

R Markdown includes several built-in document and presentation formats however you aren’t by any means limited to those. An R Markdown format is at it’s core just an R function. When you include an output format in the YAML front-matter of a document you are really just specifying the format function to call and the parameters to pass to it. For example, consider the following:

---
title: "Habits"
output:
  mypackage::quarterly_report:
    toc: true
---

This says to use the quarterly_report function defined in mypackage as the output format and to pass toc = TRUE as a parameter to the function.

The easist way to create a new format is to write a function that calls one of the built-in formats (they are designed to be extensible enough to serve as the foundation of custom formats). Another lower-level approach is to define a format directly by explicitly specifying knitr options and pandoc command line arguments. Both of these techniques are described below.

Deriving from Built-In Formats

To create a new format based on a built-in one you simply define a new function that calls one of the existing format functions. For example:

quarterly_report <- function(toc = TRUE) {

  # get the locations of resource files located within the package
  css <- system.file("reports/styles.css", package = "mypackage")
  header <- system.file("reports/quarterly/header.html", package = "mypackage")

  # call the base html_document function
  rmarkdown::html_document(toc = toc,
                           fig_width = 6.5,
                           fig_height = 4,
                           theme = NULL,
                           css = css,
                           includes = includes(before_body = header))
}

This defines a new format with the following behavior:

  1. Provides an option to determine whether there is a table of contents included in the document (implemented by passing toc through to the base format).

  2. Sets a default height and width for figures (note this is purposely not user-customizable so as to encourage a standard for all reports of this type).

  3. Disables the default bootstrap theme and provides custom CSS in its place.

  4. Adds a standard header to every document.

Note that (3) and (4) are implemented using external files that are stored within the package that defines the custom format, so their locations need to be looked up using the system.file function.

Package Vignette Example

The Package Vignette format provides an example of a format that customizes the base html_document format with custom CSS and some other tweaks related to vignette authoring. The source code for the Package Vignette format and custom template are a good starting point for creating your own HTML based formats.

Fully Custom Formats

At it’s core an R Markdown format consists of:

  1. A set of knitr options that govern how Rmd is converted to markdown.

  2. A set of pandoc options that govern how markdown is converted to the final output format (e.g. HTML).

  3. Some optional flags and filters (typically used to control handling of supporting files).

You can create a new format using the output_format function. For example, here is the simpliest possible format defintion:

simple_html_format <- function() {
  rmarkdown::output_format(knitr = knitr_options(opts_chunk = list(dev = 'png')),
                           pandoc = pandoc_options(to = "html"),
                           clean_supporting = FALSE)
}

Of course, knitr and pandoc options can get considerabiy more complicated (see the knitr_options and pandoc_options functions for details). The clean_supporting option indicates that you aren’t creating self contained output (like a PDF or HTML document with base64 encoded resources) and therefore want to preserve supporting files like plot images generated during knitting.

You can also pass a base_format to the output_format function if you want to inherit all of the behavior of an existing format but tweak a subset of it’s options.

If there are supporting files required for your format (e.g. HTML/CSS/JS) then you’ll also need to use the other arguments to output_format to ensure they are handled correctly (e.g. copying them into place alongside the generated document).

The best way to learn about creating fully custom formats is to study the source code of the existing built-in formats (e.g. html_document and pdf_document). In some cases a custom format will define it’s own pandoc template. You can see the default pandoc templates used by the rmarkdown package by looking in the inst/rmd directory of the package.

comments powered by Disqus