#' 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}",
      solve_enc(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)
  }
}
