😎 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.

143 lines
3.8KB

  1. #' Add Extra CSS Styles
  2. #'
  3. #' Adds css elements to target `outfile`, typically a xaringanthemer css file.
  4. #' The `css` argument takes a list of CSS classes and definitions (see examples below)
  5. #' and appends CSS rules to `outfile`.
  6. #'
  7. #' @section css list:
  8. #' The `css` input must be a named list of css properties and values within a
  9. #' named list of class identifiers, for example
  10. #' `list(".class-id" = list("css-property" = "value"))`.
  11. #'
  12. #' @param css A named list of CSS definitions each containing a named list
  13. #' of CSS property-value pairs, i.e.
  14. #' `list(".class-id" = list("css-property" = "value"))`
  15. #' @param append If `TRUE` output will be appended to `outfile`; otherwise,
  16. #' it will overwrite the contents of `outfile`.
  17. #' @param heading Heading added above extra CSS. Use `NULL` to disable.
  18. #'
  19. #' @examples
  20. #' style_extra_css(
  21. #' outfile = stdout(),
  22. #' css = list(
  23. #' ".red" = list(color = "red"),
  24. #' ".small" = list("font-size" = "90%"),
  25. #' ".full-width" = list(
  26. #' display = "flex",
  27. #' width = "100%",
  28. #' flex = "1 1 auto"
  29. #' )
  30. #' )
  31. #' )
  32. #' @inheritParams style_xaringan
  33. #' @export
  34. style_extra_css <- function(
  35. css,
  36. outfile = "xaringan-themer.css",
  37. append = TRUE,
  38. heading = "Extra CSS"
  39. ) {
  40. has_heading <- !is.null(heading)
  41. x <- paste0(
  42. if (has_heading) paste0("/* ", heading, " */\n"),
  43. list2css(css)
  44. )
  45. if (append) x <- paste0(if (has_heading) "\n\n" else "\n", x)
  46. if (is.null(outfile)) return(x)
  47. cat(
  48. x,
  49. file = outfile,
  50. append = append,
  51. sep = "\n"
  52. )
  53. invisible(x)
  54. }
  55. #' @inheritParams style_extra_css
  56. #' @keywords internal
  57. list2css <- function(css) {
  58. `%.%` <- function(x, y) paste0(x, y)
  59. error <- NULL
  60. if (is.null(names(css))) {
  61. stop("All elements in `css` list must be named", call. = FALSE)
  62. }
  63. if (purrr::vec_depth(css) != 3) {
  64. stop(
  65. "`css` list must be a named list within a named list, e.g.:\n",
  66. ' list(".class-id" = list("css-property" = "value"))'
  67. )
  68. }
  69. if (any(names(css) == "")) {
  70. not_named <- which(names(css) == "")
  71. if (length(not_named) > 1) {
  72. stop(
  73. call. = FALSE,
  74. "All elements in `css` list must be named. Items ",
  75. paste(not_named, collapse = ", "),
  76. " are unnamed."
  77. )
  78. } else {
  79. stop(
  80. call. = FALSE,
  81. "All elements in `css` list must be named. Item ",
  82. not_named,
  83. " is not named."
  84. )
  85. }
  86. }
  87. child_unnamed <- purrr::map_lgl(purrr::map(css, ~ {
  88. is.null(names(.)) || any(names(.) == "")
  89. }), ~ any(.))
  90. if (any(child_unnamed)) {
  91. has_unnamed <- names(css)[child_unnamed]
  92. msg <- paste(
  93. "All properties of elements in `css` list must be named.",
  94. if (length(has_unnamed) > 1) "Elements" else "Element",
  95. paste(has_unnamed, collapse = ", "),
  96. if (length(has_unnamed) > 1) "have" else "has",
  97. "unnamed property or properties."
  98. )
  99. stop(msg, call. = FALSE)
  100. }
  101. purrr::map_chr(names(css), function(el) {
  102. paste(
  103. sep = "\n",
  104. el %.% " {",
  105. paste(
  106. purrr::map_chr(names(css[[el]]), function(prop) {
  107. " " %.% prop %.% ": " %.% css[[el]][[prop]] %.% ";"
  108. }),
  109. collapse = "\n"
  110. ),
  111. "}"
  112. )
  113. })
  114. }
  115. list2fonts <- function(fonts) {
  116. if (
  117. length(setdiff(names(google_font('fam')), names(fonts))) == 0 &&
  118. !inherits(fonts, "google_font")
  119. ) {
  120. # concatenating a string and a google_font() provides a wacky list
  121. stop(
  122. "Multiple fonts in `extra_fonts` must be specified inside a `list()`.",
  123. call. = FALSE
  124. )
  125. }
  126. if (inherits(fonts, "google_font")) {
  127. fonts <- list(fonts)
  128. }
  129. fonts <- purrr::map_chr(fonts, function(f) {
  130. if (inherits(f, "google_font")) {
  131. f$url
  132. } else if (inherits(f, "character")) {
  133. f
  134. } else {
  135. NA_character_
  136. }
  137. })
  138. paste0("@import url(", fonts[!is.na(fonts)], ");")
  139. }