fix: resolve locked namespace binding in civilytics_load_fonts() and default theme to transparent background
R-CMD-check / R CMD check (pull_request) Failing after 4m13s
R-CMD-check / R CMD check (pull_request) Failing after 4m13s
- Replace .cv_fonts_loaded <<- TRUE with environment-based state (.cv_state) to avoid 'locked namespace binding' error (#18) - Add force=FALSE argument for idempotent font loading with guard check - Flip theme_civilytics() paper_bg default to FALSE (transparent) (#7) - Update roxygen docs and examples for both changes
This commit is contained in:
@@ -5,32 +5,45 @@ CV_FONT_SANS <- "Inter" # axis text, legends, UI elements
|
||||
CV_FONT_SERIF <- "Source Serif 4" # body prose / editorial long-form
|
||||
CV_FONT_MONO <- "JetBrains Mono" # code, data tables, numeric callouts
|
||||
|
||||
# Internal flag so civilytics_load_fonts() is idempotent within a session.
|
||||
.cv_fonts_loaded <- FALSE
|
||||
# Mutable package state held in an environment so the binding itself stays
|
||||
# locked (R locks all namespace bindings at load time) while the contents
|
||||
# remain writable. See https://adv-r.hadley.nz/environments.html#environments-as-containers
|
||||
.cv_state <- new.env(parent = emptyenv())
|
||||
.cv_state$fonts_loaded <- FALSE
|
||||
|
||||
#' Load Civilytics brand fonts
|
||||
#'
|
||||
#' Downloads Inter and Libre Franklin from Google Fonts via
|
||||
#' [sysfonts::font_add_google()], then calls [showtext::showtext_auto()] so
|
||||
#' that all graphics devices render text with those fonts. This is called
|
||||
#' automatically when the package loads; use this function to retry if the
|
||||
#' initial load failed (e.g., the machine was offline at load time).
|
||||
#' Downloads Inter, Libre Franklin, Source Serif 4 and JetBrains Mono from
|
||||
#' Google Fonts via [sysfonts::font_add_google()], then calls
|
||||
#' [showtext::showtext_auto()] so that all graphics devices render text with
|
||||
#' those fonts. This is called automatically when the package loads; use this
|
||||
#' function to retry if the initial load failed (e.g., the machine was offline
|
||||
#' at load time).
|
||||
#'
|
||||
#' @return Invisibly returns `NULL`.
|
||||
#' Subsequent calls within the same session are no-ops unless `force = TRUE`.
|
||||
#'
|
||||
#' @param force Logical. If `TRUE`, reload fonts even if they were already
|
||||
#' loaded in this session. Default `FALSE`.
|
||||
#'
|
||||
#' @return Invisibly returns `TRUE` if fonts were loaded, `FALSE` if skipped
|
||||
#' (already loaded and `force = FALSE`).
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' civilytics_load_fonts()
|
||||
#' }
|
||||
civilytics_load_fonts <- function() {
|
||||
civilytics_load_fonts <- function(force = FALSE) {
|
||||
if (.cv_state$fonts_loaded && !force) return(invisible(FALSE))
|
||||
|
||||
sysfonts::font_add_google("Inter", family = "Inter")
|
||||
sysfonts::font_add_google("Libre Franklin", family = "Libre Franklin")
|
||||
sysfonts::font_add_google("Source Serif 4", family = "Source Serif 4")
|
||||
sysfonts::font_add_google("JetBrains Mono", family = "JetBrains Mono")
|
||||
showtext::showtext_auto()
|
||||
.cv_fonts_loaded <<- TRUE
|
||||
invisible(NULL)
|
||||
|
||||
.cv_state$fonts_loaded <- TRUE
|
||||
invisible(TRUE)
|
||||
}
|
||||
|
||||
.onLoad <- function(libname, pkgname) {
|
||||
|
||||
@@ -36,10 +36,12 @@
|
||||
#' to [civilytics_colors]`["paper_2"]` (`#F2EDE4`).
|
||||
#' @param grid Character. Which major gridlines to draw: `"y"` (default,
|
||||
#' horizontal only), `"x"` (vertical only), `"both"`, or `"none"`.
|
||||
#' @param paper_bg Logical. If `TRUE` (default), fill the plot and panel
|
||||
#' backgrounds with the warm `paper` color. Set to `FALSE` for a
|
||||
#' transparent background (useful for slides or overlay on colored
|
||||
#' surfaces).
|
||||
#' @param paper_bg Logical. If `TRUE`, fill the plot and panel backgrounds
|
||||
#' with the warm `paper` color (Civilytics cream). Default is `FALSE`
|
||||
#' (transparent) so that figures composite cleanly onto any background.
|
||||
#' Set to `TRUE` for the branded cream canvas. Note: a transparent device
|
||||
#' background (e.g., `dev = "ragg_png"`, `dev.args = list(background =
|
||||
#' "transparent")`) is also needed for fully-transparent PNG exports.
|
||||
#'
|
||||
#' @section Font size hierarchy:
|
||||
#' All text sizes are derived from `font_size` using relative scale factors.
|
||||
@@ -68,7 +70,7 @@
|
||||
#' \dontrun{
|
||||
#' library(ggplot2)
|
||||
#'
|
||||
#' # Default editorial theme
|
||||
#' # Default — transparent background for embedding
|
||||
#' ggplot(mpg, aes(displ, hwy)) +
|
||||
#' geom_point() +
|
||||
#' theme_civilytics()
|
||||
@@ -79,10 +81,10 @@
|
||||
#' scale_color_civilytics() +
|
||||
#' theme_civilytics(grid = "both")
|
||||
#'
|
||||
#' # Transparent background for embedding
|
||||
#' # Branded cream background (opt-in)
|
||||
#' ggplot(mpg, aes(displ, hwy)) +
|
||||
#' geom_point() +
|
||||
#' theme_civilytics(paper_bg = FALSE)
|
||||
#' theme_civilytics(paper_bg = TRUE)
|
||||
#'
|
||||
#' # Larger text for poster or display
|
||||
#' ggplot(mpg, aes(displ, hwy)) +
|
||||
@@ -102,7 +104,7 @@ theme_civilytics <- function(
|
||||
accent = unname(civilytics_colors["ember_600"]),
|
||||
strip_color = unname(civilytics_colors["paper_2"]),
|
||||
grid = c("y", "x", "both", "none"),
|
||||
paper_bg = TRUE) {
|
||||
paper_bg = FALSE) {
|
||||
|
||||
grid <- match.arg(grid)
|
||||
half_line <- font_size / 2
|
||||
|
||||
Reference in New Issue
Block a user