😎 Give your xaringan slides some style
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 satır
3.5KB

  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. #'
  18. #' @examples
  19. #' style_extra_css(
  20. #' outfile = stdout(),
  21. #' css = list(
  22. #' ".red" = list(color = "red"),
  23. #' ".small" = list("font-size" = "90%"),
  24. #' ".full-width" = list(
  25. #' display = "flex",
  26. #' width = "100%",
  27. #' flex = "1 1 auto"
  28. #' )
  29. #' )
  30. #' )
  31. #' @inheritParams style_xaringan
  32. #' @export
  33. style_extra_css <- function(css, outfile = "xaringan-themer.css", append = TRUE) {
  34. cat(
  35. "\n\n/* Extra CSS */",
  36. list2css(css),
  37. file = outfile,
  38. append = TRUE,
  39. sep = "\n"
  40. )
  41. }
  42. #' @inheritParams style_extra_css
  43. #' @keywords internal
  44. list2css <- function(css) {
  45. `%.%` <- function(x, y) paste0(x, y)
  46. error <- NULL
  47. if (is.null(names(css))) {
  48. stop("All elements in `css` list must be named", call. = FALSE)
  49. }
  50. if (purrr::vec_depth(css) != 3) {
  51. stop(
  52. "`css` list must be a named list within a named list, e.g.:\n",
  53. ' list(".class-id" = list("css-property" = "value"))'
  54. )
  55. }
  56. if (any(names(css) == "")) {
  57. not_named <- which(names(css) == "")
  58. if (length(not_named) > 1) {
  59. stop(
  60. call. = FALSE,
  61. "All elements in `css` list must be named. Items ",
  62. paste(not_named, collapse = ", "),
  63. " are unnamed."
  64. )
  65. } else {
  66. stop(
  67. call. = FALSE,
  68. "All elements in `css` list must be named. Item ",
  69. not_named,
  70. " is not named."
  71. )
  72. }
  73. }
  74. child_unnamed <- purrr::map_lgl(purrr::map(css, ~ {
  75. is.null(names(.)) || any(names(.) == "")
  76. }), ~ any(.))
  77. if (any(child_unnamed)) {
  78. has_unnamed <- names(css)[child_unnamed]
  79. msg <- paste(
  80. "All properties of elements in `css` list must be named.",
  81. if (length(has_unnamed) > 1) "Elements" else "Element",
  82. paste(has_unnamed, collapse = ", "),
  83. if (length(has_unnamed) > 1) "have" else "has",
  84. "unnamed property or properties."
  85. )
  86. stop(msg, call. = FALSE)
  87. }
  88. purrr::map_chr(names(css), function(el) {
  89. paste(
  90. sep = "\n",
  91. el %.% " {",
  92. paste(
  93. purrr::map_chr(names(css[[el]]), function(prop) {
  94. " " %.% prop %.% ": " %.% css[[el]][[prop]] %.% ";"
  95. }),
  96. collapse = "\n"
  97. ),
  98. "}"
  99. )
  100. })
  101. }
  102. list2fonts <- function(fonts) {
  103. if (
  104. length(setdiff(names(google_font('fam')), names(fonts))) == 0 &&
  105. !inherits(fonts, "google_font")
  106. ) {
  107. # concatenating a string and a google_font() provides a wacky list
  108. stop(
  109. "Multiple fonts in `extra_fonts` must be specified inside a `list()`.",
  110. call. = FALSE
  111. )
  112. }
  113. if (inherits(fonts, "google_font")) {
  114. fonts <- list(fonts)
  115. }
  116. fonts <- purrr::map_chr(fonts, function(f) {
  117. if (inherits(f, "google_font")) {
  118. f$url
  119. } else if (inherits(f, "character")) {
  120. f
  121. } else {
  122. NA_character_
  123. }
  124. })
  125. paste0("@import url(", fonts[!is.na(fonts)], ");")
  126. }