#' Convert a LaTeX table to an image and place it in a rmarkdown document
#'
#' @description This is a LaTeX-only function. This function will render the
#' raw LaTeX code (could be codes generated by other table packages like
#' `xtable`) to generate a table, convert it to an image and put it back to a
#' rmarkdown environment. It is a "better than nothing" solution to print high
#' quality tables in rmarkdown Word document. By using this, you need to take
#' the responsibility of explaining to your collaborators why they can't make
#' edits to the tables in Word.
#'
#' Also, if a filename is provided, user has the option to "save" the table to
#' an image file like `ggplot2::ggsave()`.
#'
#' Note that, if you are using this function on a Windows computer, you need
#' to install Ghostscript before you can use this feature. It is essential for
#' magick to read PDFs on Windows. Website for Ghostscript: https://ghostscript.com/
#'
#' The idea of this function was coming from [this StackOverflow question](https://stackoverflow.com/questions/44711313/save-rmarkdowns-report-tables-and-figures-to-file).
#' The approach was learned and adopted from the [texpreview](https://github.com/metrumresearchgroup/texPreview)
#' package, which allows you to preview the results of TeX code in the Viewer panel.
#'
#' @param kable_input Raw LaTeX code to generate a table. It doesn't have to
#' came from `kable` or `kableExtra`.
#' @param filename Character String. If specified, the image will be saved under
#' the specified (path &) name. You don't need to put file format like ".png"
#' here.
#' @param file_format Character String to specify image format, such as `png`,
#' `jpeg`, `gif`, `tiff`, etc. Default is `png`.
#' @param latex_header_includes A character vector of extra LaTeX header stuff.
#' Each element is a row. You can have things like
#' `c("\\usepackage{threeparttable}", "\\usepackage{icons}")`
#' @param keep_pdf A T/F option to control if the mid-way standalone pdf should
#' be kept. Default is `FALSE`.
#' @param density Resolution to read the PDF file. Default value is 300, which
#' should be sufficient in most cases.
#' @param keep_tex A T/F option to control if the latex file that is initially created
#' should be kept. Default is `FALSE`.
#'
#' @export
kable_as_image <- function(kable_input, filename = NULL,
                           file_format = "png",
                           latex_header_includes = NULL,
                           keep_pdf = FALSE,
                           density = 300,
                           keep_tex = FALSE) {
  if (!requireNamespace("magick", quietly = TRUE)) {
    stop('kable_as_image requires the magick package, which is not available ',
         'on all platforms. Please get it installed ',
         'via install.packages("magick"). If you are running on Windows, you ',
         'also need to install Ghostscript. Please download it here:',
         'https://ghostscript.com/')
  } else {
    temp_tex <- c(
      "\\documentclass[border=1mm, preview]{standalone}",
      "\\usepackage[active,tightpage]{preview}",
      "\\usepackage{varwidth}",
      "\\usepackage{amssymb, amsmath}",
      "\\usepackage{ifxetex,ifluatex}",
      "\\usepackage{fixltx2e}",
      "\\usepackage{polyglossia}",
      "\\setmainlanguage{$mainlang$}",
      latex_pkg_list(),
      "\\usepackage{graphicx}",
      "\\usepackage{mathspec}",
      "\\usepackage{xltxtra,xunicode}",
      latex_header_includes,
      "\\begin{document}",
      enc2utf8(as.character(kable_input)),
      "\\end{document}"
    )
    temp_tex <- paste(temp_tex, collapse = "\n")
    temp_file <- paste0("table_", format(Sys.time(), "%Y-%m-%d_%H%M%S"))
    writeLines(temp_tex, paste0(temp_file, ".tex"))
    system(paste0("xelatex -interaction=batchmode ", temp_file, ".tex"))
    temp_file_delete <- paste0(temp_file, c(".tex", ".aux", ".log"))
    if(!keep_tex) {
      unlink(temp_file_delete)
    }

    table_img_pdf <- try(magick::image_read(paste0(temp_file, ".pdf"),
                                            density = density),
                         silent = T)
    if (class(table_img_pdf) == "try-error") {
      stop("Ghostscript is required to read PDF on windows. ",
           "Please download it here: https://ghostscript.com/")
    }
    if (!keep_pdf) {
      unlink(paste0(temp_file, ".pdf"))
    }
    table_img <- magick::image_convert(table_img_pdf, file_format)
    if (!is.null(filename)) {
      temp_img <- paste0(filename, ".", file_format)
    } else {
      temp_img <- tempfile(fileext = paste0(".", file_format))
    }
    magick::image_write(table_img, temp_img)

    include_graphics(temp_img)
  }
}
