Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 1 | #' Save kable to files |
| 2 | #' |
| 3 | #' @param x A piece of HTML code for tables, usually generated by kable and |
| 4 | #' kableExtra |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 5 | #' @param file save to files. If the input table is in HTML and the output file |
| 6 | #' ends with `.png`, `.pdf` and `.jpeg`, `webshot` will be used to do the |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 7 | #' conversion. |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 8 | #' @param bs_theme Which Bootstrap theme to use |
| 9 | #' @param self_contained Will the files be self-contained? |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 10 | #' @param extra_dependencies Additional HTML dependencies. For example, |
| 11 | #' `list(` |
| 12 | #' @param ... Additional variables being passed to `webshot::webshot`. This |
| 13 | #' is for HTML only. |
| 14 | #' @param latex_header_includes A character vector of extra LaTeX header stuff. |
| 15 | #' Each element is a row. You can have things like |
| 16 | #' `c("\\\\usepackage{threeparttable}", "\\\\usepackage{icons}")` You could |
| 17 | #' probably add your language package here if you use non-English text in your |
| 18 | #' table, such as `\\\\usepackage[magyar]{babel}`. |
| 19 | #' @param keep_tex A T/F option to control if the latex file that is initially created |
| 20 | #' should be kept. Default is `FALSE`. |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 21 | #' |
| 22 | #' @export |
| 23 | save_kable <- function(x, file, |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 24 | bs_theme = "simplex", self_contained = TRUE, |
| 25 | extra_dependencies = NULL, ..., |
| 26 | latex_header_includes = NULL, keep_tex = FALSE) { |
Hao Zhu | d851693 | 2019-01-06 18:56:47 -0500 | [diff] [blame] | 27 | if (!is.null(attr(x, "format")) && attr(x, "format") == "latex") { |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 28 | return(save_kable_latex(x, file, latex_header_includes, keep_tex)) |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 29 | } |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 30 | return(save_kable_html(x, file, bs_theme, self_contained, |
| 31 | extra_dependencies, ...)) |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 32 | } |
| 33 | |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 34 | save_kable_html <- function(x, file, bs_theme, self_contained, |
| 35 | extra_dependencies, ...) { |
| 36 | dependencies <- list( |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 37 | rmarkdown::html_dependency_jquery(), |
| 38 | rmarkdown::html_dependency_bootstrap(theme = bs_theme), |
Hao Zhu | d851693 | 2019-01-06 18:56:47 -0500 | [diff] [blame] | 39 | rmarkdown::html_dependency_font_awesome(), |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 40 | html_dependency_kePrint() |
| 41 | ) |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 42 | if (!is.null(extra_dependencies)) { |
| 43 | dependencies <- append(dependencies, extra_dependencies) |
| 44 | } |
| 45 | |
| 46 | html_header <- htmltools::tag("head", dependencies) |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 47 | html_table <- htmltools::HTML(as.character(x)) |
| 48 | html_result <- htmltools::tagList(html_header, html_table) |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 49 | |
| 50 | # Use webshot if necessary |
| 51 | if (tools::file_ext(file) %in% c("png", "jpg", "jpeg", "pdf")) { |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 52 | message("Putting together a HTML file...") |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 53 | file_html <- paste0(tools::file_path_sans_ext(file), ".html") |
| 54 | htmltools::save_html(html_result, file = file_html) |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 55 | message("Converting HTML to ", tools::file_ext(file), "...") |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 56 | webshot::webshot(file_html, file, ...) |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 57 | message("Done. ") |
| 58 | if (tools::file_ext(file) == "pdf") { |
| 59 | message("Note that HTML color may not be displayed on PDF properly.") |
| 60 | } |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 61 | unlink(file_html) |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 62 | unlink("lib", recursive = TRUE) |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 63 | } else { |
| 64 | htmltools::save_html(html_result, file = file) |
| 65 | if (self_contained) { |
| 66 | rmarkdown::pandoc_self_contained_html(file, file) |
| 67 | unlink("lib", recursive = TRUE) |
| 68 | } |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 69 | } |
Hao Zhu | d851693 | 2019-01-06 18:56:47 -0500 | [diff] [blame] | 70 | |
| 71 | return(file) |
Hao Zhu | 73cf373 | 2018-05-11 17:50:05 -0400 | [diff] [blame] | 72 | } |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 73 | |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 74 | save_kable_latex <- function(x, file, latex_header_includes, keep_tex) { |
| 75 | temp_tex <- c( |
| 76 | "\\documentclass[border=1mm, preview]{standalone}", |
| 77 | "\\usepackage[active,tightpage]{preview}", |
| 78 | "\\usepackage{varwidth}", |
| 79 | "\\usepackage{amssymb, amsmath}", |
| 80 | "\\usepackage{ifxetex,ifluatex}", |
| 81 | "\\usepackage{fixltx2e}", |
| 82 | "\\usepackage{polyglossia}", |
| 83 | "\\setmainlanguage{$mainlang$}", |
| 84 | latex_pkg_list(), |
| 85 | "\\usepackage{graphicx}", |
| 86 | "\\usepackage{mathspec}", |
| 87 | "\\usepackage{xltxtra,xunicode}", |
| 88 | latex_header_includes, |
| 89 | "\\begin{document}", |
| 90 | solve_enc(x), |
| 91 | "\\end{document}" |
| 92 | ) |
| 93 | temp_tex <- paste(temp_tex, collapse = "\n") |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 94 | |
Hao Zhu | d851693 | 2019-01-06 18:56:47 -0500 | [diff] [blame] | 95 | temp_tex_file <- paste0(tools::file_path_sans_ext(file), ".tex") |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 96 | writeLines(temp_tex, temp_tex_file, useBytes = T) |
| 97 | system(paste0("xelatex -interaction=batchmode ", temp_tex_file)) |
| 98 | if (!keep_tex) { |
| 99 | temp_file_delete <- paste0(tools::file_path_sans_ext(file), |
| 100 | c(".tex", ".aux", ".log")) |
| 101 | unlink(temp_file_delete) |
| 102 | } |
| 103 | |
Hao Zhu | d851693 | 2019-01-06 18:56:47 -0500 | [diff] [blame] | 104 | if (tools::file_ext(file) != "pdf") { |
| 105 | table_img_pdf <- try( |
| 106 | magick::image_read(paste0(tools::file_path_sans_ext(file), ".pdf"), |
| 107 | density = 300), silent = T) |
| 108 | if (class(table_img_pdf) == "try-error") { |
| 109 | stop("We hit an error when trying to use magick to read the generated ", |
| 110 | "PDF file. If you are using Windows, it could be possible that you", |
| 111 | " had not installed ghostscript (https://ghostscript.com/). ", |
| 112 | "Otherwise, you may check your magick installation and try to ", |
| 113 | "use magick::image_read to read the PDF file manually. ") |
| 114 | } |
| 115 | unlink(paste0(tools::file_path_sans_ext(file), ".pdf")) |
| 116 | table_img <- magick::image_convert(table_img_pdf, |
| 117 | tools::file_ext(file)) |
| 118 | magick::image_write(table_img, file) |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 119 | } |
Hao Zhu | 7039ecf | 2019-01-06 17:51:21 -0500 | [diff] [blame] | 120 | |
Hao Zhu | d851693 | 2019-01-06 18:56:47 -0500 | [diff] [blame] | 121 | return(file) |
Hao Zhu | 7f8b684 | 2018-10-23 17:41:13 -0400 | [diff] [blame] | 122 | } |