blob: 9999be7ec2722d25adfb414313f0ad4cfbcaac84 [file] [log] [blame]
#' Add footnote (new)
#'
#' @export
footnote <- function(kable_input,
general = NULL,
number = NULL,
alphabet = NULL,
symbol = NULL,
footnote_order = c("general", "number",
"alphabet", "symbol"),
footnote_as_chunk = FALSE,
general_title = "Note: ",
number_title = "",
alphabet_title = "",
symbol_title = ""
) {
kable_format <- attr(kable_input, "format")
if (!kable_format %in% c("html", "latex")) {
message("Currently generic markdown table using pandoc is not supported.")
return(kable_input)
}
footnote_titles <- list(
general = general_title, number = number_title,
alphabet = alphabet_title, symbol = symbol_title
)
footnote_contents <- list(
general = general, number = number, alphabet = alphabet, symbol = symbol
)
notnull <- names(footnote_contents)[!sapply(footnote_contents, is.null)]
if (length(notnull) == 0) {return(kable_input)}
if (length(alphabet) > 26) {
alphabet <- alphabet[1:26]
warning("Please don't use more than 26 footnotes in table_footnote ",
"alphabet. Use number instead.")
}
if (length(symbol) > 20) {
symbol <- symbol[1:20]
warning("Please don't use more than 20 footnotes in table_footnote ",
"symbol. Use number instead.")
}
footnote_order <- footnote_order[footnote_order %in% notnull]
footnote_titles <- footnote_titles[footnote_order]
footnote_contents <- footnote_contents[footnote_order]
footnote_table <- footnote_table_maker(
kable_format, footnote_titles, footnote_contents
)
if (kable_format == "html") {
return(footnote_html(kable_input, footnote_table, footnote_as_chunk))
}
if (kable_format == "latex") {
return(footnote_latex(kable_input, footnote_table, footnote_as_chunk))
}
}
footnote_table_maker <- function(format, footnote_titles, footnote_contents) {
number_index <- read.csv(system.file("symbol_index.csv",
package = "kableExtra"))
if (format == "latex") {
symbol_index <- number_index$symbol.latex
} else {
symbol_index <- number_index$symbol.html
}
contents_length <- sapply(footnote_contents, length)
if (!is.null(footnote_contents$general)) {
footnote_contents$general <- data.frame(
index = "",
footnote = paste(footnote_contents$general, collapse = " ")
)
}
if (!is.null(footnote_contents$number)) {
footnote_contents$number <- data.frame(
index = as.character(1:length(footnote_contents$number)),
footnote = footnote_contents$number
)
}
if (!is.null(footnote_contents$alphabet)) {
footnote_contents$alphabet <- data.frame(
index = letters[1:length(footnote_contents$alphabet)],
footnote = footnote_contents$alphabet
)
}
if (!is.null(footnote_contents$symbol)) {
footnote_contents$symbol <- data.frame(
index = symbol_index[1:length(footnote_contents$symbol)],
footnote = footnote_contents$symbol
)
}
out <- list()
out$contents <- footnote_contents
out$titles <- footnote_titles
return(out)
}
# HTML
footnote_html <- function(kable_input, footnote_table, footnote_as_chunk) {
kable_attrs <- attributes(kable_input)
kable_xml <- read_kable_as_xml(kable_input)
new_html_footnote <- html_tfoot_maker(footnote_table, footnote_as_chunk)
xml_add_child(kable_xml, new_html_footnote)
out <- as_kable_xml(kable_xml)
attributes(out) <- kable_attrs
return(out)
}
html_tfoot_maker <- function(footnote_table, footnote_as_chunk) {
footnote_types <- names(footnote_table$contents)
footnote_text <- c()
for (i in footnote_types) {
footnote_text <- c(footnote_text, html_tfoot_maker_(
footnote_table$contents[[i]], footnote_table$titles[[i]], i,
footnote_as_chunk))
}
footnote_text <- paste0(
"<tfoot>", paste0(footnote_text, collapse = ""), "</tfoot>"
)
footnote_node <- read_html(footnote_text, options = c("RECOVER", "NOERROR"))
return(xml_child(xml_child(footnote_node, 1), 1))
}
html_tfoot_maker_ <- function(ft_contents, ft_title, ft_type, ft_chunk) {
footnote_text <- apply(ft_contents, 1, function(x) {
paste0('<sup>', x[1], '</sup> ', x[2])
})
if (ft_title != "") {
title_text <- paste0('<strong>', ft_title, '</strong>')
footnote_text <- c(title_text, footnote_text)
}
if (!ft_chunk) {
footnote_text <- paste0(
'<tr><td style="padding: 0; border: 0;" colspan="100%">',
footnote_text, '</td></tr>'
)
} else {
footnote_text <- paste0(
'<tr><td style="padding: 0; border: 0;" colspan="100%">',
paste0(footnote_text, collapse = " "),
'</td></tr>'
)
}
return(footnote_text)
}
# LaTeX
footnote_latex <- function(kable_input, footnote_table, footnote_as_chunk) {
table_info <- magic_mirror(kable_input)
out <- enc2utf8(as.character(kable_input))
if (table_info$tabular == "longtable") {
return()
}
footnote_text <- latex_tfoot_maker(footnote_table, footnote_as_chunk,
table_info$ncol)
out <- sub(table_info$end_tabular,
paste0(footnote_text, "\n\\\\end{", table_info$tabular, "}"),
out)
out <- structure(out, format = "latex", class = "knitr_kable")
attr(out, "kable_meta") <- table_info
return(out)
}
latex_tfoot_maker <- function(footnote_table, footnote_as_chunk, ncol) {
footnote_types <- names(footnote_table$contents)
footnote_text <- c()
for (i in footnote_types) {
footnote_text <- c(footnote_text, latex_tfoot_maker_(
footnote_table$contents[[i]], footnote_table$titles[[i]], i,
footnote_as_chunk, ncol))
}
footnote_text <- paste0(footnote_text, collapse = "\n")
return(footnote_text)
}
latex_tfoot_maker_ <- function(ft_contents, ft_title, ft_type, ft_chunk, ncol) {
footnote_text <- apply(ft_contents, 1, function(x) {
if (x[1] == "") {
x[2]
} else {
paste0('\\\\textsuperscript{', x[1], '} ', x[2])
}
})
if (ft_title != "") {
title_text <- paste0('\\\\textbf{', ft_title, '} ')
footnote_text <- c(title_text, footnote_text)
}
if (!ft_chunk) {
footnote_text <- paste0(
'\\\\multicolumn{', ncol, '}{l}{', footnote_text, '}\\\\\\\\'
)
} else {
footnote_text <- paste0(
'\\\\multicolumn{', ncol, '}{l}{',
paste0(footnote_text, collapse = " "),
'}\\\\\\\\'
)
}
return(footnote_text)
}