😎 Give your xaringan slides some style
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

144 linhas
3.9KB

  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(str_wrap(
  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(str_wrap(
  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(str_wrap(
  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(str_wrap(msg), call. = FALSE)
  100. }
  101. x <- purrr::imap_chr(css, function(rules, selector) {
  102. paste(
  103. sep = "\n",
  104. selector %.% " {",
  105. paste(
  106. purrr::imap_chr(rules, function(value, prop) {
  107. " " %.% prop %.% ": " %.% value %.% ";"
  108. }),
  109. collapse = "\n"
  110. ),
  111. "}"
  112. )
  113. })
  114. unname(x)
  115. }
  116. list2fonts <- function(fonts) {
  117. if (
  118. length(setdiff(names(google_font('fam')), names(fonts))) == 0 &&
  119. !inherits(fonts, "google_font")
  120. ) {
  121. # concatenating a string and a google_font() provides a wacky list
  122. stop(
  123. "Multiple fonts in `extra_fonts` must be specified inside a `list()`.",
  124. call. = FALSE
  125. )
  126. }
  127. if (inherits(fonts, "google_font")) {
  128. fonts <- list(fonts)
  129. }
  130. fonts <- purrr::map_chr(fonts, function(f) {
  131. if (inherits(f, "google_font")) {
  132. f$url
  133. } else if (inherits(f, "character")) {
  134. f
  135. } else {
  136. NA_character_
  137. }
  138. })
  139. paste0("@import url(", fonts[!is.na(fonts)], ");")
  140. }