blob: 6a831187ee173eef2bc1127d5733a4e7d527d964 [file] [log] [blame]
Hao Zhu2a64dc62017-08-28 10:57:57 -04001#' Convert a LaTeX table to an image and place it in a rmarkdown document
2#'
3#' @description This is a LaTeX-only function. This function will render the
4#' raw LaTeX code (could be codes generated by other table packages like
5#' `xtable`) to generate a table, convert it to an image and put it back to a
6#' rmarkdown environment. It is a "better than nothing" solution to print high
7#' quality tables in rmarkdown Word document. By using this, you need to take
Hao Zhu245931c2017-09-01 22:43:56 -04008#' the responsibility of explaining to your collaborators why they can't make
Hao Zhua9c43dc2017-09-04 23:00:39 -04009#' edits to the tables in Word.
Hao Zhu2a64dc62017-08-28 10:57:57 -040010#'
11#' Also, if a filename is provided, user has the option to "save" the table to
12#' an image file like `ggplot2::ggsave()`.
13#'
Hao Zhu246b95c2017-09-14 14:29:48 -040014#' Note that, if you are using this function on a Windows computer, you need
15#' to install Ghostscript before you can use this feature. It is essential for
16#' magick to read PDFs on Windows. Website for Ghostscript: https://ghostscript.com/
17#'
Hao Zhu2a64dc62017-08-28 10:57:57 -040018#' The idea of this function was coming from [this StackOverflow question](https://stackoverflow.com/questions/44711313/save-rmarkdowns-report-tables-and-figures-to-file).
19#' The approach was learned and adopted from the [texpreview](https://github.com/metrumresearchgroup/texPreview)
20#' package, which allows you to preview the results of TeX code in the Viewer panel.
21#'
22#' @param kable_input Raw LaTeX code to generate a table. It doesn't have to
23#' came from `kable` or `kableExtra`.
24#' @param filename Character String. If specified, the image will be saved under
25#' the specified (path &) name. You don't need to put file format like ".png"
26#' here.
27#' @param file_format Character String to specify image format, such as `png`,
28#' `jpeg`, `gif`, `tiff`, etc. Default is `png`.
29#' @param latex_header_includes A character vector of extra LaTeX header stuff.
30#' Each element is a row. You can have things like
31#' `c("\\usepackage{threeparttable}", "\\usepackage{icons}")`
32#' @param keep_pdf A T/F option to control if the mid-way standalone pdf should
33#' be kept. Default is `FALSE`.
34#'
Hao Zhu2a64dc62017-08-28 10:57:57 -040035#' @export
36kable_as_image <- function(kable_input, filename = NULL,
37 file_format = "png",
38 latex_header_includes = NULL,
39 keep_pdf = FALSE) {
40 temp_tex <- c(
41 "\\documentclass[border=1mm, preview]{standalone}",
42 "\\usepackage[active,tightpage]{preview}",
43 "\\usepackage{varwidth}",
Hao Zhua9c43dc2017-09-04 23:00:39 -040044 "\\usepackage{amssymb, amsmath}",
Hao Zhu2a64dc62017-08-28 10:57:57 -040045 "\\usepackage{ifxetex,ifluatex}",
46 "\\usepackage{fixltx2e}",
47 "\\usepackage{polyglossia}",
48 "\\setmainlanguage{$mainlang$}",
Hao Zhu2a6256d2017-09-14 14:54:40 -040049 latex_pkg_list(),
Hao Zhu2a64dc62017-08-28 10:57:57 -040050 "\\usepackage{graphicx}",
51 "\\usepackage{mathspec}",
52 "\\usepackage{xltxtra,xunicode}",
53 latex_header_includes,
54 "\\begin{document}",
55 enc2utf8(as.character(kable_input)),
56 "\\end{document}"
57 )
58 temp_tex <- paste(temp_tex, collapse = "\n")
Hao Zhucc397922017-09-14 11:49:21 -040059 temp_file <- paste0("table_", format(Sys.time(), "%Y-%m-%d_%H%M%S"))
Hao Zhu2a64dc62017-08-28 10:57:57 -040060 write_file(temp_tex, paste0(temp_file, ".tex"))
61 system(paste0("xelatex -interaction=batchmode ", temp_file, ".tex"))
62 temp_file_delete <- paste0(temp_file, c(".tex", ".aux", ".log"))
63 unlink(temp_file_delete)
64
Hao Zhu246b95c2017-09-14 14:29:48 -040065 table_img_pdf <- try(image_read(paste0(temp_file, ".pdf"), density = 300),
66 silent = T)
67 if (class(table_img_pdf) == "try-error") {
68 stop("Ghostscript is required to read PDF on windows. ",
69 "Please download it here: https://ghostscript.com/")
70 }
Hao Zhu2a64dc62017-08-28 10:57:57 -040071 if (!keep_pdf) {
72 unlink(paste0(temp_file, ".pdf"))
73 }
74 table_img <- image_convert(table_img_pdf, file_format)
75 if (!is.null(filename)) {
76 temp_img <- paste0(filename, ".", file_format)
77 } else {
78 temp_img <- tempfile(fileext = paste0(".", file_format))
79 }
80 image_write(table_img, temp_img)
81
82 include_graphics(temp_img)
Hao Zhu2a6256d2017-09-14 14:54:40 -040083 return(kable_input)
Hao Zhu2a64dc62017-08-28 10:57:57 -040084}