😎 Give your xaringan slides some style
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

173 lines
6.0KB

  1. force(text_font_family)
  2. force(text_font_weight)
  3. force(text_font_url)
  4. force(text_font_family_fallback)
  5. force(header_font_family)
  6. force(header_font_weight)
  7. force(header_font_url)
  8. force(code_font_family)
  9. force(code_font_url)
  10. force(code_font_family_fallback)
  11. # the defaults are google fonts
  12. is_default <- function(type, suffix) {
  13. # check if font arg value is from xaringanthemer_font_default
  14. var <- paste0(type, "_", suffix)
  15. inherits(
  16. get(var, envir = parent.frame(2), inherits = FALSE),
  17. "xaringanthemer_default"
  18. )
  19. }
  20. for (var in c("text", "header", "code")) {
  21. suffixes <- c("font_family", "font_weight", "font_url")
  22. if (var == "code") suffixes <- setdiff(suffixes, "font_weight")
  23. var_is_google <- all(vapply(suffixes, is_default, logical(1), type = var))
  24. var_is_google <- as.integer(var_is_google)
  25. r_set_font_is_google <- glue::glue("{var}_font_is_google <- {var_is_google}")
  26. eval(parse(text = r_set_font_is_google))
  27. }
  28. # Make sure font names are wrapped in quotes if they have spaces
  29. f_args <- names(formals(sys.function()))
  30. for (var in f_args[grepl("font_family$", f_args)]) {
  31. var_value <- get(var, inherits = FALSE)
  32. if (!is.null(var_value)) {
  33. eval(parse(text = paste0(var, "<-quote_elements_w_spaces(", var, ")")))
  34. }
  35. }
  36. # Warn if base_font_size isn't absolute
  37. css_abs_units <- c("cm", "mm", "Q", "in", "pc", "pt", "px")
  38. if (!grepl(paste(tolower(css_abs_units), collapse = "|"), tolower(base_font_size))) {
  39. warning(
  40. glue::glue(
  41. "Base font size '{base_font_size}' is not in absolute units. ",
  42. "For best results, specify the `base_font_size` using absolute CSS units: ",
  43. "{paste(css_abs_units, collapse = ', ')}"
  44. ),
  45. call. = FALSE,
  46. immediate. = TRUE
  47. )
  48. }
  49. # If certain colors aren't in hexadecimal it may cause problems with theme_xaringan()
  50. # TODO: at some point I'd rather be able to process CSS colors or variables
  51. colors_used_by_theme_xaringan <- list(
  52. background_color = background_color,
  53. text_color = text_color,
  54. header_color = header_color,
  55. text_bold_color = text_bold_color,
  56. inverse_background_color = inverse_background_color,
  57. inverse_text_color = inverse_text_color,
  58. inverse_header_color = inverse_header_color
  59. )
  60. colors_used_by_theme_xaringan <- purrr::discard(colors_used_by_theme_xaringan, is.null)
  61. colors_are_hex <- purrr::map_lgl(colors_used_by_theme_xaringan, check_color_is_hex, throw = NULL)
  62. if (any(!colors_are_hex)) {
  63. colors_better_as_hex <- names(colors_used_by_theme_xaringan)[!colors_are_hex]
  64. colors_better_as_hex <- paste(colors_better_as_hex, collapse = ", ")
  65. warning(
  66. glue::glue("Colors that will be used by `theme_xaringan()` need to be in ",
  67. "hexadecimal format: {colors_better_as_hex}"),
  68. immediate. = TRUE,
  69. call. = FALSE
  70. )
  71. }
  72. # Use font_..._google args to overwrite font args
  73. for (var in f_args[grepl("font_google$", f_args)]) {
  74. gf <- eval(parse(text = var))
  75. if (is.null(gf)) next
  76. if (!inherits(gf, "google_font")) {
  77. stop("`", var, "` must be set using `google_font()`.")
  78. }
  79. group <- strsplit(var, "_")[[1]][1]
  80. if (group == "text") {
  81. text_font_family <- quote_elements_w_spaces(gf$family)
  82. text_font_weight <- gf$weights %||% "normal"
  83. if (grepl(",", text_font_weight)) {
  84. # Use first font weight if multiple are imported
  85. text_font_weight <- substr(text_font_weight, 1, regexpr(",", text_font_weight)[1] - 1)
  86. }
  87. text_font_url <- gf$url
  88. } else {
  89. eval(parse(text = paste0(group, "_font_family <- quote_elements_w_spaces(gf$family)")))
  90. eval(parse(text = paste0(group, "_font_url <- gf$url")))
  91. }
  92. eval(parse(text = paste0(group, "_font_is_google <- 1")))
  93. }
  94. extra_font_imports <- if (is.null(extra_fonts)) "" else list2fonts(extra_fonts)
  95. extra_font_imports <- paste(extra_font_imports, collapse = "\n")
  96. # convert NA arguments to NULL
  97. for (var in f_args) {
  98. val <- eval(parse(text = var))
  99. if (is.null(val)) next
  100. val <- val[!is.na(val)]
  101. is_na <- length(val) == 0
  102. if (is_na) assign(var, NULL, envir = sys.frame(sys.nframe()))
  103. }
  104. # prepare variables for template
  105. body_font_family <- paste(c(text_font_family, text_font_family_fallback, text_font_base), collapse = ", ")
  106. background_size_fallback <- if (is.null(background_position)) "cover" else "100%"
  107. background_size <- background_image %??% (background_size %||% background_size_fallback)
  108. title_slide_background_size <- title_slide_background_size %||% (
  109. title_slide_background_image %??% "cover"
  110. )
  111. table_row_even_background_color <- table_row_even_background_color %||% background_color
  112. # stash theme settings in package env
  113. lapply(f_args, function(n) assign(n, get(n), envir = xaringanthemer_env))
  114. for (font_is_google in paste0(c("text", "code", "header"), "_font_is_google")) {
  115. assign(
  116. font_is_google,
  117. get(font_is_google, inherits = FALSE) == 1,
  118. envir = xaringanthemer_env
  119. )
  120. }
  121. xaringanthemer_version <- utils::packageVersion("xaringanthemer")
  122. # prepare header background object
  123. needs_leading_dot <- !grepl("^\\.", header_background_ignore_classes)
  124. header_background_ignore_classes[needs_leading_dot] <- paste0(
  125. ".",
  126. header_background_ignore_classes[needs_leading_dot]
  127. )
  128. header_background_ignore_classes <- purrr::map(
  129. header_background_ignore_classes,
  130. ~ list(class = .)
  131. )
  132. if (is.null(header_background_padding)) {
  133. slide_padding <- css_get_padding(padding)
  134. header_background_padding <- paste(
  135. "2rem", slide_padding$right, "1.5rem", slide_padding$left
  136. )
  137. }
  138. header_background <- list(
  139. auto = header_background_auto,
  140. background_color = header_background_color,
  141. text_color = header_background_text_color,
  142. padding = header_background_padding,
  143. content_padding_top = header_background_content_padding_top,
  144. ignore = header_background_ignore_classes
  145. )
  146. colors <- prepare_colors(colors)
  147. tf <- system.file("resources", "template.css", package = "xaringanthemer")
  148. template <- readLines(tf, warn = FALSE)
  149. template <- paste(template, collapse = "\n")
  150. x <- whisker::whisker.render(template)
  151. if (!is.null(extra_css)) {
  152. x <- c(x, style_extra_css(extra_css, outfile = NULL))
  153. }
  154. if (is.null(outfile)) {
  155. return(x)
  156. }
  157. writeLines(x, con = outfile)
  158. invisible(outfile)