Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 1 | #' HTML table attributes |
| 2 | #' |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 3 | #' @description This function provides a cleaner approach to modify the style |
| 4 | #' of HTML tables other than using the `table.attr` option in `knitr::kable()`. |
| 5 | #' Currenly, it assumes the HTML document has boot |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 6 | #' |
Hao Zhu | 9495658 | 2017-02-21 18:18:29 -0500 | [diff] [blame] | 7 | #' @param bootstrap_options A character vector for bootstrap table options. For |
| 8 | #' detailed information, please check the package vignette or visit the |
Hao Zhu | 59f5fe0 | 2017-02-22 11:27:14 -0500 | [diff] [blame] | 9 | #' w3schools' \href{https://www.w3schools.com/bootstrap/bootstrap_tables.asp}{Bootstrap Page} |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 10 | #' . Possible options include "basic", "striped", "bordered", "hover", |
Hao Zhu | 9495658 | 2017-02-21 18:18:29 -0500 | [diff] [blame] | 11 | #' "condensed" and "responsive". |
Hao Zhu | 59f5fe0 | 2017-02-22 11:27:14 -0500 | [diff] [blame] | 12 | #' @param full_width A `TRUE` or `FALSE` variable controlling whether the HTML |
Hao Zhu | 9495658 | 2017-02-21 18:18:29 -0500 | [diff] [blame] | 13 | #' table should have 100\% width. |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 14 | #' @param position A character string determining whether and how the HTML table |
Hao Zhu | 59f5fe0 | 2017-02-22 11:27:14 -0500 | [diff] [blame] | 15 | #' should float on the page. Values could be "left", "center", "right" |
Hao Zhu | 9495658 | 2017-02-21 18:18:29 -0500 | [diff] [blame] | 16 | #' @param font_size A numeric input for table font size |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 17 | #' |
| 18 | #' @export |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 19 | kable_styling <- function(kable_input, |
| 20 | bootstrap_options = "basic", |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 21 | latex_options = "basic", |
| 22 | full_width = NULL, |
| 23 | position = c("center", "left", "right", |
| 24 | "float_left", "float_right"), |
| 25 | font_size = NULL) { |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 26 | kable_format <- attr(kable_input, "format") |
| 27 | if (!kable_format %in% c("html", "latex")) { |
| 28 | stop("Please specify output format in your kable function. Currently ", |
| 29 | "generic markdown table using pandoc is not supported.") |
| 30 | } |
| 31 | if (kable_format == "html") { |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 32 | if (is.null(full_width)) full_width <- T |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 33 | return(htmlTable_styling(kable_input, |
| 34 | bootstrap_options = bootstrap_options, |
| 35 | full_width = full_width, |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 36 | position = position, |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 37 | font_size = font_size)) |
| 38 | } |
| 39 | if (kable_format == "latex") { |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 40 | if (is.null(full_width)) full_width <- F |
| 41 | return(pdfTable_styling(kable_input, |
| 42 | latex_options = latex_options, |
| 43 | full_width = full_width, |
| 44 | position = position, |
| 45 | font_size = font_size)) |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 46 | } |
| 47 | } |
| 48 | |
| 49 | # htmlTable Styling ------------ |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 50 | htmlTable_styling <- function(kable_input, |
| 51 | bootstrap_options = "basic", |
| 52 | full_width = T, |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 53 | position = c("center", "left", "right", |
| 54 | "float_left", "float_right"), |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 55 | font_size = NULL) { |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 56 | |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 57 | kable_xml <- read_xml(as.character(kable_input), options = c("COMPACT")) |
| 58 | |
| 59 | # Modify class |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 60 | bootstrap_options <- match.arg( |
| 61 | bootstrap_options, |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 62 | c("basic", "striped", "bordered", "hover", "condensed", "responsive"), |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 63 | several.ok = T |
| 64 | ) |
| 65 | |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 66 | kable_xml_class <- NULL |
| 67 | if (xml_has_attr(kable_xml, "class")) { |
| 68 | kable_xml_class <- xml_attr(kable_xml, "class") |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 69 | } |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 70 | if (length(bootstrap_options) == 1 && bootstrap_options == "basic") { |
| 71 | bootstrap_options <- "table" |
| 72 | } else { |
| 73 | bootstrap_options <- bootstrap_options[bootstrap_options != "basic"] |
| 74 | bootstrap_options <- paste0("table-", bootstrap_options) |
| 75 | bootstrap_options <- c("table", bootstrap_options) |
| 76 | } |
| 77 | xml_attr(kable_xml, "class") <- paste(c(kable_xml_class, bootstrap_options), |
| 78 | collapse = " ") |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 79 | |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 80 | # Modify style |
| 81 | kable_xml_style <- NULL |
| 82 | if (xml_has_attr(kable_xml, "style")) { |
| 83 | kable_xml_style <- xml_attr(kable_xml, "style") |
| 84 | } |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 85 | if (!is.null(font_size)) { |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 86 | kable_xml_style <- c(kable_xml_style, |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 87 | paste0("font-size: ", font_size, "px;")) |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 88 | } |
| 89 | if (!full_width) { |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 90 | kable_xml_style <- c(kable_xml_style, "width: auto !important;") |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 91 | } |
Hao Zhu | 9495658 | 2017-02-21 18:18:29 -0500 | [diff] [blame] | 92 | |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 93 | position <- match.arg(position) |
| 94 | position_style <- switch( |
| 95 | position, |
| 96 | center = "margin-left: auto; margin-right: auto;", |
| 97 | left = "text-align: right;", |
| 98 | right = "margin-right: 0; margin-left: auto", |
| 99 | float_left = "float: left; margin-right: 10px;", |
| 100 | float_right = "float: right; margin-left: 10px;" |
| 101 | ) |
| 102 | kable_xml_style <- c(kable_xml_style, position_style) |
| 103 | |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 104 | if (length(kable_xml_style) != 0) { |
| 105 | xml_attr(kable_xml, "style") <- paste(kable_xml_style, collapse = " ") |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 106 | } |
Hao Zhu | 2623412 | 2017-02-22 15:34:33 -0500 | [diff] [blame] | 107 | return(structure(as.character(kable_xml), format = "html", |
| 108 | class = "knitr_kable")) |
Hao Zhu | e10cfd3 | 2017-02-21 16:41:14 -0500 | [diff] [blame] | 109 | } |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 110 | |
| 111 | # LaTeX table style |
| 112 | pdfTable_styling <- function(kable_input, |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 113 | latex_options = "basic", |
| 114 | full_width = F, |
| 115 | position = c("center", "left", "right", |
| 116 | "float_left", "float_right"), |
| 117 | font_size = NULL) { |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 118 | |
Hao Zhu | c05e181 | 2017-02-25 01:45:35 -0500 | [diff] [blame^] | 119 | latex_options <- match.arg( |
| 120 | latex_options, |
| 121 | c("basic", "striped", "hold_position", "scale_down"), |
| 122 | several.ok = T |
| 123 | ) |
| 124 | |
| 125 | out = NULL |
| 126 | out <- as.character(kable_input) |
| 127 | table_info <- magic_mirror(kable_input) |
| 128 | valign <- sub("\\[", "\\\\[", table_info$valign) |
| 129 | valign <- sub("\\]", "\\\\]", valign) |
| 130 | begin_tabular <- paste0("\\\\begin\\{", table_info$tabular, "\\}", valign) |
| 131 | end_tabular <- paste0("\\\\end\\{", table_info$tabular, "\\}") |
| 132 | |
| 133 | |
| 134 | if ("striped" %in% latex_options) { |
| 135 | usepackage_latex("xcolor", "table") |
| 136 | out <- paste0( |
| 137 | # gray!6 is the same as shadecolor ({RGB}{248, 248, 248}) in pdf_document |
| 138 | "\\rowcolors{2}{gray!6}{white}\n", |
| 139 | out, |
| 140 | "\n\\rowcolors{2}{white}{white}" |
| 141 | ) |
| 142 | } |
| 143 | |
| 144 | # hold_position is only meaningful in a table environment |
| 145 | if ("hold_position" %in% latex_options & table_info$table_env) { |
| 146 | table_env <- "\\\\begin\\{table\\}" |
| 147 | out <- sub("\\\\begin\\{table\\}", "\\\\begin\\{table\\}[!h]", out) |
| 148 | } |
| 149 | |
| 150 | if ("scale_down" %in% latex_options | full_width) { |
| 151 | out <- sub(begin_tabular, |
| 152 | paste0("\\\\resizebox\\{\\\\textwidth\\}\\{\\!\\}\\{", |
| 153 | begin_tabular), |
| 154 | out) |
| 155 | out <- sub(end_tabular, paste0(end_tabular, "\\}"), out) |
| 156 | } |
| 157 | |
| 158 | if (full_width) { |
| 159 | size_matrix <- sapply(sapply(table_info$contents, str_split, " & "), nchar) |
| 160 | col_max_length <- apply(size_matrix, 1, max) + 4 |
| 161 | col_ratio <- round(col_max_length / sum(col_max_length) * 0.9, 2) |
| 162 | col_align <- paste0("p{", col_ratio, "\\\\hsize}") |
| 163 | col_align <- paste0("{", paste(col_align, collapse = ""), "}") |
| 164 | |
| 165 | out <- sub(paste0(begin_tabular, "\\{[^\\\\n]*\\}"), begin_tabular, out) |
| 166 | out <- sub(begin_tabular, paste0(begin_tabular, col_align), out) |
| 167 | } |
| 168 | |
| 169 | position <- match.arg(position) |
| 170 | if (position == "right") { |
| 171 | warning("Right a") |
| 172 | } |
| 173 | |
| 174 | out <- structure(out, format = "latex", class = "knitr_kable") |
| 175 | return(out) |
Hao Zhu | c1f3841 | 2017-02-23 12:13:48 -0500 | [diff] [blame] | 176 | } |