blob: fb83abe2890f19be9767d38aca3237aaad3215af [file] [log] [blame]
Hao Zhue0a36a82015-11-23 15:35:20 -05001#' Rmarkdown Format
2#'
3#' @description If the export format of the Rmarkdown document exist,
4#'
5#' @importFrom rmarkdown metadata
6#'
7#' @export
8
9rmd_format <- function(){
10 rmd_output_metadata <- metadata$output
Hao Zhuc1f38412017-02-23 12:13:48 -050011 return(names(rmd_output_metadata))
12}
13
14#' Load a LaTeX package
15#'
16#' @description Load a LaTeX package using R code. Just like `\\usepackage{}`
17#' in LaTeX
18#'
19#' @param name The LaTeX package name
20#' @param options The LaTeX options for the package
Hao Zhu78e61222017-05-24 20:53:35 -040021#'
22#' @examples usepackage_latex("xcolor")
Hao Zhuc1f38412017-02-23 12:13:48 -050023#' @export
24usepackage_latex <- function(name, options = NULL) {
25 invisible(knit_meta_add(list(latex_dependency(name, options))))
Hao Zhue0a36a82015-11-23 15:35:20 -050026}
Hao Zhu62cdde52017-05-20 22:16:03 -040027
28# Find the right xml section. Since xml_child + search name will result in a
29# crash (at least on my machine), here is a helper function.
30xml_tpart <- function(x, part) {
31 xchildren <- xml_children(x)
32 children_names <- xml_name(xchildren)
Hao Zhufc14c9b2017-05-22 14:03:22 -040033 if(!part %in% children_names) return(NULL)
Hao Zhu62cdde52017-05-20 22:16:03 -040034 return(xchildren[[which(children_names == part)]])
35}
36
37positions_corrector <- function(positions, group_header_rows, n_row) {
38 pc_matrix <- data.frame(row_id = 1:n_row)
39 pc_matrix$group_header <- pc_matrix$row_id %in% group_header_rows
40 pc_matrix$adj <- cumsum(pc_matrix$group_header)
41 pc_matrix$old_id <- cumsum(!pc_matrix$group_header)
42 pc_matrix$old_id[duplicated(pc_matrix$old_id)] <- NA
43 adjust_numbers <- pc_matrix$adj[pc_matrix$old_id %in% positions]
44 return(adjust_numbers + positions)
45}
Hao Zhu73604282017-06-11 22:08:48 -040046
47latex_row_cells <- function(x) {
Hao Zhuda886992019-01-07 17:29:44 -050048 out <- strsplit(x, " \\& ")
Hao Zhu7039ecf2019-01-06 17:51:21 -050049 if (substr(x, nchar(x) - 2, nchar(x)) == " & ") {
50 out <- c(out, "")
51 }
52 return(out)
Hao Zhu73604282017-06-11 22:08:48 -040053}
Hao Zhu2a87e8e2017-06-14 15:49:33 -040054
Hao Zhu2ce42b92017-06-15 17:15:33 -040055regex_escape <- function(x, double_backslash = FALSE) {
56 if (double_backslash) {
57 x <- gsub("\\\\", "\\\\\\\\", x)
58 }
59 x <- gsub("\\$", "\\\\\\$", x)
60 x <- gsub("\\(", "\\\\(", x)
61 x <- gsub("\\)", "\\\\)", x)
Hao Zhu9b05ce12017-08-26 11:02:23 -040062 x <- gsub("\\[", "\\\\[", x)
63 x <- gsub("\\]", "\\\\]", x)
Hao Zhu2ce42b92017-06-15 17:15:33 -040064 x <- gsub("\\{", "\\\\{", x)
65 x <- gsub("\\}", "\\\\}", x)
66 x <- gsub("\\*", "\\\\*", x)
Hao Zhuf451dbb2017-08-22 16:51:38 -040067 x <- gsub("\\+", "\\\\+", x)
energien35f01b12017-10-14 21:06:21 +020068 x <- gsub("\\?", "\\\\?", x)
Hao Zhucfab7f12018-04-21 11:04:52 -040069 x <- gsub("\\|", "\\\\|", x)
Hao Zhu5d53dad2018-05-20 19:02:53 -040070 x <- gsub("\\^", "\\\\^", x)
Hao Zhu2ce42b92017-06-15 17:15:33 -040071 return(x)
72}
Hao Zhu96a50b52017-06-14 18:09:35 -040073
Hao Zhuf2dfd142017-07-24 14:43:28 -040074as_kable_xml <- function(x) {
Hao Zhuf01139c2017-08-03 09:08:20 -040075 out <- structure(as.character(x), format = "html", class = "knitr_kable")
Hao Zhuf2dfd142017-07-24 14:43:28 -040076 return(out)
77}
Hao Zhu9bab1532017-07-24 15:08:41 -040078
79read_kable_as_xml <- function(x) {
Hao Zhu0a98df02017-12-27 14:52:37 -050080 kable_html <- read_html(as.character(x), options = c("RECOVER", "NOERROR"))
Hao Zhu9bab1532017-07-24 15:08:41 -040081 xml_child(xml_child(kable_html, 1), 1)
82}
Hao Zhu356ca9f2017-09-05 16:10:26 -040083
84#' LaTeX Packages
85#' @description This function shows all LaTeX packages that is supposed to be
86#' loaded for this package in a rmarkdown yaml format.
87#'
88#' @export
89kableExtra_latex_packages <- function() {
90
Hao Zhu2a6256d2017-09-14 14:54:40 -040091 pkg_list <- paste0(" - ", latex_pkg_list())
Hao Zhu356ca9f2017-09-05 16:10:26 -040092
93 pkg_text <- paste0(
94 "header-includes:\n",
95 paste0(pkg_list, collapse = "\n")
96 )
97
98 cat(pkg_text)
99}
Hao Zhu2a6256d2017-09-14 14:54:40 -0400100
101latex_pkg_list <- function() {
102 return(c(
103 "\\usepackage{booktabs}",
104 "\\usepackage{longtable}",
105 "\\usepackage{array}",
106 "\\usepackage{multirow}",
Hao Zhu2a6256d2017-09-14 14:54:40 -0400107 "\\usepackage{wrapfig}",
108 "\\usepackage{float}",
109 "\\usepackage{colortbl}",
110 "\\usepackage{pdflscape}",
111 "\\usepackage{tabu}",
Hao Zhu5ece06e2018-01-19 23:18:02 -0500112 "\\usepackage{threeparttable}",
Hao Zhu6107f372018-05-21 00:23:26 -0400113 "\\usepackage{threeparttablex}",
114 "\\usepackage[normalem]{ulem}",
antaldaniel719e7112018-05-30 21:40:32 +0200115 "\\usepackage[normalem]{ulem}",
116 "\\usepackage[utf8]{inputenc}",
Hao Zhuf1873a42019-01-07 15:57:01 -0500117 "\\usepackage{makecell}",
118 "\\usepackage{xcolor}"
Hao Zhu2a6256d2017-09-14 14:54:40 -0400119 ))
120}
Hao Zhu064990d2017-10-17 18:08:42 -0400121
122# Fix duplicated rows in LaTeX tables
123fix_duplicated_rows_latex <- function(kable_input, table_info) {
124 # Since sub/string_replace start from beginning, we count unique value from
125 # behind.
126 rev_contents <- rev(table_info$contents)
127 dup_index <- rev(ave(seq_along(rev_contents), rev_contents,
128 FUN = seq_along))
129 for (i in which(dup_index != 1)) {
130 dup_row <- table_info$contents[i]
131 empty_times <- dup_index[i] - 1
Leo83f05132018-05-10 14:12:16 +0800132 # insert empty_times before last non whitespace characters
Hao Zhubdc59ba2018-04-05 14:24:56 -0400133 new_row <- str_replace(
Leo83f05132018-05-10 14:12:16 +0800134 dup_row, "(?<=\\s)([\\S]+[\\s]*)$",
135 paste0("\\\\\\\\vphantom\\\\{", empty_times, "\\\\} \\1"))
136 kable_input <- sub(dup_row, new_row, kable_input)
Hao Zhu064990d2017-10-17 18:08:42 -0400137 table_info$contents[i] <- new_row
138 }
139 table_info$duplicated_rows <- FALSE
140 return(list(kable_input, table_info))
141}
142
Hao Zhu3fc0e882018-04-03 16:06:41 -0400143# Solve enc issue for LaTeX tables
144solve_enc <- function(x) {
antaldaniel719e7112018-05-30 21:40:32 +0200145 #may behave differently based on Sys.setlocale settings with respect to characters
Hao Zhu905b31a2019-01-07 11:00:05 -0500146 out <- enc2utf8(as.character(base::format(x, trim = TRUE, justify = 'none')))
147 mostattributes(out) <- attributes(x)
148 return(out)
Hao Zhu3fc0e882018-04-03 16:06:41 -0400149}
Hao Zhu064990d2017-10-17 18:08:42 -0400150
Hao Zhuf94a26f2018-04-05 17:42:55 -0400151input_escape <- function(x, latex_align) {
152 x <- escape_latex2(x)
153 x <- linebreak(x, align = latex_align, double_escape = TRUE)
154}
155