😎 Give your xaringan slides some style
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

709 lines
23KB

  1. #' A Plot Theme for ggplot2 by xaringanthemer
  2. #'
  3. #' @description
  4. #'
  5. #' **Lifecycle:** [Experimental](https://www.tidyverse.org/lifecycle/#experimental).
  6. #'
  7. #' Creates [ggplot2] themes to match the xaringanthemer theme used in the
  8. #' [xaringan] slides that seamlessly matches the "normal" slide colors and
  9. #' styles.
  10. #'
  11. #' @param text_color Color for text and foreground, inherits from `text_color`
  12. #' @param background_color Color for background, inherits from
  13. #' `background_color`
  14. #' @param accent_color Color for titles and accents, inherits from
  15. #' `header_color`
  16. #' @param accent_secondary_color Color for secondary accents, inherits from
  17. #' `text_bold_color`
  18. #' @inheritDotParams theme_xaringan_base
  19. #'
  20. #' @examples
  21. #' if (requireNamespace("ggplot2", quietly = TRUE)) {
  22. #' # Set xaringanthemer theme but save to tempfile
  23. #' style_duo_accent(outfile = tempfile())
  24. #'
  25. #' library(ggplot2)
  26. #' ggplot(iris) +
  27. #' aes(Petal.Length, Petal.Width) +
  28. #' geom_point() +
  29. #' theme_xaringan()
  30. #' }
  31. #'
  32. #' @return A ggplot2 theme
  33. #' @family xaringanthemer ggplot2 themes
  34. #' @export
  35. theme_xaringan <- function(
  36. text_color = NULL,
  37. background_color = NULL,
  38. accent_color = NULL,
  39. accent_secondary_color = NULL,
  40. ...
  41. ) {
  42. requires_xaringanthemer_env()
  43. requires_package(fn = "xaringan_theme")
  44. background_color <- background_color %||% xaringanthemer_env$background_color
  45. text_color <- text_color %||% xaringanthemer_env$text_color
  46. accent_color <- accent_color %||% xaringanthemer_env$header_color
  47. accent_secondary_color <- accent_secondary_color %||% xaringanthemer_env$text_bold_color %||% accent_color
  48. theme_xaringan_base(text_color, background_color,
  49. accent_color = accent_color,
  50. accent_secondary_color = accent_secondary_color,
  51. ...)
  52. }
  53. #' An Inverse Plot Theme for ggplot2 by xaringanthemer
  54. #'
  55. #' @description
  56. #'
  57. #' **Lifecycle:** [Experimental](https://www.tidyverse.org/lifecycle/#experimental).
  58. #'
  59. #' A [ggplot2] xaringanthemer plot theme to seamlessly match the "inverse"
  60. #' [xaringan] slide colors and styles as styled by [xaringanthemer].
  61. #'
  62. #' @param text_color Color for text and foreground, inherits from `text_color`
  63. #' @param background_color Color for background, inherits from
  64. #' `background_color`
  65. #' @param accent_color Color for titles and accents, inherits from
  66. #' `header_color`
  67. #' @param accent_secondary_color Color for secondary accents, inherits from
  68. #' `text_bold_color`
  69. #' @inheritDotParams theme_xaringan_base
  70. #'
  71. #' @examples
  72. #' if (requireNamespace("ggplot2", quietly = TRUE)) {
  73. #' # Set xaringanthemer theme but save to tempfile
  74. #' style_duo_accent(outfile = tempfile())
  75. #'
  76. #' library(ggplot2)
  77. #' ggplot(iris) +
  78. #' aes(Petal.Length, Petal.Width) +
  79. #' geom_point() +
  80. #' theme_xaringan()
  81. #' }
  82. #'
  83. #' @return A ggplot2 theme
  84. #' @family xaringanthemer ggplot2 themes
  85. #' @export
  86. theme_xaringan_inverse <- function(
  87. text_color = NULL,
  88. background_color = NULL,
  89. accent_color = NULL,
  90. accent_secondary_color = NULL,
  91. ...
  92. ) {
  93. requires_xaringanthemer_env()
  94. requires_package(fn = "xaringan_theme")
  95. background_color <- background_color %||% xaringanthemer_env$inverse_background_color
  96. text_color <- text_color %||% xaringanthemer_env$inverse_text_color
  97. accent_color <- accent_color %||% xaringanthemer_env$inverse_header_color
  98. accent_secondary_color <- accent_secondary_color %||% accent_color
  99. theme_xaringan_base(text_color, background_color,
  100. accent_color = accent_color,
  101. accent_secondary_color = accent_secondary_color,
  102. ...)
  103. }
  104. #' The ggplot2 xaringanthemer base plot theme
  105. #'
  106. #' @description
  107. #'
  108. #' **Lifecycle:** [Experimental](https://www.tidyverse.org/lifecycle/#experimental).
  109. #'
  110. #' Provides a base plot theme for [ggplot2] to match the [xaringan] slide theme
  111. #' created by [xaringanthemer]. The theme is designed to create a general plot
  112. #' style from two colors, a `background_color` and a `text_color` (or foreground
  113. #' color). Also accepts an `accent_color` and an `accent_secondary_color` that are
  114. #' [xaringanthemer] is not required for the base theme. Use
  115. #' [theme_xaringan()] or [theme_xaringan_inverse()] in xaringan slides styled by
  116. #' xaringanthemer for a plot theme that matches the slide style.
  117. #'
  118. #' @param text_color Color for text and foreground
  119. #' @param background_color Color for background
  120. #' @param accent_color Color for titles and accents, inherits from
  121. #' `header_color` or `text_color`. Used for the `title` base setting in
  122. #' [ggplot2::theme()], and additionally for setting the `color` or `fill` of
  123. #' [ggplot2] geom defaults.
  124. #' @param accent_secondary_color Color for secondary accents, inherits from
  125. #' `text_bold_color` or `accent_color`. Used only when setting [ggplot2] geom
  126. #' defaults.
  127. #' @param set_ggplot_defaults Should defaults be set for [ggplot2] _geoms_?
  128. #' Defaults to TRUE. To restore ggplot's defaults, or the previously set geom
  129. #' defaults, see [theme_xaringan_restore_defaults()].
  130. #' @param text_font Font to use for text elements, passed to
  131. #' [sysfonts::font_add_google()], if available and `text_font_use_google` is
  132. #' `TRUE`. Inherits from `text_font_family`.
  133. #' @param text_font_use_google Is `text_font` available on [Google
  134. #' Fonts](https://fonts.google.com)?
  135. #' @param text_font_size Base text font size, inherits from `text_font_size`, or
  136. #' defaults to 11.
  137. #' @param title_font Font to use for title elements, passed to
  138. #' [sysfonts::font_add_google()], if available and `title_font_use_google` is
  139. #' `TRUE`. Inherits from `title_font_family`.
  140. #' @param title_font_use_google Is `title_font` available on [Google
  141. #' Fonts](https://fonts.google.com)?
  142. #' @param title_font_size Base text font size, inherits from `title_font_size`,
  143. #' or defaults to 14.
  144. #' @param ... Ignored
  145. #'
  146. #' @examples
  147. #' if (requireNamespace("ggplot2", quietly = TRUE)) {
  148. #' library(ggplot2)
  149. #' ggplot(iris) +
  150. #' aes(Petal.Length, Petal.Width) +
  151. #' geom_point() +
  152. #' theme_xaringan_base(
  153. #' text_color = "#e1e5f2",
  154. #' background_color = "#021c25",
  155. #' accent_color = "#1f7a8c",
  156. #' set_ggplot_defaults = TRUE
  157. #' ) +
  158. #' labs(
  159. #' title = "Basic Iris Plot",
  160. #' subtitle = "+ theme_xaringan_base()",
  161. #' caption = "{xaringanthemer}"
  162. #' )
  163. #'
  164. #' ggplot(iris) +
  165. #' aes(Petal.Length, Petal.Width) +
  166. #' geom_point() +
  167. #' theme_xaringan_base(
  168. #' text_color = "#021c25",
  169. #' background_color = "#e1e5f2",
  170. #' accent_color = "#1f7a8c",
  171. #' set_ggplot_defaults = TRUE
  172. #' ) +
  173. #' labs(
  174. #' title = "Basic Iris Plot",
  175. #' subtitle = "+ theme_xaringan_base()",
  176. #' caption = "{xaringanthemer}"
  177. #' )
  178. #' }
  179. #'
  180. #' @return A ggplot2 theme
  181. #' @family xaringanthemer ggplot2 themes
  182. #' @export
  183. theme_xaringan_base <- function(
  184. text_color,
  185. background_color,
  186. ...,
  187. set_ggplot_defaults = TRUE,
  188. accent_color = NULL,
  189. accent_secondary_color = NULL,
  190. text_font = NULL,
  191. text_font_use_google = NULL,
  192. text_font_size = NULL,
  193. title_font = NULL,
  194. title_font_use_google = NULL,
  195. title_font_size = NULL
  196. ) {
  197. blend <- color_blender(text_color, background_color)
  198. text_font_size <- text_font_size %||% web_to_point(xaringanthemer_env$text_font_size, scale = 1.25) %||% 11
  199. title_font_size <- title_font_size %||% web_to_point(xaringanthemer_env$header_h3_font_size, scale = 0.8) %||% 14
  200. text_font <- if (!is.null(text_font)) {
  201. register_font(text_font, identical(text_font_use_google, TRUE))
  202. } else get_theme_font("text")
  203. title_font <- if (!is.null(title_font)) {
  204. register_font(title_font, identical(title_font_use_google, TRUE))
  205. } else get_theme_font("header")
  206. text_font %||% "sans"
  207. title_font %||% "sans"
  208. if (set_ggplot_defaults) {
  209. accent_color <- accent_color %||% xaringanthemer_env$header_color %||% text_color
  210. accent_secondary_color <- accent_secondary_color %||% xaringanthemer_env$text_bold_color %||% accent_color
  211. theme_xaringan_set_defaults(text_color, background_color, accent_color, accent_secondary_color)
  212. }
  213. ggplot2::theme(
  214. line = ggplot2::element_line(color = blend(0.2)),
  215. rect = ggplot2::element_rect(fill = background_color),
  216. text = ggplot2::element_text(
  217. color = blend(0.1),
  218. family = text_font,
  219. size = text_font_size),
  220. title = ggplot2::element_text(
  221. color = accent_color,
  222. family = title_font,
  223. size = title_font_size),
  224. plot.background = ggplot2::element_rect(
  225. fill = background_color,
  226. color = background_color),
  227. panel.background = ggplot2::element_rect(
  228. fill = background_color,
  229. color = background_color),
  230. panel.grid.major = ggplot2::element_line(
  231. color = blend(0.8),
  232. inherit.blank = TRUE),
  233. panel.grid.minor = ggplot2::element_line(
  234. color = blend(0.9),
  235. inherit.blank = TRUE),
  236. axis.title = ggplot2::element_text(size = title_font_size * 0.8),
  237. axis.ticks = ggplot2::element_line(color = blend(0.8)),
  238. axis.text = ggplot2::element_text(color = blend(0.4)),
  239. legend.key = element_rect(fill="transparent", colour=NA),
  240. plot.caption = ggplot2::element_text(
  241. size = text_font_size * 0.8,
  242. color = blend(0.3))
  243. )
  244. }
  245. #' Set and Restore ggplot2 geom Defaults
  246. #'
  247. #' @description
  248. #'
  249. #' **Lifecycle:** [Experimental](https://www.tidyverse.org/lifecycle/#experimental).
  250. #'
  251. #' Set [ggplot2] _geom_ defaults to match [theme_xaringan()] with
  252. #' `theme_xaringan_set_defaults()` and restore the standard or previously-set
  253. #' defaults with `theme_xaringan_restore_defaults()`. By default,
  254. #' `theme_xaringan_set_defaults()` is run with [theme_xaringan()] or
  255. #' [theme_xaringan_inverse()].
  256. #'
  257. #' @family xaringanthemer ggplot2 themes
  258. #' @inheritParams theme_xaringan
  259. #' @return Invisibly returns a list of the current ggplot2 geom defaults
  260. #' @export
  261. theme_xaringan_set_defaults <- function(
  262. text_color = NULL,
  263. background_color = NULL,
  264. accent_color = text_color,
  265. accent_secondary_color = accent_color,
  266. text_family = NULL
  267. ) {
  268. requires_package("ggplot2")
  269. blend <- color_blender(text_color, background_color)
  270. xaringan_theme_defaults <- list(
  271. "line" = list(color = text_color),
  272. "vline" = list(color = accent_secondary_color),
  273. "hline" = list(color = accent_secondary_color),
  274. "abline" = list(color = accent_secondary_color),
  275. "segment" = list(color = text_color),
  276. "bar" = list(fill = accent_color),
  277. "col" = list(fill = accent_color),
  278. "boxplot" = list(color = text_color),
  279. "contour" = list(color = text_color),
  280. "density" = list(color = text_color,
  281. fill = text_color,
  282. alpha = 0.1),
  283. "dotplot" = list(color = accent_color),
  284. "errorbarh" = list(color = text_color),
  285. "crossbar" = list(color = text_color),
  286. "errorbar" = list(color = text_color),
  287. "linerange" = list(color = text_color),
  288. "pointrange" = list(color = text_color),
  289. "map" = list(color = text_color),
  290. "path" = list(color = text_color),
  291. "line" = list(color = text_color),
  292. "step" = list(color = text_color),
  293. "point" = list(color = accent_color),
  294. "polygon" = list(color = accent_color,
  295. fill = accent_color),
  296. "quantile" = list(color = text_color),
  297. "rug" = list(color = blend(0.5)),
  298. "segment" = list(color = text_color),
  299. "smooth" = list(fill = blend(0.75),
  300. color = accent_secondary_color),
  301. "spoke" = list(color = text_color),
  302. "label" = list(color = text_color,
  303. family = text_family %||% get_theme_font("text")),
  304. "text" = list(color = text_color,
  305. family = text_family %||% get_theme_font("text")),
  306. "rect" = list(fill = text_color),
  307. "tile" = list(fill = text_color),
  308. "violin" = list(fill = text_color),
  309. "sf" = list(color = text_color)
  310. )
  311. geom_names <- setNames(nm = names(xaringan_theme_defaults))
  312. previous_defaults <- lapply(
  313. geom_names,
  314. function(geom) safely_set_geom(geom, xaringan_theme_defaults[[geom]])
  315. )
  316. if (is.null(xaringanthemer_env$old_ggplot_defaults)) {
  317. xaringanthemer_env$old_ggplot_defaults <- previous_defaults
  318. }
  319. invisible(previous_defaults)
  320. }
  321. #' @describeIn theme_xaringan_set_defaults Restore previous or standard [ggplot2] _geom_ defaults.
  322. #' @inheritParams theme_xaringan
  323. #' @return Invisibly returns a list of the current ggplot2 geom defaults
  324. #' @export
  325. xaringan_theme_restore_defaults <- function() {
  326. requires_package("ggplot2")
  327. requires_xaringanthemer_env()
  328. if (is.null(xaringanthemer_env$old_ggplot_defaults)) return(invisible())
  329. old_default <- xaringanthemer_env$old_ggplot_defaults
  330. old_default_not_std <- vapply(old_default, function(x) length(x) > 0, logical(1))
  331. old_default <- old_default[old_default_not_std]
  332. restore_default <- utils::modifyList(xaringanthemer_env$std_ggplot_defaults, old_default)
  333. geom_names <- setNames(nm = names(restore_default))
  334. previous_defaults <- lapply(
  335. geom_names,
  336. function(geom) safely_set_geom(geom, restore_default[[geom]])
  337. )
  338. invisible(previous_defaults)
  339. }
  340. safely_set_geom <- function(geom, new) {
  341. tryCatch({
  342. ggplot2::update_geom_defaults(geom, new)
  343. },
  344. error = function(e) invisible(),
  345. warning = function(w) invisible())
  346. }
  347. # Color Scales ------------------------------------------------------------
  348. #' Xaringan Themer ggplot2 Scales
  349. #'
  350. #' @description
  351. #'
  352. #' **Lifecycle:** [Experimental](https://www.tidyverse.org/lifecycle/#experimental).
  353. #'
  354. #' Color and fill single-color scales for discrete and continuous values,
  355. #' created using the primary accent color of the xaringanthemer styles.
  356. #'
  357. #' @param ... Arguments passed on to the appropriate scale function, one of
  358. #' [colorspace::scale_color_discrete_sequential],
  359. #' [colorspace::scale_color_continuous_sequential],
  360. #' [colorspace::scale_fill_discrete_sequential], or
  361. #' [colorspace::scale_fill_continuous_sequential].
  362. #' @param color A color value, in hex, to override the default color. Otherwise,
  363. #' the primary color of the resulting scale is chosen from the xaringanthemer
  364. #' slide styles.
  365. #' @param inverse If `color` is not supplied and `inverse = TRUE`, a primary
  366. #' color is chosen to work well with the inverse slide styles, namely the
  367. #' value of `inverse_header_color`
  368. #' @param direction Direction of the discrete scale. Use values less than 0 to
  369. #' reverse the direction, e.g. `direction = -1`.
  370. #' @inheritParams colorspace::scale_color_continuous_sequential
  371. #' @param ... Additional arguments passed to [ggplot2::continuous_scale()] or
  372. #' [ggplot2:discrete_scale()].
  373. #' @param aes_type The type of aesthetic to which the scale is being applied.
  374. #' One of "color", "colour", or "fill".
  375. #' @name scale_xaringan
  376. NULL
  377. #' @rdname scale_xaringan
  378. #' @export
  379. scale_xaringan_discrete <- function(
  380. aes_type = c("color", "colour", "fill"),
  381. ...,
  382. color = NULL,
  383. direction = 1,
  384. inverse = FALSE
  385. ) {
  386. aes_type <- match.arg(aes_type)
  387. color <- hex2HCL(get_theme_accent_color(color, inverse))
  388. pal <- function(n) {
  389. colors <- colorspace::sequential_hcl(
  390. n = n,
  391. c1 = color[1, "C"], l1 = color[1, "L"], h1 = color[1, "H"],
  392. rev = direction >= 1
  393. )
  394. }
  395. ggplot2::discrete_scale(aes_type, "manual", pal, ...)
  396. }
  397. #' @rdname scale_xaringan
  398. #' @export
  399. scale_xaringan_fill_discrete <- function(
  400. ..., color = NULL, direction = 1, inverse = FALSE
  401. ) {
  402. scale_xaringan_discrete(
  403. "fill", ..., color = color, direction = direction, inverse = inverse
  404. )
  405. }
  406. #' @rdname scale_xaringan
  407. #' @export
  408. scale_xaringan_color_discrete <- function(
  409. ..., color = NULL, direction = 1, inverse = FALSE
  410. ) {
  411. scale_xaringan_discrete(
  412. "color", ..., color = color, direction = direction, inverse = inverse
  413. )
  414. }
  415. #' @rdname scale_xaringan
  416. #' @export
  417. scale_xaringan_colour_discrete <- scale_xaringan_color_discrete
  418. #' @rdname scale_xaringan
  419. #' @export
  420. scale_xaringan_continuous <- function(
  421. aes_type = c("color", "colour", "fill"),
  422. ..., color = NULL, begin = 0, end = 1, inverse = FALSE
  423. ) {
  424. aes_type <- match.arg(aes_type)
  425. color <- hex2HCL(get_theme_accent_color(color, inverse))
  426. colors <- colorspace::sequential_hcl(
  427. n = 12, c1 = color[1, "C"], l1 = color[1, "L"], h1 = color[1, "H"],
  428. rev = TRUE
  429. )
  430. rescaler <- function(x, ...) {
  431. scales::rescale(x, to = c(begin, end), from = range(x, na.rm = TRUE))
  432. }
  433. ggplot2::continuous_scale(
  434. aes_type, "continuous_sequential",
  435. palette = scales::gradient_n_pal(colors, values = NULL),
  436. rescaler = rescaler,
  437. oob = scales::censor,
  438. ...
  439. )
  440. }
  441. #' @rdname scale_xaringan
  442. #' @export
  443. scale_xaringan_fill_continuous <- function(
  444. ..., color = NULL, begin = 0, end = 1, inverse = FALSE
  445. ) {
  446. scale_xaringan_continuous(
  447. "fill", ..., color = color, begin = begin, end = end, inverse = inverse
  448. )
  449. }
  450. #' @rdname scale_xaringan
  451. #' @export
  452. scale_xaringan_color_continuous <- function(
  453. ..., color = NULL, begin = 0, end = 1, inverse = FALSE
  454. ) {
  455. scale_xaringan_continuous(
  456. "color", ..., color = color, begin = begin, end = end, inverse = inverse
  457. )
  458. }
  459. #' @rdname scale_xaringan
  460. #' @export
  461. scale_xaringan_colour_continuous <- scale_xaringan_color_continuous
  462. get_theme_accent_color <- function(color = NULL, inverse = FALSE) {
  463. color <-
  464. if (!inverse) {
  465. color %||%
  466. xaringanthemer_env[["header_color"]] %||%
  467. xaringanthemer_env[["text_color"]]
  468. } else {
  469. color %||% xaringanthemer_env[["inverse_header_color"]]
  470. }
  471. if (is.null(color)) {
  472. stop(
  473. call. = FALSE,
  474. "No color provided and no default available. ",
  475. "Have you forgotten to use a style function to set the xaringan theme?"
  476. )
  477. }
  478. color
  479. }
  480. blend_colors <- function(x, y, alpha = 0.5) {
  481. x <- colorspace::hex2RGB(x)
  482. y <- colorspace::hex2RGB(y)
  483. z <- colorspace::mixcolor(alpha, x, y)
  484. colorspace::hex(z)
  485. }
  486. color_blender <- function(x, y) function(alpha = 0.5) blend_colors(x, y, alpha)
  487. hex2HCL <- function(x) {
  488. colorspace::coords(as(colorspace::hex2RGB(x), "polarLUV"))
  489. }
  490. # Fonts -------------------------------------------------------------------
  491. get_theme_font <- function(element = c("text", "header", "code")) {
  492. element <- match.arg(element)
  493. element_family <- paste0(element, "_font_family")
  494. element_google <- paste0(element, "_font_google")
  495. element_url <- paste0(element, "_font_url")
  496. family <- xaringanthemer_env[[element_family]]
  497. is_google_font <- !is.null(xaringanthemer_env[[element_google]]) ||
  498. grepl("fonts.google", xaringanthemer_env[[element_url]], fixed = TRUE)
  499. register_font(family, google = is_google_font, fn = sys.calls()[[max(1, length(sys.calls()) - 1)]])
  500. }
  501. register_font <- function(
  502. family,
  503. google = TRUE,
  504. fn = sys.calls()[[max(1, length(sys.calls()) - 1)]][[1]],
  505. ...
  506. ) {
  507. if (is.null(family)) return(NULL)
  508. family <- gsub("['\"]", "", family)
  509. if (!identical(xaringanthemer_env$showtext_auto, TRUE)) {
  510. if (requires_package(pkg = "showtext", fn, required = FALSE)) {
  511. showtext::showtext_auto()
  512. } else return(family)
  513. xaringanthemer_env$showtext_auto <- TRUE
  514. }
  515. if (!requires_package(pkg = "sysfonts", fn, required = FALSE)) {
  516. return(family)
  517. } else if (!family %in% sysfonts::font_families()) {
  518. is_default_font <- family %in% c(
  519. "Roboto", "Source Code Pro", "Yanone Kaffeesatz"
  520. )
  521. if (identical(google, TRUE) || is_default_font) {
  522. tryCatch(
  523. sysfonts::font_add_google(family, ...),
  524. error = function(e) warning(e$message),
  525. warning = function(w) warning(w$message)
  526. )
  527. } else {
  528. warning(paste(
  529. "Please manually register fonts not served by Google Fonts.",
  530. "See `sysfonts::font_add()` for more information."))
  531. }
  532. }
  533. family
  534. }
  535. requires_package <- function(pkg = "ggplot2", fn = "", required = TRUE) {
  536. raise <- if (required) stop else warning
  537. if (!requireNamespace(pkg, quietly = TRUE)) {
  538. msg <- paste0(
  539. "`", pkg, "` is ",
  540. if (required) "required " else "suggested ",
  541. if (fn != "") paste0("by ", fn, "() ")[1],
  542. "but is not installed."
  543. )
  544. raise(msg, call. = FALSE)
  545. invisible(FALSE)
  546. }
  547. invisible(TRUE)
  548. }
  549. requires_xaringanthemer_env <- function() {
  550. if (!exists("xaringanthemer_env") || is.null(xaringanthemer_env$header_color)) {
  551. stop("Please call a xaringanthemer theme function first.")
  552. }
  553. }
  554. #' Get the Value of xaringanthemer Style Setting
  555. #'
  556. #' A helper function to retrieve the value of style settings as set by a
  557. #' xaringanthemer style function, for use in plotting and other circumstances.
  558. #'
  559. #' @section Style Settings:
  560. #' Style settings used by xaringanthemer include:
  561. #'
  562. #' - `background_color`
  563. #' - `background_image`
  564. #' - `background_position`
  565. #' - `background_size`
  566. #' - `blockquote_left_border_color`
  567. #' - `code_font_family`
  568. #' - `code_font_family_fallback`
  569. #' - `code_font_google`
  570. #' - `code_font_size`
  571. #' - `code_font_url`
  572. #' - `code_highlight_color`
  573. #' - `code_inline_background_color`
  574. #' - `code_inline_color`
  575. #' - `code_inline_font_size`
  576. #' - `extra_css`
  577. #' - `extra_fonts`
  578. #' - `footnote_color`
  579. #' - `footnote_font_size`
  580. #' - `footnote_position_bottom`
  581. #' - `header_background_auto`
  582. #' - `header_background_color`
  583. #' - `header_background_content_padding_top`
  584. #' - `header_background_ignore_classes`
  585. #' - `header_background_padding`
  586. #' - `header_background_text_color`
  587. #' - `header_color`
  588. #' - `header_font_family`
  589. #' - `header_font_google`
  590. #' - `header_font_url`
  591. #' - `header_font_weight`
  592. #' - `header_h1_font_size`
  593. #' - `header_h2_font_size`
  594. #' - `header_h3_font_size`
  595. #' - `inverse_background_color`
  596. #' - `inverse_header_color`
  597. #' - `inverse_text_color`
  598. #' - `inverse_text_shadow`
  599. #' - `left_column_selected_color`
  600. #' - `left_column_subtle_color`
  601. #' - `link_color`
  602. #' - `padding`
  603. #' - `table_border_color`
  604. #' - `table_row_border_color`
  605. #' - `table_row_even_background_color`
  606. #' - `text_bold_color`
  607. #' - `text_color`
  608. #' - `text_font_base`
  609. #' - `text_font_family`
  610. #' - `text_font_family_fallback`
  611. #' - `text_font_google`
  612. #' - `text_font_size`
  613. #' - `text_font_url`
  614. #' - `text_font_weight`
  615. #' - `text_slide_number_color`
  616. #' - `text_slide_number_font_size`
  617. #' - `title_slide_background_color`
  618. #' - `title_slide_background_image`
  619. #' - `title_slide_background_position`
  620. #' - `title_slide_background_size`
  621. #' - `title_slide_text_color`
  622. #'
  623. #' @param setting A xaringanthemer style setting
  624. #' @export
  625. theme_xaringan_get_value <- function(setting) {
  626. requires_xaringanthemer_env()
  627. if (length(setting) > 1) {
  628. xaringanthemer_env[setting]
  629. } else {
  630. xaringanthemer_env[[setting]]
  631. }
  632. }
  633. web_to_point <- function(x, px_per_em = 16, scale = 1) {
  634. if (is.null(x)) return(NULL)
  635. if (grepl("pt$", x)) {
  636. return(as.numeric(sub("pt$", "", x)))
  637. } else if (grepl("px$", x)) {
  638. x <- as.numeric(sub("px$", "", x))
  639. return(x * 0.75)
  640. } else if (grepl("em$", x)) {
  641. x <- as.numeric(sub("em$", "", x))
  642. return(x * px_per_em * 0.75)
  643. } else {
  644. return()
  645. }
  646. }