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

- 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:
2026-08-01 02:07:09 -04:00
parent 0ef0f310e2
commit e257180f15
2 changed files with 34 additions and 19 deletions
+24 -11
View File
@@ -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) {