From 422f24cfc1ecc292e2af795917946928f31b2f36 Mon Sep 17 00:00:00 2001 From: Alexander Rossell Hayes Date: Tue, 17 Sep 2024 13:47:23 -0400 Subject: [PATCH 1/9] fix(md): convert `text` to character before applying `from_markdown` class --- NEWS.md | 2 ++ R/helpers.R | 3 ++- tests/testthat/test-fmt_markdown.R | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 72f387f512..f1a1a3c7ec 100644 --- a/NEWS.md +++ b/NEWS.md @@ -59,6 +59,8 @@ * Improved footnote rendering in Quarto with `fmt_markdown()` (@olivroy, #1773) +* Fixed an issue where `md()` and `fmt_markdown()` would render factors as their numeric levels rather than their text labels (@rossellhayes, #1883). + # gt 0.11.0 ## New features diff --git a/R/helpers.R b/R/helpers.R index eda11c1289..e7e071090b 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -70,7 +70,8 @@ #' #' @export md <- function(text) { - + # Ensure input is text (e.g. for factors) + text <- as.character(text) # Apply the `from_markdown` class class(text) <- "from_markdown" text diff --git a/tests/testthat/test-fmt_markdown.R b/tests/testthat/test-fmt_markdown.R index eddeb5a629..004a382d21 100644 --- a/tests/testthat/test-fmt_markdown.R +++ b/tests/testthat/test-fmt_markdown.R @@ -235,3 +235,23 @@ test_that("LaTeX formulas render correctly in HTML", { # Take a snapshot of `gt_tbl` expect_snapshot_html(gt_tbl) }) + +test_that("fmt_markdown() works correctly with factors", { + + text <- "This is Markdown *text*." + + # Create a `gt_tbl` object with `gt()` + # and a tibble; format all columns with + # `fmt_markdown()` + tab <- + dplyr::tibble(column_1 = factor(text)) %>% + gt() %>% + fmt_markdown(columns = everything()) + + # Compare output of cell to the expected HTML output strings + expect_equal( + (tab %>% + render_formats_test(context = "html"))[["column_1"]][[1]], + "This is Markdown text." + ) +}) From 09199dbb150688ded81e024da32ae0c9520b3d4a Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:15:47 -0400 Subject: [PATCH 2/9] Restyle existing R code --- R/opts.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/opts.R b/R/opts.R index 7cdd52ff18..0f9bad6b33 100644 --- a/R/opts.R +++ b/R/opts.R @@ -1635,7 +1635,9 @@ opt_table_font <- function( if (!is.null(weight)) { - if (is.numeric(weight)) weight <- as.character(weight) + if (is.numeric(weight)) { + weight <- as.character(weight) + } data <- tab_options( From 45db793d1dfaf97b33e88ad9d63a0f84d5407068 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:17:06 -0400 Subject: [PATCH 3/9] Add the `size` and `color` args to `opt_table_font()` --- R/opts.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/opts.R b/R/opts.R index 0f9bad6b33..aaf74d60fe 100644 --- a/R/opts.R +++ b/R/opts.R @@ -1582,8 +1582,10 @@ opt_table_font <- function( data, font = NULL, stack = NULL, + size = NULL, weight = NULL, style = NULL, + color = NULL, add = TRUE ) { From 8fe27e3e39947490fbf70a3561703039d564472b Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:17:33 -0400 Subject: [PATCH 4/9] Add documentation for new arguments --- R/opts.R | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/R/opts.R b/R/opts.R index aaf74d60fe..b8852ca420 100644 --- a/R/opts.R +++ b/R/opts.R @@ -1456,6 +1456,17 @@ opt_table_outline <- function( #' A name that is representative of a font stack (obtained via internally via #' the [system_fonts()] helper function). If provided, this new stack will #' replace any defined fonts and any `font` values will be prepended. +#' +#' @param size *Text size* +#' +#' `scalar` // *default:* `NULL` (`optional`) +#' +#' The text size for the entire table can be set by providing a `size` value. +#' Can be specified as a single-length character vector with units of pixels +#' (e.g., `12px`) or as a percentage (e.g., `80%`). If provided as a +#' single-length numeric vector, it is assumed that the value is given in +#' units of pixels. The [px()] and [pct()] helper functions can also be used +#' to pass in numeric values and obtain values as pixel or percentage units. #' #' @param style *Text style* #' @@ -1472,6 +1483,13 @@ opt_table_outline <- function( #' `"normal"`, `"bold"`, `"lighter"`, `"bolder"`, or, a numeric value between #' `1` and `1000`, inclusive. Please note that typefaces have varying support #' for the numeric mapping of weight. +#' +#' @param color *Text color* +#' +#' `scalar` // *default:* `NULL` (`optional`) +#' +#' The `color` option defines the text color used throughout the table. A +#' color name or a hexadecimal color code should be provided. #' #' @param add *Add to existing fonts* #' From be9ea7fb010b8ef58650ff951e4dac51d9859437 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:17:56 -0400 Subject: [PATCH 5/9] Implement new args through `tab_options()` calls --- R/opts.R | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/R/opts.R b/R/opts.R index b8852ca420..50cd1025e6 100644 --- a/R/opts.R +++ b/R/opts.R @@ -1653,6 +1653,16 @@ opt_table_font <- function( ) } + if (!is.null(size)) { + + data <- + tab_options( + data = data, + table.font.size = size + ) + + } + if (!is.null(weight)) { if (is.numeric(weight)) { @@ -1681,6 +1691,15 @@ opt_table_font <- function( ) } + if (!is.null(color)) { + + data <- + tab_options( + data = data, + table.font.color = color + ) + } + data } From a1251174457c99c3606f8d536bd4a1cb41317afe Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:18:08 -0400 Subject: [PATCH 6/9] Modify text in example --- R/opts.R | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/R/opts.R b/R/opts.R index 50cd1025e6..0156f7c5de 100644 --- a/R/opts.R +++ b/R/opts.R @@ -1540,9 +1540,8 @@ opt_table_outline <- function( #' #' Use a subset of the [`sp500`] dataset to create a small **gt** table. We'll #' use [fmt_currency()] to display a dollar sign for the first row of monetary -#' values. Then, set a larger font size for the table and use the -#' `"Merriweather"` font (from *Google Fonts*, via [google_font()]) with two -#' system font fallbacks (`"Cochin"` and the generic `"serif"`). +#' values. The `"Merriweather"` font (from *Google Fonts*, via [google_font()]) +#' with two system font fallbacks (`"Cochin"` and the generic `"serif"`). #' #' ```r #' sp500 |> From e679737eafd4852f9ace82c2fc315fb7bb51a5e1 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:18:10 -0400 Subject: [PATCH 7/9] Update opt_table_font.Rd --- man/opt_table_font.Rd | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/man/opt_table_font.Rd b/man/opt_table_font.Rd index f802c01a7b..32c5b92ec5 100644 --- a/man/opt_table_font.Rd +++ b/man/opt_table_font.Rd @@ -8,8 +8,10 @@ opt_table_font( data, font = NULL, stack = NULL, + size = NULL, weight = NULL, style = NULL, + color = NULL, add = TRUE ) } @@ -37,6 +39,17 @@ A name that is representative of a font stack (obtained via internally via the \code{\link[=system_fonts]{system_fonts()}} helper function). If provided, this new stack will replace any defined fonts and any \code{font} values will be prepended.} +\item{size}{\emph{Text size} + +\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) + +The text size for the entire table can be set by providing a \code{size} value. +Can be specified as a single-length character vector with units of pixels +(e.g., \verb{12px}) or as a percentage (e.g., \verb{80\%}). If provided as a +single-length numeric vector, it is assumed that the value is given in +units of pixels. The \code{\link[=px]{px()}} and \code{\link[=pct]{pct()}} helper functions can also be used +to pass in numeric values and obtain values as pixel or percentage units.} + \item{weight}{\emph{Text weight} \verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) @@ -53,6 +66,13 @@ for the numeric mapping of weight.} An option to modify the text style. Can be one of either \code{"normal"}, \code{"italic"}, or \code{"oblique"}.} +\item{color}{\emph{Text color} + +\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) + +The \code{color} option defines the text color used throughout the table. A +color name or a hexadecimal color code should be provided.} + \item{add}{\emph{Add to existing fonts} \verb{scalar} // \emph{default:} \code{TRUE} @@ -121,9 +141,8 @@ multiple computer systems. Any of the following keywords can be used: Use a subset of the \code{\link{sp500}} dataset to create a small \strong{gt} table. We'll use \code{\link[=fmt_currency]{fmt_currency()}} to display a dollar sign for the first row of monetary -values. Then, set a larger font size for the table and use the -\code{"Merriweather"} font (from \emph{Google Fonts}, via \code{\link[=google_font]{google_font()}}) with two -system font fallbacks (\code{"Cochin"} and the generic \code{"serif"}). +values. The \code{"Merriweather"} font (from \emph{Google Fonts}, via \code{\link[=google_font]{google_font()}}) +with two system font fallbacks (\code{"Cochin"} and the generic \code{"serif"}). \if{html}{\out{
}}\preformatted{sp500 |> dplyr::slice(1:10) |> From 2badbf0c5100f333bfaf4ec5d7d07d1f80380915 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 17 Sep 2024 21:18:22 -0400 Subject: [PATCH 8/9] Add tests for `opt_table_font()` --- tests/testthat/test-opts.R | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/testthat/test-opts.R b/tests/testthat/test-opts.R index a90114780e..40d45ab256 100644 --- a/tests/testthat/test-opts.R +++ b/tests/testthat/test-opts.R @@ -340,6 +340,22 @@ test_that("opt_table_font() sets the correct options", { "font-weight: bold;", "font-style: italic;" ) %>% expect_true() + + # Expect that the `size` option is passed as a CSS value + tbl %>% + opt_table_font(size = px(32)) %>% + compile_scss() %>% + as.character() %>% + html_fragment_within("font-size: 32px;") %>% + expect_true() + + # Expect that the `color` option is passed as a CSS value + tbl %>% + opt_table_font(color = "#228B23") %>% + compile_scss() %>% + as.character() %>% + html_fragment_within("color: #228B23;") %>% + expect_true() # Expect that adding a font from the Google Fonts service # is possible with the `google_font()` function From 87298717782ca5fe70633149ef7f5ac088fd8980 Mon Sep 17 00:00:00 2001 From: olivroy Date: Tue, 24 Sep 2024 15:40:26 -0400 Subject: [PATCH 9/9] Misc performance improvements for nanoplots / `vec_*()` functions. --- R/dt_spanners.R | 2 +- R/fmt.R | 8 ++++---- R/format_data.R | 4 ++++ R/format_vec.R | 2 +- R/helpers.R | 2 -- R/utils_render_common.R | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/R/dt_spanners.R b/R/dt_spanners.R index 308b1fdb6f..01e9380285 100644 --- a/R/dt_spanners.R +++ b/R/dt_spanners.R @@ -35,7 +35,7 @@ dt_spanners_set <- function(data, spanners) { dt_spanners_init <- function(data) { spanners <- - dplyr::tibble( + vctrs::data_frame( # Column names that are part of the spanner vars = list(), # The spanner label diff --git a/R/fmt.R b/R/fmt.R index d7cb99ec87..647e6ad00d 100644 --- a/R/fmt.R +++ b/R/fmt.R @@ -552,7 +552,7 @@ format_num_to_str <- function( system = c("intl", "ind") ) { - system <- rlang::arg_match(system) + system <- rlang::arg_match0(system, c("intl", "ind")) # If this hardcoding is ever to change, then we need to # modify the regexes below @@ -604,7 +604,7 @@ format_num_to_str <- function( # Remove `-` for any signed zeros returned by `formatC()` x_str_signed_zero <- grepl("^(-0|-0\\.0*?)$", x_str) - x_str[x_str_signed_zero] <- gsub("-", "", x_str[x_str_signed_zero]) + x_str[x_str_signed_zero] <- gsub("-", "", x_str[x_str_signed_zero], fixed = TRUE) # If a trailing decimal mark is to be retained (not the # default option but sometimes desirable), affix the `dec_mark` @@ -633,7 +633,7 @@ format_num_to_str <- function( FUN = insert_seps_ind ) - decimal_str <- rep("", length(x_str_numeric)) + decimal_str <- rep_len("", length(x_str_numeric)) decimal_str[has_decimal] <- gsub("^.*?(\\..*)", "\\1", x_str_numeric[has_decimal]) @@ -670,7 +670,7 @@ format_num_to_str_c <- function( system = c("intl", "ind") ) { - system <- rlang::arg_match(system) + system <- rlang::arg_match0(system, c("intl", "ind")) format_num_to_str( x = x, diff --git a/R/format_data.R b/R/format_data.R index 01e7cf053b..273daec6da 100644 --- a/R/format_data.R +++ b/R/format_data.R @@ -9667,6 +9667,10 @@ fmt_markdown <- function( rows = {{ rows }}, fns = list( html = function(x) { + # Ensure input is x (e.g. for factors) + if (!is.character(x)) { + x <- as.character(x) + } process_text(md(x), context = "html") }, latex = function(x) { diff --git a/R/format_vec.R b/R/format_vec.R index 112ccb9c97..565985bf07 100644 --- a/R/format_vec.R +++ b/R/format_vec.R @@ -3341,7 +3341,7 @@ vec_fmt_markdown <- function( } gt_one_col <- function(x) { - gt(dplyr::tibble(x = x), auto_align = FALSE, process_md = FALSE) + gt(data.frame(x = x, stringsAsFactors = FALSE), auto_align = FALSE, process_md = FALSE, groupname_col = NULL) } # Similar as `stop_if_not_vector()` if `valid_classes` is not supplied. diff --git a/R/helpers.R b/R/helpers.R index e7e071090b..43d6c95749 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -70,8 +70,6 @@ #' #' @export md <- function(text) { - # Ensure input is text (e.g. for factors) - text <- as.character(text) # Apply the `from_markdown` class class(text) <- "from_markdown" text diff --git a/R/utils_render_common.R b/R/utils_render_common.R index 8b7b99d92b..85ca62afe5 100644 --- a/R/utils_render_common.R +++ b/R/utils_render_common.R @@ -471,7 +471,7 @@ perform_col_merge <- function(data, context) { } ) - glue_src_data <- stats::setNames(glue_src_data, seq_len(length(glue_src_data))) + glue_src_data <- stats::setNames(glue_src_data, seq_along(glue_src_data)) glued_cols <- as.character(glue_gt(glue_src_data, pattern))