1#' Convert to GitHub Flavored Markdown
2#'
3#' Format for converting from R Markdown to GitHub Flavored Markdown.
4#'
5#' See the \href{https://rmarkdown.rstudio.com/github_document_format.html}{online
6#' documentation} for additional details on using the \code{github_document}
7#' format.
8#' @inheritParams output_format
9#' @inheritParams html_document
10#' @inheritParams md_document
11#' @param hard_line_breaks \code{TRUE} to generate markdown that uses a simple
12#'   newline to represent a line break (as opposed to two-spaces and a newline).
13#' @param html_preview \code{TRUE} to also generate an HTML file for the purpose of
14#'   locally previewing what the document will look like on GitHub.
15#' @param keep_html \code{TRUE} to keep the preview HTML file in the working
16#'   directory. Default is \code{FALSE}.
17#' @return R Markdown output format to pass to \code{\link{render}}
18#' @export
19github_document <- function(toc = FALSE,
20                            toc_depth = 3,
21                            number_sections = FALSE,
22                            fig_width = 7,
23                            fig_height = 5,
24                            dev = 'png',
25                            df_print = "default",
26                            includes = NULL,
27                            md_extensions = NULL,
28                            hard_line_breaks = TRUE,
29                            pandoc_args = NULL,
30                            html_preview = TRUE,
31                            keep_html = FALSE) {
32
33  # add special markdown rendering template to ensure we include the title fields
34  # and add an optional feature to number sections
35  pandoc_args <- c(
36    pandoc_args, "--template",
37    pkg_file_arg("rmarkdown/templates/github_document/resources/default.md")
38  )
39
40  pandoc2 <- pandoc2.0()
41  # use md_document as base
42  if (pandoc2) {
43    variant <-  "gfm"
44  } else {
45    variant <- "markdown_github"
46  }
47  if (!hard_line_breaks) variant <- paste0(variant, "-hard_line_breaks")
48
49  # atx headers are the default in pandoc 2.11.2 and the flag has been deprecated
50  # to be replace by `--markdown-headings=atx|setx`
51  if (!pandoc_available("2.11.2")) pandoc_args <- c(
52    "--atx-headers", pandoc_args
53  )
54
55  if (toc && !isTRUE(grepl("gfm_auto_identifiers", md_extensions))) {
56    md_extensions <- c(md_extensions, "+gfm_auto_identifiers")
57  }
58
59  format <- md_document(
60    variant = variant, toc = toc, toc_depth = toc_depth,
61    number_sections = number_sections, fig_width = fig_width,
62    fig_height = fig_height, dev = dev, df_print = df_print,
63    includes = includes, md_extensions = md_extensions,
64    pandoc_args = pandoc_args
65  )
66
67  # add a post processor for generating a preview if requested
68  if (html_preview) {
69    format$post_processor <- function(metadata, input_file, output_file, clean, verbose) {
70
71      css <- pkg_file_arg(
72        "rmarkdown/templates/github_document/resources/github.css")
73      # provide a preview that looks like github
74      args <- c(
75        "--standalone", "--self-contained", "--highlight-style", "pygments",
76        "--template", pkg_file_arg(
77          "rmarkdown/templates/github_document/resources/preview.html"),
78        "--variable", paste0("github-markdown-css:", css),
79        if (pandoc2) c("--metadata", "pagetitle=PREVIEW")  # HTML5 requirement
80      )
81
82      # run pandoc
83      preview_file <- file_with_ext(output_file, "html")
84      pandoc_convert(
85        input = output_file, to = "html", from = variant, output = preview_file,
86        options = args, verbose = verbose
87      )
88
89      # move the preview to the preview_dir if specified
90      if (!keep_html) {
91        preview_dir <- Sys.getenv("RMARKDOWN_PREVIEW_DIR", unset = NA)
92        if (!is.na(preview_dir)) {
93          relocated_preview_file <- tempfile("preview-", preview_dir, ".html")
94          file.copy(preview_file, relocated_preview_file)
95          file.remove(preview_file)
96          preview_file <- relocated_preview_file
97        }
98      }
99
100      if (verbose) message("\nPreview created: ", preview_file)
101
102      output_file
103    }
104  }
105
106  format  # return format
107}
108
109# explicit definition of gfm_format -- not currently used b/c it didn't
110# yield different about that 'gfm' w/ pandoc 2.11. keeping in the source
111# code for now in case we need to use it for another workaround.
112gfm_format <- function() {
113  paste0("markdown_strict",
114   # commonmark
115   "+raw_html",
116   "+all_symbols_escapable",
117   "+backtick_code_blocks",
118   "+fenced_code_blocks",
119   "+space_in_atx_header",
120   "+intraword_underscores",
121   "+lists_without_preceding_blankline",
122   "+shortcut_reference_links",
123   # gfm extensions
124   "+auto_identifiers",
125   "+autolink_bare_uris",
126   "+emoji",
127   "+gfm_auto_identifiers",
128   "+pipe_tables",
129   "+strikeout",
130   "+task_lists"
131  )
132}
133