From 0806c621c33c2d5b84c5a43acd112ad6982bcce8 Mon Sep 17 00:00:00 2001 From: bd-karen-byron Date: Sat, 2 Nov 2024 15:09:26 -0400 Subject: [PATCH] capturing show footnote on every page in a clean pull --- R/footnote.R | 84 +++++++++++++++---- man/footnote.Rd | 4 + tests/visual_tests/footnote_latex_perm.Rmd | 58 +++++++++++++ .../footnote_latex_perm_child.Rmd | 36 ++++++++ 4 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 tests/visual_tests/footnote_latex_perm.Rmd create mode 100644 tests/visual_tests/footnote_latex_perm_child.Rmd diff --git a/R/footnote.R b/R/footnote.R index 723661df..8a99f05d 100644 --- a/R/footnote.R +++ b/R/footnote.R @@ -27,6 +27,8 @@ #' @param fixed_small_size T/F When you want to keep the footnote small after #' specifying large font size with the kable_styling() (e.g. ideal font for headers #' and table content with small font in footnotes). +#' @param show_every_page T/F To make footnotes print at bottom of all pages for +#' long tables. Only applies to pdf longtables. #' @param general_title Section header for general footnotes. Default is #' "Note: ". #' @param number_title Section header for number footnotes. Default is "". @@ -64,6 +66,7 @@ footnote <- function(kable_input, escape = TRUE, threeparttable = FALSE, fixed_small_size = FALSE, + show_every_page = FALSE, general_title = "Note: ", number_title = "", alphabet_title = "", @@ -127,7 +130,7 @@ footnote <- function(kable_input, } if (kable_format == "latex") { return(footnote_latex(kable_input, footnote_table, footnote_as_chunk, - threeparttable, fixed_small_size)) + threeparttable, fixed_small_size, show_every_page)) } } @@ -265,9 +268,12 @@ html_tfoot_maker_ <- function(ft_contents, ft_title, ft_type, ft_chunk) { # LaTeX footnote_latex <- function(kable_input, footnote_table, footnote_as_chunk, - threeparttable, fixed_small_size) { + threeparttable, fixed_small_size, show_every_page) { + fn_regexp <- fn_text <- longtable_start <- longtable_text <- NULL + table_info <- magic_mirror(kable_input) out <- solve_enc(kable_input) + fn_regexp <- fn_text <- longtable_start <- longtable_text <- NULL footnote_text <- latex_tfoot_maker(footnote_table, footnote_as_chunk, table_info$ncol, threeparttable) @@ -284,12 +290,16 @@ footnote_latex <- function(kable_input, footnote_table, footnote_as_chunk, paste0("\\\\end{", table_info$tabular, "}\n\\\\end{ThreePartTable}"), out) - if (table_info$booktabs) { - out <- sub(bottomrule_regexp, "\\1\n\\\\insertTableNotes", out) - } else { - out <- sub("\\\\hline\n\\\\end\\{longtable\\}", - "\\\\hline\n\\\\insertTableNotes\n\\\\end\\{longtable\\}", - out) + if (!show_every_page) { + if (table_info$booktabs) { + out <- sub(bottomrule_regexp, + "\\1\n\\\\insertTableNotes", + out) + } else if (!show_every_page) { + out <- sub("\\\\hline\n\\\\end\\{longtable\\}", + "\\\\hline\n\\\\insertTableNotes\n\\\\end\\{longtable\\}", + out) + } } } else { if (table_info$tabular == "tabu") { @@ -309,13 +319,59 @@ footnote_latex <- function(kable_input, footnote_table, footnote_as_chunk, out) } } else { - if (table_info$booktabs) { - out <- sub(bottomrule_regexp, - paste0("\\1\n", footnote_text), out) + if(!show_every_page) { + if (table_info$booktabs) { + out <- sub(bottomrule_regexp, + paste0("\\1\n", footnote_text), + out) + } else { + out <- sub(table_info$end_tabular, + paste0(footnote_text, "\n\\\\end{", table_info$tabular, "}"), + out) + } + } + } + + if (table_info$tabular == "longtable" & show_every_page) { + fn_regexp <- ifelse(threeparttable, "\\\\insertTableNotes", + footnote_text) + fn_text <- gsub("\\\\", "\\", fn_regexp, fixed = TRUE) + if(is.null(table_info$repeat_header_latex)) { + # need full \begin{longtable} command + # table_info valign2 ok but align missing vertical lines + longtable_start <- sub(".*\\\\begin\\{longtable\\}", + "\\\\begin\\{longtable\\}", out) + longtable_text <- sub("\n.*", "", longtable_start) + out <- sub(longtable_text, + paste(longtable_text, fn_text, "\n\\endfoot\n"), + out, fixed = TRUE) } else { - out <- sub(table_info$end_tabular, - paste0(footnote_text, "\n\\\\end{", table_info$tabular, "}"), - out) + if(!table_info$booktabs){ + out <- sub( + "\\\\endhead\\n", + paste0("\\\\endhead\n", + fn_regexp, "\n\\\\endfoot\n", + fn_regexp, "\n\\\\endlastfoot\n"), + out) + } else { + if (grepl( # no repeat_header_continued in kable_styling + "\\\\endhead\\n\\n\\\\endfoot", + out)) { + out <- sub( + "\\\\endhead\\n\\n\\\\endfoot", + paste0("\\\\endhead\n\\\\midrule\n", fn_regexp, "\n\\\\endfoot"), + out) + } else { # repeat_header_continued in kable_styling + out <- sub( + "\\\\endfoot", + paste0(fn_regexp, "\n\\\\endfoot"), + out) + } + out <- sub( + "\\\\endlastfoot", + paste0(fn_regexp, "\n\\\\endlastfoot"), + out) + } } } diff --git a/man/footnote.Rd b/man/footnote.Rd index 4f066faa..cf1a9501 100644 --- a/man/footnote.Rd +++ b/man/footnote.Rd @@ -15,6 +15,7 @@ footnote( escape = TRUE, threeparttable = FALSE, fixed_small_size = FALSE, + show_every_page = FALSE, general_title = "Note: ", number_title = "", alphabet_title = "", @@ -56,6 +57,9 @@ long paragraph of footnotes.} specifying large font size with the kable_styling() (e.g. ideal font for headers and table content with small font in footnotes).} +\item{show_every_page}{T/F To make footnotes print at bottom of all pages for +long tables. Only applies to pdf longtables.} + \item{general_title}{Section header for general footnotes. Default is "Note: ".} diff --git a/tests/visual_tests/footnote_latex_perm.Rmd b/tests/visual_tests/footnote_latex_perm.Rmd new file mode 100644 index 00000000..d5e0a7b6 --- /dev/null +++ b/tests/visual_tests/footnote_latex_perm.Rmd @@ -0,0 +1,58 @@ +--- +title: "footnote_perm" +author: "Byron" +date: "9/11/2024" +output: pdf_document +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set(echo = !TRUE) +devtools::load_all() +# library(kableExtra) + +dat <- data.frame( + Col1 = LETTERS[rep(1:26, each = 2)], + Col2 = letters[rep(1:26, 2)], + n = 0:51 +) +# "\\tnote{1} is TPT only +names(dat)[3] <- paste0(names(dat)[3], footnote_marker_number(1)) +``` + + +```{r permute, results='asis'} +# Define new environment +latex_opt <- c("basic", "repeat_header") # test basic to show doesn't cause trouble +is_bt <- c(FALSE, TRUE) +is_tpt <- c(FALSE, TRUE) +is_cont_at_btm <- c(FALSE, TRUE) # only shows for booktabs +is_every <- c(FALSE, TRUE) + +child_env <- new.env() +for(i_latex_opt in seq_along(latex_opt)){ + for(i_bt in seq_along(is_bt)){ + for(i_tpt in seq_along(is_tpt)){ + for(i_is_cont_at_btm in seq_along(is_cont_at_btm)){ + for(i_every in seq_along(is_every)){ + child_env$i_latex_opt <- i_latex_opt + child_env$i_bt <- i_bt + child_env$i_tpt <- i_tpt + child_env$i_is_cont_at_btm <- i_is_cont_at_btm + child_env$i_every <- i_every + + # knit the document and save the character output to an object + res <- knitr::knit_child( + "footnote_latex_perm_child.Rmd", + envir = child_env, + quiet = TRUE + ) + + # Cat the object to make it render in your main document + cat(res, sep = "\n") + } + } + } + } +} +``` + diff --git a/tests/visual_tests/footnote_latex_perm_child.Rmd b/tests/visual_tests/footnote_latex_perm_child.Rmd new file mode 100644 index 00000000..5ba0d08c --- /dev/null +++ b/tests/visual_tests/footnote_latex_perm_child.Rmd @@ -0,0 +1,36 @@ +--- +output: + pdf_document +--- +```{r results='asis'} +# i_latex_opt <- i_bt <- i_tpt <- i_is_cont_at_btm <- i_every <- 2 +use_lab <- paste("lab", i_latex_opt, i_bt, i_tpt, + i_is_cont_at_btm, i_every, sep = "-") +``` + +### `r use_lab` +Permutations +\vspace{-10pt} + +* latex option: `r latex_opt[i_latex_opt]` +* booktab: `r is_bt[i_bt]` +* TPT: `r is_tpt[i_tpt]` +* continue on bottom: `r is_cont_at_btm[i_is_cont_at_btm]` +* every page: `r is_every[i_every]` + + +```{r results='asis'} +dat |> + kbl(format = "latex", caption = "Table caption", + label = use_lab, escape = FALSE, + booktabs = is_bt[i_bt], longtable = TRUE) |> + kable_styling( + latex_options = latex_opt[i_latex_opt], + repeat_header_continued = is_cont_at_btm[i_is_cont_at_btm]) |> + footnote( + number = c("footnote on colname"), + threeparttable = is_tpt[i_tpt], + show_every_page = is_every[i_every]) +``` + +\clearpage