1#' Convert to a PDF/LaTeX document
2#'
3#' Formats for converting from R Markdown to a PDF or LaTeX document.
4#'
5#' @inheritParams html_document
6#'
7#' @param fig_crop \code{TRUE} to automatically apply the \code{pdfcrop} utility
8#'   (if available) to pdf figures
9#' @param dev Graphics device to use for figure output (defaults to pdf)
10#' @param highlight Syntax highlighting style. Supported styles include
11#'   "default", "tango", "pygments", "kate", "monochrome", "espresso",
12#'   "zenburn", and "haddock". Pass \code{NULL} to prevent syntax highlighting.
13#' @param keep_tex Keep the intermediate tex file used in the conversion to PDF
14#' @param latex_engine LaTeX engine for producing PDF output. Options are
15#'   "pdflatex", "lualatex", and "xelatex".
16#' @param citation_package The LaTeX package to process citations, \code{natbib}
17#'   or \code{biblatex}. Use \code{none} if neither package is to be used.
18#' @param template Pandoc template to use for rendering. Pass "default" to use
19#'   the rmarkdown package default template; pass \code{NULL} to use pandoc's
20#'   built-in template; pass a path to use a custom template that you've
21#'   created.  See the documentation on
22#'   \href{http://pandoc.org/README.html}{pandoc online documentation}
23#'   for details on creating custom templates.
24#' @param extra_dependencies A LaTeX dependency \code{latex_dependency()}, a
25#'   list of LaTeX dependencies, a character vector of LaTeX package names (e.g.
26#'   \code{c("framed", "hyperref")}), or a named list of LaTeX package options
27#'   with the names being package names (e.g. \code{list(hypreref =
28#'   c("unicode=true", "breaklinks=true"), lmodern = NULL)}). It can be used to
29#'   add custom LaTeX packages to the .tex header.
30#'
31#' @return R Markdown output format to pass to \code{\link{render}}
32#'
33#' @details
34#'
35#' See the \href{http://rmarkdown.rstudio.com/pdf_document_format.html}{online
36#' documentation} for additional details on using the \code{pdf_document} format.
37#'
38#' Creating PDF output from R Markdown requires that LaTeX be installed.
39#'
40#' R Markdown documents can have optional metadata that is used to generate a
41#' document header that includes the title, author, and date. For more details
42#' see the documentation on R Markdown \link[=rmd_metadata]{metadata}.
43#'
44#' R Markdown documents also support citations. You can find more information on
45#' the markdown syntax for citations in the
46#' \href{http://rmarkdown.rstudio.com/authoring_bibliographies_and_citations.html}{Bibliographies
47#' and Citations} article in the online documentation.
48#'
49#' Many aspects of the LaTeX template used to create PDF documents can be
50#' customized using metadata. For example:
51#'
52#' \tabular{l}{
53#' \code{---} \cr
54#' \code{title: "Crop Analysis Q3 2013"} \cr
55#' \code{fontsize: 11pt} \cr
56#' \code{geometry: margin=1in} \cr
57#' \code{---}
58#' }
59#'
60#' Available metadata variables include:
61#'
62#' \describe{
63#'    \item{\code{lang}}{Document language code (e.g. "es", "fr", "pt-BR")}
64#'    \item{\code{fontsize}}{Font size (e.g. 10pt, 11pt, 12pt)}
65#'    \item{\code{documentclass}}{LaTeX document class (e.g. article)}
66#'    \item{\code{classoption}}{Option for \code{documentclass} (e.g. oneside); may be repeated}
67#'    \item{\code{geometry}}{Options for geometry class (e.g. margin=1in); may be repeated}
68#'    \item{\code{mainfont, sansfont, monofont, mathfont}}{Document fonts (works only with xelatex and lualatex, see the \code{latex_engine} option)}
69#'    \item{\code{linkcolor, urlcolor, citecolor}}{Color for internal, external, and citation links (red, green, magenta, cyan, blue, black)}
70#'    \item{\code{linestretch}}{Options for line spacing (e.g. 1, 1.5, 3)}
71#' }
72#'
73#' @examples
74#' \dontrun{
75#'
76#' library(rmarkdown)
77#'
78#' # simple invocation
79#' render("input.Rmd", pdf_document())
80#'
81#' # specify an option for latex engine
82#' render("input.Rmd", pdf_document(latex_engine = "lualatex"))
83#'
84#' # add a table of contents and pass an option to pandoc
85#' render("input.Rmd", pdf_document(toc = TRUE, "--listings"))
86#' }
87#'
88#' @export
89pdf_document <- function(toc = FALSE,
90                         toc_depth = 2,
91                         number_sections = FALSE,
92                         fig_width = 6.5,
93                         fig_height = 4.5,
94                         fig_crop = TRUE,
95                         fig_caption = TRUE,
96                         dev = 'pdf',
97                         df_print = "default",
98                         highlight = "default",
99                         template = "default",
100                         keep_tex = FALSE,
101                         latex_engine = "pdflatex",
102                         citation_package = c("none", "natbib", "biblatex"),
103                         includes = NULL,
104                         md_extensions = NULL,
105                         pandoc_args = NULL,
106                         extra_dependencies = NULL) {
107
108  # base pandoc options for all PDF output
109  args <- c()
110
111  # table of contents
112  args <- c(args, pandoc_toc_args(toc, toc_depth))
113
114  # template path and assets
115  if (identical(template, "default")) {
116
117    pandoc_available(error = TRUE)
118    # choose the right template
119    version <- pandoc_version()
120    if (version >= "1.17.0.2")
121      latex_template <- "default-1.17.0.2.tex"
122    else if (version >= "1.15.2")
123      latex_template <- "default-1.15.2.tex"
124    else if (version >= "1.14")
125      latex_template <- "default-1.14.tex"
126    else
127      latex_template <- "default.tex"
128
129    # add to args
130    args <- c(args, "--template",
131              pandoc_path_arg(rmarkdown_system_file(paste0("rmd/latex/",
132                                                           latex_template))))
133
134  } else if (!is.null(template)) {
135    args <- c(args, "--template", pandoc_path_arg(template))
136  }
137
138  # numbered sections
139  if (number_sections)
140    args <- c(args, "--number-sections")
141
142  # highlighting
143  if (!is.null(highlight))
144    highlight <- match.arg(highlight, highlighters())
145  args <- c(args, pandoc_highlight_args(highlight))
146
147  # latex engine
148  latex_engine = match.arg(latex_engine, c("pdflatex", "lualatex", "xelatex"))
149  args <- c(args, pandoc_latex_engine_args(latex_engine))
150
151  # citation package
152  citation_package <- match.arg(citation_package)
153  if (citation_package != "none") args <- c(args, paste0("--", citation_package))
154
155  # content includes
156  args <- c(args, includes_to_pandoc_args(includes))
157
158  # make sure the graphics package is always loaded
159  if (identical(template, "default")) args <- c(args, "--variable", "graphics=yes")
160
161  # args args
162  args <- c(args, pandoc_args)
163
164  saved_files_dir <- NULL
165
166  # Use filter to set pdf geometry defaults (while making sure we don't override
167  # any geometry settings already specified by the user)
168  pdf_pre_processor <- function(metadata, input_file, runtime, knit_meta, files_dir,
169                                output_dir) {
170
171    args <- c()
172
173    # set the margin to 1 inch if no other geometry options specified
174    has_geometry <- function(text) {
175      length(grep("^geometry:.*$", text)) > 0
176    }
177    if (!has_geometry(readLines(input_file, warn = FALSE)))
178      args <- c(args, "--variable", "geometry:margin=1in")
179
180    if (length(extra_dependencies) || has_latex_dependencies(knit_meta)) {
181      extra_dependencies <- latex_dependencies(extra_dependencies)
182      all_dependencies <- append(extra_dependencies, flatten_latex_dependencies(knit_meta))
183      filename <- as_tmpfile(latex_dependencies_as_string(all_dependencies))
184      if ("header-includes" %in% names(metadata)) {
185        cat(c("", metadata[["header-includes"]]), sep = "\n", file = filename, append = TRUE)
186      }
187      args <- c(args, includes_to_pandoc_args(includes(in_header = filename)))
188    }
189    args
190  }
191
192
193  pre_processor <- function(metadata, input_file, runtime, knit_meta,
194                                files_dir, output_dir) {
195    # save files dir (for generating intermediates)
196    saved_files_dir <<- files_dir
197
198    # use a geometry filter when we are using the "default" template
199    if (identical(template, "default"))
200      pdf_pre_processor(metadata, input_file, runtime, knit_meta, files_dir,
201                        output_dir)
202    else
203      invisible(NULL)
204  }
205
206  intermediates_generator <- function(original_input, encoding,
207                                      intermediates_dir) {
208    return(pdf_intermediates_generator(saved_files_dir, original_input,
209                                        encoding, intermediates_dir))
210  }
211
212  # return format
213  output_format(
214    knitr = knitr_options_pdf(fig_width, fig_height, fig_crop, dev),
215    pandoc = pandoc_options(to = "latex",
216                            from = from_rmarkdown(fig_caption, md_extensions),
217                            args = args,
218                            latex_engine = latex_engine,
219                            keep_tex = keep_tex),
220    clean_supporting = !keep_tex,
221    df_print = df_print,
222    pre_processor = pre_processor,
223    intermediates_generator = intermediates_generator
224  )
225}
226
227pdf_intermediates_generator <- function(saved_files_dir, original_input,
228                                        encoding, intermediates_dir) {
229  # copy all intermediates (pandoc will need to bundle them in the PDF)
230  intermediates <- copy_render_intermediates(original_input, encoding,
231                                             intermediates_dir, FALSE)
232
233  # we need figures from the supporting files dir to be available during
234  # render as well; if we have a files directory, copy its contents
235  if (!is.null(saved_files_dir) && dir_exists(saved_files_dir)) {
236    file.copy(saved_files_dir, intermediates_dir, recursive = TRUE)
237    intermediates <- c(intermediates, list.files(
238      path = file.path(intermediates_dir, basename(saved_files_dir)),
239      all.files = TRUE, recursive = TRUE, full.names = TRUE))
240  }
241
242  intermediates
243}
244
245#' @param ... Arguments passed to \code{pdf_document()}.
246#' @rdname pdf_document
247#' @export
248latex_document <- function(...) {
249  merge_lists(pdf_document(...), list(pandoc = list(ext = ".tex", keep_tex = TRUE)))
250}
251
252#' @rdname pdf_document
253#' @export
254latex_fragment <- function(...) {
255  latex_document(..., template = rmarkdown_system_file("rmd/fragment/default.tex"))
256}
257