Hao Zhu | 8dd65a9 | 2018-01-05 20:40:27 -0500 | [diff] [blame^] | 1 | #' Add advanced footnote |
| 2 | #' |
| 3 | #' @export |
| 4 | add_footnote_adv <- function(kable_input, |
| 5 | general = NULL, |
| 6 | number = NULL, |
| 7 | alphabet = NULL, |
| 8 | symbol = NULL, |
| 9 | footnote_order = c("general", "number", |
| 10 | "alphabet", "symbol"), |
| 11 | footnote_as_chunk = FALSE, |
| 12 | general_title = "Note: ", |
| 13 | number_title = "", |
| 14 | alphabet_title = "", |
| 15 | symbol_title = "" |
| 16 | ) { |
| 17 | kable_format <- attr(kable_input, "format") |
| 18 | if (!kable_format %in% c("html", "latex")) { |
| 19 | message("Currently generic markdown table using pandoc is not supported.") |
| 20 | return(kable_input) |
| 21 | } |
| 22 | footnote_titles <- list( |
| 23 | general = general_title, number = number_title, |
| 24 | alphabet = alphabet_title, symbol = symbol_title |
| 25 | ) |
| 26 | footnote_contents <- list( |
| 27 | general = general, number = number, alphabet = alphabet, symbol = symbol |
| 28 | ) |
| 29 | notnull <- names(footnote_contents)[!sapply(footnote_contents, is.null)] |
| 30 | if (length(notnull) == 0) {return(kable_input)} |
| 31 | if (length(alphabet) > 26) { |
| 32 | alphabet <- alphabet[1:26] |
| 33 | warning("Please don't use more than 26 footnotes in table_footnote ", |
| 34 | "alphabet. Use number instead.") |
| 35 | } |
| 36 | if (length(symbol) > 20) { |
| 37 | symbol <- symbol[1:20] |
| 38 | warning("Please don't use more than 20 footnotes in table_footnote ", |
| 39 | "symbol. Use number instead.") |
| 40 | } |
| 41 | footnote_order <- footnote_order[footnote_order %in% notnull] |
| 42 | footnote_titles <- footnote_titles[footnote_order] |
| 43 | footnote_contents <- footnote_contents[footnote_order] |
| 44 | footnote_table <- footnote_table_maker( |
| 45 | kable_format, footnote_titles, footnote_contents |
| 46 | ) |
| 47 | if (kable_format == "html") { |
| 48 | return(add_footnote_adv_html(kable_input, footnote_table, footnote_as_chunk)) |
| 49 | } |
| 50 | # if (kable_format == "latex") { |
| 51 | # return(add_footnote_adv_latex(kable_input, footnote_table)) |
| 52 | # } |
| 53 | } |
| 54 | |
| 55 | footnote_table_maker <- function(format, footnote_titles, footnote_contents) { |
| 56 | number_index <- read.csv(system.file("symbol_index.csv", |
| 57 | package = "kableExtra")) |
| 58 | if (format == "latex") { |
| 59 | symbol_index <- number_index$symbol.latex |
| 60 | } else { |
| 61 | symbol_index <- number_index$symbol.html |
| 62 | } |
| 63 | contents_length <- sapply(footnote_contents, length) |
| 64 | |
| 65 | if (!is.null(footnote_contents$general)) { |
| 66 | footnote_contents$general <- data.frame( |
| 67 | index = "", |
| 68 | footnote = paste(footnote_contents$general, collapse = " ") |
| 69 | ) |
| 70 | } |
| 71 | if (!is.null(footnote_contents$number)) { |
| 72 | footnote_contents$number <- data.frame( |
| 73 | index = as.character(1:length(footnote_contents$number)), |
| 74 | footnote = footnote_contents$number |
| 75 | ) |
| 76 | } |
| 77 | if (!is.null(footnote_contents$alphabet)) { |
| 78 | footnote_contents$alphabet <- data.frame( |
| 79 | index = letters[1:length(footnote_contents$alphabet)], |
| 80 | footnote = footnote_contents$alphabet |
| 81 | ) |
| 82 | } |
| 83 | if (!is.null(footnote_contents$symbol)) { |
| 84 | footnote_contents$symbol <- data.frame( |
| 85 | index = symbol_index[1:length(footnote_contents$symbol)], |
| 86 | footnote = footnote_contents$symbol |
| 87 | ) |
| 88 | } |
| 89 | |
| 90 | out <- list() |
| 91 | out$contents <- footnote_contents |
| 92 | out$titles <- footnote_titles |
| 93 | return(out) |
| 94 | } |
| 95 | |
| 96 | # HTML |
| 97 | add_footnote_adv_html <- function(kable_input, footnote_table, |
| 98 | footnote_as_chunk) { |
| 99 | kable_attrs <- attributes(kable_input) |
| 100 | kable_xml <- read_kable_as_xml(kable_input) |
| 101 | |
| 102 | new_html_footnote <- adv_html_tfoot_maker(footnote_table, footnote_as_chunk) |
| 103 | xml_add_child(kable_xml, new_html_footnote) |
| 104 | |
| 105 | out <- as_kable_xml(kable_xml) |
| 106 | attributes(out) <- kable_attrs |
| 107 | return(out) |
| 108 | } |
| 109 | |
| 110 | adv_html_tfoot_maker <- function(footnote_table, footnote_as_chunk) { |
| 111 | footnote_types <- names(footnote_table$contents) |
| 112 | footnote_text <- c() |
| 113 | for (i in footnote_types) { |
| 114 | footnote_text <- c(footnote_text, adv_html_tfoot_maker_( |
| 115 | footnote_table$contents[[i]], footnote_table$titles[[i]], i, |
| 116 | footnote_as_chunk)) |
| 117 | } |
| 118 | footnote_text <- paste0( |
| 119 | "<tfoot>", paste0(footnote_text, collapse = ""), "</tfoot>" |
| 120 | ) |
| 121 | footnote_node <- read_html(footnote_text, options = c("RECOVER", "NOERROR")) |
| 122 | return(xml_child(xml_child(footnote_node, 1), 1)) |
| 123 | } |
| 124 | |
| 125 | adv_html_tfoot_maker_ <- function(ft_contents, ft_title, ft_type, ft_chunk) { |
| 126 | |
| 127 | footnote_text <- apply(ft_contents, 1, function(x) { |
| 128 | paste0('<sup>', x[1], '</sup> ', x[2]) |
| 129 | }) |
| 130 | if (ft_title != "") { |
| 131 | title_text <- paste0('<strong>', ft_title, '</strong>') |
| 132 | footnote_text <- c(title_text, footnote_text) |
| 133 | } |
| 134 | if (!ft_chunk) { |
| 135 | footnote_text <- paste0( |
| 136 | '<tr><td style="padding: 0; border: 0;" colspan="100%">', |
| 137 | footnote_text, '</td></tr>' |
| 138 | ) |
| 139 | } else { |
| 140 | footnote_text <- paste0( |
| 141 | '<tr><td style="padding: 0; border: 0;" colspan="100%">', |
| 142 | paste0(footnote_text, collapse = ""), |
| 143 | '</td></tr>' |
| 144 | ) |
| 145 | } |
| 146 | # } |
| 147 | return(footnote_text) |
| 148 | } |