1#' Convert to a markdown document
2#'
3#' Format for converting from R Markdown to another variant of markdown (e.g.
4#' strict markdown or github flavored markdown)
5#'
6#' See the \href{https://bookdown.org/yihui/rmarkdown/markdown-document.html}{online
7#' documentation} for additional details on using the \code{md_document} format.
8#'
9#' R Markdown documents can have optional metadata that is used to generate a
10#' document header that includes the title, author, and date. For more details
11#' see the documentation on R Markdown \link[=rmd_metadata]{metadata}.
12#' @inheritParams html_document
13#' @param variant Markdown variant to produce (defaults to "markdown_strict").
14#'   Other valid values are "commonmark", "gfm", "commonmark_x", "markdown_mmd",
15#'   markdown_phpextra", "markdown_github", or even "markdown" (which produces
16#'   pandoc markdown). You can also compose custom markdown variants, see the
17#'   \href{https://pandoc.org/MANUAL.html}{pandoc online documentation} for
18#'   details.
19#' @param preserve_yaml Preserve YAML front matter in final document.
20#' @param fig_retina Scaling to perform for retina displays. Defaults to
21#'   \code{NULL} which performs no scaling. A setting of 2 will work for all
22#'   widely used retina displays, but will also result in the output of
23#'   \code{<img>} tags rather than markdown images due to the need to set the
24#'   width of the image explicitly.
25#' @param ext Extention of the output document (defaults to ".md").
26#' @return R Markdown output format to pass to \code{\link{render}}
27#' @examples
28#' \dontrun{
29#' library(rmarkdown)
30#'
31#' render("input.Rmd", md_document())
32#'
33#' render("input.Rmd", md_document(variant = "markdown_github"))
34#' }
35#' @export
36md_document <- function(variant = "markdown_strict",
37                        preserve_yaml = FALSE,
38                        toc = FALSE,
39                        toc_depth = 3,
40                        number_sections = FALSE,
41                        fig_width = 7,
42                        fig_height = 5,
43                        fig_retina = NULL,
44                        dev = 'png',
45                        df_print = "default",
46                        includes = NULL,
47                        md_extensions = NULL,
48                        pandoc_args = NULL,
49                        ext = ".md") {
50
51
52  # base pandoc options for all markdown output
53  args <- c(if (preserve_yaml) "--standalone")
54
55  # table of contents
56  args <- c(args, pandoc_toc_args(toc, toc_depth))
57
58  # content includes
59  args <- c(args, includes_to_pandoc_args(includes))
60
61  # pandoc args
62  args <- c(args, pandoc_args)
63
64  # variants
65  variant <- adapt_md_variant(variant, preserve_yaml)
66
67  # add post_processor for yaml preservation if not supported by pandoc
68  post_processor <- if (preserve_yaml && !grepl('yaml_metadata_block', variant, fixed = TRUE)) {
69    function(metadata, input_file, output_file, clean, verbose) {
70      input_lines <- read_utf8(input_file)
71      partitioned <- partition_yaml_front_matter(input_lines)
72      if (!is.null(partitioned$front_matter)) {
73        output_lines <- c(partitioned$front_matter, "", read_utf8(output_file))
74        write_utf8(output_lines, output_file)
75      }
76      output_file
77    }
78  }
79
80  # return format
81  output_format(
82    knitr = knitr_options_html(fig_width, fig_height, fig_retina, FALSE, dev),
83    pandoc = pandoc_options(
84      to = variant,
85      from = from_rmarkdown(extensions = md_extensions),
86      args = args,
87      ext = ext,
88      lua_filters = if (number_sections) pkg_file_lua("number-sections.lua")
89    ),
90    clean_supporting = FALSE,
91    df_print = df_print,
92    post_processor = post_processor
93  )
94}
95
96adapt_md_variant <- function(variant, preserve_yaml) {
97  variant_base <- gsub("^([^+-]*).*", "\\1", variant)
98  variant_extensions <- gsub(sprintf("^%s", variant_base), "", variant)
99
100  set_extension <- function(format, ext, add = TRUE) {
101    ext <- paste0(ifelse(add, "+", "-"), ext)
102    if (grepl(ext, format, fixed = TRUE)) return(format)
103    paste0(format, ext, collapse = "")
104  }
105
106  add_yaml_block_ext <- function(extensions, preserve_yaml) {
107    set_extension(variant_extensions, "yaml_metadata_block", preserve_yaml)
108  }
109
110  # yaml_metadata_block extension
111  variant_extensions <- switch(
112    variant_base,
113    gfm =,
114    commonmark =,
115    commonmark_x = {
116      if (pandoc_available(2.13)) {
117        add_yaml_block_ext(variant_extensions, preserve_yaml)
118      } else {
119        variant_extensions
120      }
121    },
122    markdown =,
123    markdown_phpextra =,
124    markdown_github =,
125    markdown_mmd =,
126    markdown_strict = add_yaml_block_ext(variant_extensions, preserve_yaml),
127    # do not modified for unknown (yet) md variant
128    variant_extensions
129  )
130
131  paste0(variant_base, variant_extensions, collapse = "")
132}
133