diff --git a/DESCRIPTION b/DESCRIPTION
index f9ec010..1a297da 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: xaringanBuilder
Title: Functions For Building Xaringan Slides To Different Outputs
-Version: 0.0.5.9000
+Version: 0.0.6.9000
Authors@R:
c(person(given = "John",
family = "Helveston",
@@ -30,7 +30,8 @@ Imports:
pagedown,
progress,
rmarkdown,
- xaringan
+ xaringan,
+ zip
Suggests:
chromote,
officer,
diff --git a/NAMESPACE b/NAMESPACE
index 9807f46..a845f71 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -4,6 +4,7 @@ export(build_all)
export(build_gif)
export(build_html)
export(build_pdf)
+export(build_png)
export(build_pptx)
export(build_social)
export(build_thumbnail)
diff --git a/NEWS.md b/NEWS.md
index 6cac36d..3b72f8a 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,16 +1,17 @@
-# xaringanBuilder 0.0.5
+# xaringanBuilder 0.0.6
+
+* Depreciated `build_thumbnail()` and added `build_png()` as an improved replacement.
+* `build_png()` fixes part of issue #15 so that the png aspect ratio matches that of the xaringan slides.
+* `build_png()` also has options for changing the png density and building more than just the title slide (can build pngs of some or all slides using the `slides` argument).
+* All documentation and examples updated to match new features.
+* New example slides made to demonstrate new features.
-## Summary of larger updates:
+# xaringanBuilder 0.0.5
* Major improvements to how paths are handled by adding the build_paths() function (not exported). Now you can use a url to build to any output types except for social and html (which both require starting from the Rmd file).
* Added build_to_pdf() function (not exported) as an internal helper to build from a Rmd or html file to the pdf.
-
-## Summary of smaller updates:
-
* Added `assert_chrome_installed()` for issue #12
-## Bugs
-
# xaringanBuilder 0.0.4
* Added `build_social()` for making a png of the first slides sized for sharing on social media.
diff --git a/R/all.R b/R/all.R
index ec1e8ce..2b6b32d 100644
--- a/R/all.R
+++ b/R/all.R
@@ -1,14 +1,14 @@
#' Build xaringan slides to multiple outputs.
#'
#' Build xaringan slides to multiple outputs. Options are `"html"`, `"pdf"`,
-#' `"gif"`, `"pptx"`, `"thumbnail"`, and `"social"`. See individual
-#' build_..() functions for details about each output type.
+#' `"gif"`, `"pptx"`, `"png"`, and `"social"`. See each individual
+#' build_*() function for details about each output type.
#' @param input Path to Rmd file of xaringan slides.
#' @param include A vector of the different output types to build. Options are
-#' `"html"`, `"pdf"`, `"gif"`, `"pptx"`, `"thumbnail"`, and `"social"`.
-#' Defaults to `c("html", "pdf", "gif", "pptx", "thumbnail", "social")`.
+#' `"html"`, `"pdf"`, `"gif"`, `"pptx"`, `"png"`, and `"social"`.
+#' Defaults to `c("html", "pdf", "gif", "pptx", "png", "social")`.
#' @param exclude A vector of the different output types to NOT build. Options
-#' are `"html"`, `"pdf"`, `"gif"`, `"pptx"`, `"thumbnail"`, and `"social"`.
+#' are `"html"`, `"pdf"`, `"gif"`, `"pptx"`, `"png"`, and `"social"`.
#' Defaults to `NULL`, in which case all all output types are built.
#' @param complex_slides For "complex" slides (e.g. slides with panelsets or
#' other html widgets or advanced features), set `complex_slides = TRUE`.
@@ -21,25 +21,32 @@
#' @param delay Seconds of delay between advancing to and printing
#' a new slide. Only used if `complex_slides = TRUE` or `partial_slides =
#' TRUE`.
+#' @param density Resolution of the resulting png files used in the png, gif,
+#' and pptx output types file. Defaults to `"72x72"`.
+#' @param slides A vector of the slide number(s) to return for the png output.
+#' Defaults to `1`, returning only the title slide. You can get a zip
+#' file of all the slides as pngs by setting `slides = "all"`).
+#' @param fps Frames per second of the gif file.
#' @export
#' @examples
#' \dontrun{
#' # Builds every output by default
#' build_all("slides.Rmd")
#'
-#' # Choose which output types to include
+#' # Both of these build html, pdf, and gif outputs
#' build_all("slides.Rmd", include = c("html", "pdf", "gif"))
-#'
-#' # Choose which output types to exclude
-#' build_all("slides.Rmd", exclude = c("pptx", "thumbnail"))
+#' build_all("slides.Rmd", exclude = c("pptx", "png", "social"))
#' }
build_all <- function(
input,
- include = c("html", "pdf", "gif", "pptx", "thumbnail", "social"),
+ include = c("html", "pdf", "gif", "pptx", "png", "social"),
exclude = NULL,
complex_slides = FALSE,
partial_slides = FALSE,
- delay = 1
+ delay = 1,
+ density = "72x72",
+ slides = 1,
+ fps = 1
) {
# Check that input file has the correct extension
assert_path_ext(input, "rmd")
@@ -47,14 +54,6 @@ build_all <- function(
# Build input and output paths
paths <- build_paths(input, output_file = NULL)
- include <- match.arg(include, several.ok = TRUE)
- do_htm <- ("html" %in% include) && (! "html" %in% exclude)
- do_pdf <- ("pdf" %in% include) && (! "pdf" %in% exclude)
- do_gif <- ("gif" %in% include) && (! "gif" %in% exclude)
- do_ppt <- ("pptx" %in% include) && (! "pptx" %in% exclude)
- do_thm <- ("thumbnail" %in% include) && (! "thumbnail" %in% exclude)
- do_soc <- ("social" %in% include) && (! "social" %in% exclude)
-
# Build hierarchy:
#
# Rmd
@@ -63,38 +62,52 @@ build_all <- function(
# |
# |--> html
# |
- # |--> thumbnail (png)
- # |
# |--> pdf
# |
- # |--> gif
- # |
- # |--> pptx
+ # |--> png
+ # |
+ # |--> gif
+ # |
+ # |--> pptx
#
# currently calling a step out of order will create the intermediate steps
# if at some point intermediate files are removed if not requested, the
# logic here will need to be changed.
- if (do_gif && (!fs::file_exists(paths$input$pdf) || do_htm)) {
- # to make a gif we need the PDF file
- # or if we update the HTML, we should also update the PDF for the gif
- do_pdf <- TRUE
- }
- if (do_ppt && (!fs::file_exists(paths$input$pdf) || do_htm)) {
- # to make a pptx we need the PDF file
- # or if we update the HTML, we should also update the PDF for the pptx
- do_pdf <- TRUE
+ include <- match.arg(include, several.ok = TRUE)
+ do_soc <- ("social" %in% include) && (! "social" %in% exclude)
+ do_htm <- ("html" %in% include) && (! "html" %in% exclude)
+ do_pdf <- ("pdf" %in% include) && (! "pdf" %in% exclude)
+ do_png <- ("png" %in% include) && (! "png" %in% exclude)
+ do_gif <- ("gif" %in% include) && (! "gif" %in% exclude)
+ do_ppt <- ("pptx" %in% include) && (! "pptx" %in% exclude)
+
+ if (!fs::file_exists(paths$input$pdf) || do_htm) {
+ # If the PDF doesn't exist or we're updating the html file,
+ # then we need to also update the PDF if we are going to
+ # built to png, gif, or pptx outputs
+ if (do_png | do_gif | do_ppt) {
+ do_pdf <- TRUE
+ }
}
- if ((do_pdf || do_thm) && !fs::file_exists(paths$input$html)) {
- # to make a PDF or thumbnail we need the html file
+
+ if (do_pdf && !fs::file_exists(paths$input$html)) {
+ # to make a PDF, we need the html file
do_htm <- TRUE
}
# Do each step in order to ensure updates propagate
# (or we use the current version of the required build step)
- if (do_soc) build_social(paths$input$rmd, paths$output$social)
- if (do_htm) build_html(paths$input$rmd, paths$output$html)
- if (do_thm) build_thumbnail(paths$input$html, paths$output$thumbnail)
+ if (do_soc) {
+ build_social(
+ input = paths$input$rmd,
+ output_file = paths$output$social)
+ }
+ if (do_htm) {
+ build_html(
+ input = paths$input$rmd,
+ output_file = paths$output$html)
+ }
if (do_pdf) {
build_pdf(
input = paths$input$html,
@@ -103,8 +116,27 @@ build_all <- function(
partial_slides = partial_slides,
delay = delay)
}
- if (do_gif) build_gif(paths$input$pdf, paths$output$gif)
- if (do_ppt) build_pptx(paths$input$pdf, paths$output$pptx)
+ if (do_png) {
+ build_png(
+ input = paths$input$pdf,
+ output_file = paths$output$png,
+ density = density,
+ slides = slides
+ )
+ }
+ if (do_gif) {
+ build_gif(
+ input = paths$input$pdf,
+ output_file = paths$output$gif,
+ density = density,
+ fps = fps)
+ }
+ if (do_ppt) {
+ build_pptx(
+ input = paths$input$pdf,
+ output_file = paths$output$pptx,
+ density = density)
+ }
invisible(input)
}
diff --git a/R/gif.R b/R/gif.R
index a6a8c5d..ed246b9 100644
--- a/R/gif.R
+++ b/R/gif.R
@@ -2,11 +2,12 @@
#'
#' Build xaringan slides as a gif file. The function builds to the pdf and
#' then converts it to a gif.
-#' @param input Path to a Rmd, html, or pdf file, or a url of xaringan slides.
+#' @param input Path to a Rmd file, html file, pdf file, or a url.
#' If the input is a url to xaringan slides on a website, you must provide the
#' full url ending in ".html".
#' @param output_file Name of the output gif file.
-#' @param density Resolution of the resulting gif file.
+#' @param density Resolution of the resulting gif file. Defaults to
+#' `"72x72"`.
#' @param fps Frames per second of the resulting gif file.
#' @param complex_slides For "complex" slides (e.g. slides with panelsets or
#' other html widgets or advanced features), set `complex_slides = TRUE`.
@@ -22,10 +23,11 @@
#' @export
#' @examples
#' \dontrun{
-#' # Build gif from Rmd, html, or pdf file
+#' # Build gif from Rmd, html, pdf, or url
#' build_gif("slides.Rmd")
#' build_gif("slides.html")
#' build_gif("slides.pdf")
+#' build_gif("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
#' }
build_gif <- function(
input,
diff --git a/R/pdf.R b/R/pdf.R
index e2aa344..9cf1344 100644
--- a/R/pdf.R
+++ b/R/pdf.R
@@ -23,12 +23,10 @@
#' @export
#' @examples
#' \dontrun{
-#' # Build a pdf from a Rmd or html file
+#' # Build pdf from Rmd, html, or url
#' build_pdf("slides.Rmd")
#' build_pdf("slides.html")
-#'
-#' # Build a pdf from a url
-#' build_pdf("http://www.mysite.com/myslides.html")
+#' build_pdf("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
#'
#' # Build a pdf with partial (continuation) slides
#' build_pdf("slides.Rmd", partial_slides = TRUE)
@@ -81,15 +79,6 @@ build_pdf <- function(
}
}
-#' Print "simple" xaringan slides to PDF
-#'
-#' Prints "simple" xaringan slides - those without panelsets or other html
-#' widgets or advanced features, and also slides without partial slides.
-#'
-#' @param input Path to Rmd or html file of xaringan slides.
-#' @param output_file The name of the output file. If `NULL` (the default) then
-#' the output filename will be based on filename for the input file.
-#' If a filename is provided, a path to the output file can also be provided.
build_pdf_simple <- function(input, output_file = NULL) {
print_build_status(input, output_file)
pagedown::chrome_print(
@@ -101,21 +90,6 @@ build_pdf_simple <- function(input, output_file = NULL) {
# in v0.0.2. He also posted it on his blog here:
# https://www.garrickadenbuie.com/blog/print-xaringan-chromote/
-#' Print "complex" xaringan slides to PDF
-#'
-#' Prints "complex" xaringan slides (e.g. slides with panelsets or other html
-#' widgets or advanced features) to a PDF file. Requires a local installation
-#' of Chrome.
-#'
-#' @param input Path to Rmd or html file of xaringan slides.
-#' @param output_file The name of the output file. If `NULL` (the default) then
-#' the output filename will be based on filename for the input file.
-#' If a filename is provided, a path to the output file can also be provided.
-#' @param partial_slides Should partial (continuation) slides be
-#' included in the output? If `FALSE`, the default, only the complete slide
-#' is included in the PDF.
-#' @param delay Seconds of delay between advancing to and printing
-#' a new slide.
build_pdf_complex <- function(input, output_file, partial_slides, delay) {
if (!requireNamespace("chromote", quietly = TRUE)) {
stop("`chromote` is required: devtools::install_github('rstudio/chromote')")
diff --git a/R/png.R b/R/png.R
new file mode 100644
index 0000000..d1bda5a
--- /dev/null
+++ b/R/png.R
@@ -0,0 +1,135 @@
+#' Build xaringan slides as png file(s).
+#'
+#' Build png image(s) of xaringan slides. The function builds to the pdf and
+#' then converts it into png files of each slide. The slide numbers defined
+#' by the `slides` argument are saved (defaults to `1`, returning only the
+#' title slide). If `length(slides) > 1`, it will return the png files in a
+#' zip file. You can also get a zip file of all the slides as pngs by setting
+#' `slides = "all"`).
+#' @param input Path to a Rmd file, html file, pdf file, or a url.
+#' If the input is a url to xaringan slides on a website, you must provide the
+#' full url ending in ".html".
+#' @param output_file Name of the output png or zip file.
+#' @param density Resolution of the resulting gif file. Defaults to
+#' `"72x72"`.
+#' @param slides A vector of the slide number(s) to return. Defaults to `1`,
+#' returning only the title slide. You can also get a zip file of all the
+#' slides as pngs by setting `slides = "all"`).
+#' @param complex_slides For "complex" slides (e.g. slides with panelsets or
+#' other html widgets or advanced features), set `complex_slides = TRUE`.
+#' Defaults to `FALSE`. This will use the {chromote} package to iterate through
+#' the slides at a pace set by the `delay` argument. Requires a local
+#' installation of Chrome.
+#' @param partial_slides Should partial (continuation) slides be
+#' included in the output? If `FALSE`, the default, only the complete slide
+#' is included in the PDF.
+#' @param delay Seconds of delay between advancing to and printing
+#' a new slide. Only used if `complex_slides = TRUE` or `partial_slides =
+#' TRUE`.
+#' @export
+#' @examples
+#' \dontrun{
+#' # By default, a png of only the first slide is built
+#' build_png("slides.Rmd")
+#' build_png("slides.html")
+#' build_png("slides.pdf")
+#' build_png("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
+#'
+#' # Build zip file of multiple or all slides
+#' build_png("slides.pdf", slides = c(1, 3, 5))
+#' build_png("slides.pdf", slides = "all")
+#' }
+build_png <- function(
+ input,
+ output_file = NULL,
+ density = "72x72",
+ slides = 1,
+ complex_slides = FALSE,
+ partial_slides = FALSE,
+ delay = 1
+) {
+ # Check input and output files have correct extensions
+ assert_io_paths(
+ input, c("rmd", "html", "pdf"),
+ output_file, c("png", "zip")
+ )
+
+ # Build input and output paths
+ paths <- build_paths(input, output_file)
+
+ # Build html and / or pdf (if input is not pdf)
+ if (!test_path_ext(input, "pdf")) {
+ build_to_pdf(input, paths, complex_slides, partial_slides, delay)
+ }
+
+ # Build png from pdf
+ print_build_status(paths$input$pdf, paths$output$png)
+ pdf <- magick::image_read(paths$input$pdf, density = density)
+ pngs <- magick::image_convert(pdf, 'png')
+ if (length(slides) > 1) {
+ zip_pngs(pngs, slides, paths$output$zip)
+ } else if (slides == "all") {
+ slides <- seq(length(pngs))
+ zip_pngs(pngs, slides, paths$output$zip)
+ } else {
+ magick::image_write(pngs[slides], paths$output$png)
+ }
+}
+
+zip_pngs <- function(pngs, slides, output_file) {
+ png_paths <- c()
+ png_names <- c()
+ temp_folder <- tempdir()
+ png_root <- fs::path_ext_set(fs::path_file(output_file), "png")
+ for (slide in slides) {
+ png_name <- append_to_file_path(png_root, paste0("_", slide))
+ png_path <- magick::image_write(
+ pngs[slide], fs::path(temp_folder, png_name))
+ png_paths <- c(png_paths, png_path)
+ png_names <- c(png_names, png_name)
+ }
+ zip::zip(output_file, files = png_names, root = temp_folder)
+}
+
+#' Build png thumbnail image of first slide.
+#'
+#' Build png thumbnail image of first xaringan slide. Requires a local
+#' installation of Chrome.
+#' @param input Path to a Rmd file or html file / url of xaringan slides. If
+#' the input is a url to xaringan slides on a website, you must provide the
+#' full url ending in ".html".
+#' @param output_file Name of the output png file.
+#' @export
+#' @examples
+#' \dontrun{
+#' # Build first slide thumbnail from Rmd or html file
+#' build_thumbnail("slides.Rmd")
+#' build_thumbnail("slides.html")
+#' }
+build_thumbnail <- function(input, output_file = NULL) {
+ # v0.0.5
+ .Deprecated("build_png")
+
+ # Check if Chrome is installed
+ assert_chrome_installed()
+
+ # Check input and output files have correct extensions
+ assert_io_paths(input, c("rmd", "html"), output_file, "png")
+
+ # Build input and output paths
+ paths <- build_paths(input, output_file)
+
+ # Build html (if input is rmd)
+ if (test_path_ext(input, "rmd")) {
+ build_html(paths$input$rmd, paths$output$html)
+ }
+
+ # Build png from html
+ input <- paths$input$html
+ output_file <- paths$output$thumbnail
+ print_build_status(input, output_file)
+ pagedown::chrome_print(
+ input = input,
+ output = output_file,
+ format = "png")
+}
diff --git a/R/pptx.R b/R/pptx.R
index e3111bf..b77c40e 100644
--- a/R/pptx.R
+++ b/R/pptx.R
@@ -1,12 +1,14 @@
#' Build xaringan slides as pptx file.
#'
#' Build xaringan slides as a pptx file. The function builds to the pdf and
-#' then inserts a png image of each slide as a new slide in a pptx file.
-#' @param input Path to a Rmd, html, or pdf file, or a url of xaringan slides.
+#' then converts it into png images that are inserted on each slide in the
+#' pptx file.
+#' @param input Path to a Rmd file, html file, pdf file, or a url.
#' If the input is a url to xaringan slides on a website, you must provide the
#' full url ending in ".html".
#' @param output_file Name of the output pptx file.
-#' @param density Resolution of the resulting pptx file.
+#' @param density Resolution of the resulting gif file. Defaults to
+#' `"72x72"`.
#' @param complex_slides For "complex" slides (e.g. slides with panelsets or
#' other html widgets or advanced features), set `complex_slides = TRUE`.
#' Defaults to `FALSE`. This will use the {chromote} package to iterate through
@@ -21,10 +23,11 @@
#' @export
#' @examples
#' \dontrun{
-#' # Build gif from Rmd, html, or pdf file
+#' # Build pptx from Rmd, html, pdf, or url
#' build_pptx("slides.Rmd")
#' build_pptx("slides.html")
#' build_pptx("slides.pdf")
+#' build_pptx("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
#' }
build_pptx <- function(
input,
diff --git a/R/social.R b/R/social.R
index fd036b3..127d0fa 100644
--- a/R/social.R
+++ b/R/social.R
@@ -14,7 +14,7 @@
#' @examples
#' \dontrun{
#' # Build png image of first xaringan slide from Rmd file
-#' # for sharing on social media
+#' # sized for sharing on social media
#' build_social("slides.Rmd")
#' }
#'
diff --git a/R/thumbnail.R b/R/thumbnail.R
deleted file mode 100644
index 0810a36..0000000
--- a/R/thumbnail.R
+++ /dev/null
@@ -1,40 +0,0 @@
-#' Build png thumbnail image of first slide.
-#'
-#' Build png thumbnail image of first xaringan slide. Requires a local
-#' installation of Chrome.
-#' @param input Path to a Rmd file or html file / url of xaringan slides. If
-#' the input is a url to xaringan slides on a website, you must provide the
-#' full url ending in ".html".
-#' @param output_file Name of the output png file.
-#' @export
-#' @examples
-#' \dontrun{
-#' # Build first slide thumbnail from Rmd or html file
-#' build_thumbnail("slides.Rmd")
-#' build_thumbnail("slides.html")
-#' }
-build_thumbnail <- function(input, output_file = NULL) {
-
- # Check if Chrome is installed
- assert_chrome_installed()
-
- # Check input and output files have correct extensions
- assert_io_paths(input, c("rmd", "html"), output_file, "png")
-
- # Build input and output paths
- paths <- build_paths(input, output_file)
-
- # Build html (if input is rmd)
- if (test_path_ext(input, "rmd")) {
- build_html(paths$input$rmd, paths$output$html)
- }
-
- # Build png from html
- input <- paths$input$html
- output_file <- paths$output$thumbnail
- print_build_status(input, output_file)
- pagedown::chrome_print(
- input = input,
- output = output_file,
- format = "png")
-}
diff --git a/R/utils.R b/R/utils.R
index 88823d4..ac9d0a1 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -60,12 +60,11 @@ build_paths <- function(input, output_file = NULL) {
output_pdf <- fs::path_ext_set(output_root, "pdf")
output_gif <- fs::path_ext_set(output_root, "gif")
output_pptx <- fs::path_ext_set(output_root, "pptx")
+ output_zip <- fs::path_ext_set(output_root, "zip")
output_png <- fs::path_ext_set(output_root, "png")
- output_thumbnail <- output_png
output_social <- output_png
- # Append "_thumbnail" and "_social" to png outputs
+ # Append "_social" to png outputs
if (is.null(output_file)) {
- output_thumbnail <- append_to_file_path(output_png, "_thumbnail")
output_social <- append_to_file_path(output_png, "_social")
}
@@ -82,7 +81,8 @@ build_paths <- function(input, output_file = NULL) {
pdf = output_pdf,
gif = output_gif,
pptx = output_pptx,
- thumbnail = output_thumbnail,
+ zip = output_zip,
+ png = output_png,
social = output_social
)
))
@@ -105,12 +105,6 @@ append_to_file_path <- function(path, s) {
)
}
-pdf_to_pngs <- function(input, density) {
- pdf <- magick::image_read(input, density = density)
- pngs <- magick::image_convert(pdf, 'png')
- return(pngs)
-}
-
print_build_status <- function(input, output_file) {
cli::cli_process_start(
"Building {.file {fs::path_file(output_file)}} from {.path {fs::path_file(input)}}",
@@ -118,6 +112,12 @@ print_build_status <- function(input, output_file) {
)
}
+pdf_to_pngs <- function(input, density) {
+ pdf <- magick::image_read(input, density = density)
+ pngs <- magick::image_convert(pdf, 'png')
+ return(pngs)
+}
+
build_to_pdf <- function(
input,
paths,
diff --git a/README.Rmd b/README.Rmd
index df94608..3a00fef 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -31,8 +31,8 @@ Build xaringan slides to multiple output formats:
- pdf
- gif
- pptx
-- thumbnail - png of first slide (useful for Youtube thumbnail)
-- social - png of first slide sized for social media sharing (e.g. Twitter)
+- png (convert some or all slides to png files; useful for generating Youtube thumbnails, for example)
+- social: png image of first slide sized for social media sharing (e.g. Twitter)
## Installation
@@ -45,11 +45,19 @@ remotes::install_github("jhelvy/xaringanBuilder")
## Usage
+The xaringan Rmd files used in all examples below can be found [here](https://github.com/jhelvy/xaringanBuilder/tree/master/inst/example)
+
```
library(xaringanBuilder)
```
-The xaringan Rmd files used in all examples below can be found [here](https://github.com/jhelvy/xaringanBuilder/tree/master/inst/example)
+### Input - Output
+
+All `build_**()` functions use the `input` and `output_file` arguments.
+
+The `input` argument is required and can be a full or local path to the input file (a Rmd, html, or pdf file), or a url to a set of xaringan slides on the web.
+
+The `output_file` argument is optional. It can be a full or local path to the output file, and it must end in an appropriate extension (e.g. `slides.gif` for `build_gif()`). If it is not provided, the output file name will be determined based on the `input` argument.
### Build HTML
@@ -61,23 +69,25 @@ build_html("slides.Rmd")
### Build PDF
-Build a pdf file from a Rmd or html file, or a url to slides:
+Input can be a Rmd file, html file, or url:
```
build_pdf("slides.Rmd")
build_pdf("slides.html")
-build_pdf("http://www.mysite.com/myslides.html")
+build_pdf("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
```
+**Note**: Building the PDF requires a local installation of Google Chrome
+
### Build GIF
-Build a gif file from a Rmd, html, or pdf file, or a url to slides:
+Input can be a Rmd file, html file, pdf file, or url:
```
build_gif("slides.Rmd")
build_gif("slides.html")
build_gif("slides.pdf")
-build_gif("http://www.mysite.com/myslides.html")
+build_gif("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
```
Example:
@@ -86,30 +96,40 @@ Example:
### Build PPTX
-Build a pptx file from a Rmd, html or pdf file, or a url to slides. The pptx file contains slides of png images of each rendered xaringan slide:
+Creates a pptx file where each slide contains a png image of each xaringan slide. While you won't be able to edit the xaringan content from Powerpoint, you can at least annotate it.
+
+(See the [slidex](https://github.com/datalorax/slidex) package by @datalorax to do the opposite: pptx --> xaringan!)
+
+Input can be a Rmd file, html file, pdf file, or url:
```
build_pptx("slides.Rmd")
build_pptx("slides.html")
build_pptx("slides.pdf")
-build_pptx("http://www.mysite.com/myslides.html")
+build_pptx("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
```
-(See the [slidex](https://github.com/datalorax/slidex) package by @datalorax to do the opposite: pptx --> xaringan!)
+### Build PNG
-### Build Thumbnail
+Build png image(s) of some or all slides. Useful for generating Youtube thumbnails, for example.
-Build a "thumbnail" png image of the first slide from a Rmd or html file, or a url to slides (useful for Youtube thumbnail):
+Input can be a Rmd file, html file, pdf file, or url:
```
-build_thumbnail("slides.Rmd")
-build_thumbnail("slides.html")
-build_thumbnail("http://www.mysite.com/myslides.html")
+# By default, a png of only the first slide is built
+build_png("slides.Rmd")
+build_png("slides.html")
+build_png("slides.pdf")
+build_png("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
+
+# Build zip file of multiple or all slides
+build_png("slides.pdf", slides = c(1, 3, 5))
+build_png("slides.pdf", slides = "all")
```
Example:
-
+
### Build Social
@@ -119,6 +139,8 @@ Build a png of the first slide from a Rmd file. Image is sized for sharing on so
build_social("slides.Rmd")
```
+**Note**: This option requires the [chromote](https://github.com/rstudio/chromote) and [pdftools](https://github.com/ropensci/pdftools) packages.
+
Example:
@@ -128,7 +150,8 @@ Example:
Use `build_all()` to build all output types from a Rmd file:
```
-build_all("slides.Rmd") # Builds every output by default
+# Builds every output by default
+build_all("slides.Rmd")
```
Use the `include` or `exclude` arguments to control which output types to include or exclude:
@@ -136,12 +159,12 @@ Use the `include` or `exclude` arguments to control which output types to includ
```
# Both of these build html, pdf, and gif outputs
build_all("slides.Rmd", include = c("html", "pdf", "gif"))
-build_all("slides.Rmd", exclude = c("pptx", "thumbnail", "social"))
+build_all("slides.Rmd", exclude = c("pptx", "png", "social"))
```
## "Complex" slides
-"Complex" slides are slides that contain [panelsets](https://pkg.garrickadenbuie.com/xaringanExtra/#/panelset) or other html widgets / advanced features that might not render well as a pdf. To render these, set `complex_slides = TRUE` in `build_pdf()`, `build_gif()`, `build_pptx()`, or `build_all()`.
+"Complex" slides are slides that contain [panelsets](https://pkg.garrickadenbuie.com/xaringanExtra/#/panelset) or other html widgets / advanced features that might not render well as a pdf. To render these, set `complex_slides = TRUE` in `build_pdf()`, `build_png()`, `build_gif()`, `build_pptx()`, or `build_all()`.
For example:
@@ -150,11 +173,11 @@ build_pdf("slides_complex.Rmd", complex_slides = TRUE)
build_pdf("slides_complex.html", complex_slides = TRUE)
```
-**Note**: This option requires a local installation of Google Chrome as well as the [chromote](https://github.com/rstudio/chromote) package.
+**Note**: This option requires the [chromote](https://github.com/rstudio/chromote) and [pdftools](https://github.com/ropensci/pdftools) packages.
## Partial / incremental slides
-For pdf, gif, and pptx output types, if you want to build a new slide for each increment on [incremental slides](https://slides.yihui.org/xaringan/incremental.html#1), set `partial_slides = TRUE` in `build_pdf()`, `build_gif()`, `build_pptx()`, or `build_all()`.
+For pdf, gif, and pptx output types, if you want to build a new slide for each increment on [incremental slides](https://slides.yihui.org/xaringan/incremental.html#1), set `partial_slides = TRUE` in `build_pdf()`, `build_png()`, `build_gif()`, `build_pptx()`, or `build_all()`.
For example:
@@ -163,7 +186,7 @@ build_pdf("slides.Rmd", partial_slides = TRUE)
build_pdf("slides.html", partial_slides = TRUE)
```
-**Note**: This option requires a local installation of Google Chrome as well as the [chromote](https://github.com/rstudio/chromote) package.
+**Note**: This option requires the [chromote](https://github.com/rstudio/chromote) and [pdftools](https://github.com/ropensci/pdftools) packages.
## Build hierarchy
@@ -175,19 +198,19 @@ Rmd
|--> social (png)
|
|--> html
- |
- |--> thumbnail (png)
|
|--> pdf
|
- |--> gif
- |
- |--> pptx
+ |--> png
+ |
+ |--> gif
+ |
+ |--> pptx
```
## Local Chrome installation requirement
-Some build steps require a local installation on Chrome, which may not be available (e.g. on a computing cluster). If you are unable to install Chrome, the recommended workflow is to build intermediate output formats and use an alternative method for the output format that requires Chrome.
+Building the PDF requires a local installation on Chrome, which may not be available (e.g. on a computing cluster). If you are unable to install Chrome, the recommended workflow is to build intermediate output formats and use an alternative method for building the PDF.
For example, to build a pptx from a Rmd file without Chrome, you could:
@@ -200,7 +223,7 @@ For example, to build a pptx from a Rmd file without Chrome, you could:
- Author: *John Paul Helveston* [www.jhelvy.com](http://www.jhelvy.com/)
- Date First Written: *September 27, 2020*
-- Most Recent Update: `r format(Sys.Date(), format="%B %d %Y")`
+- Most Recent Update: `r format(Sys.Date(), format="%B %d, %Y")`
- License: [MIT](https://github.com/jhelvy/xaringanBuilder/blob/master/LICENSE.md)
## Citation Information
diff --git a/README.md b/README.md
index ed6ae21..1746b3a 100644
--- a/README.md
+++ b/README.md
@@ -16,8 +16,9 @@ Build xaringan slides to multiple output formats:
- pdf
- gif
- pptx
-- thumbnail - png of first slide (useful for Youtube thumbnail)
-- social - png of first slide sized for social media sharing
+- png (convert some or all slides to png files; useful for generating
+ Youtube thumbnails, for example)
+- social: png image of first slide sized for social media sharing
(e.g. Twitter)
## Installation
@@ -29,11 +30,24 @@ You can install the current version of xaringanBuilder from GitHub:
## Usage
- library(xaringanBuilder)
-
The xaringan Rmd files used in all examples below can be found
[here](https://github.com/jhelvy/xaringanBuilder/tree/master/inst/example)
+ library(xaringanBuilder)
+
+### Input - Output
+
+All `build_**()` functions use the `input` and `output_file` arguments.
+
+The `input` argument is required and can be a full or local path to the
+input file (a Rmd, html, or pdf file), or a url to a set of xaringan
+slides on the web.
+
+The `output_file` argument is optional. It can be a full or local path
+to the output file, and it must end in an appropriate extension
+(e.g. `slides.gif` for `build_gif()`). If it is not provided, the output
+file name will be determined based on the `input` argument.
+
### Build HTML
Build an html file from a Rmd file:
@@ -42,20 +56,23 @@ Build an html file from a Rmd file:
### Build PDF
-Build a pdf file from a Rmd or html file, or a url to slides:
+Input can be a Rmd file, html file, or url:
build_pdf("slides.Rmd")
build_pdf("slides.html")
- build_pdf("http://www.mysite.com/myslides.html")
+ build_pdf("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
+
+**Note**: Building the PDF requires a local installation of Google
+Chrome
### Build GIF
-Build a gif file from a Rmd, html, or pdf file, or a url to slides:
+Input can be a Rmd file, html file, pdf file, or url:
build_gif("slides.Rmd")
build_gif("slides.html")
build_gif("slides.pdf")
- build_gif("http://www.mysite.com/myslides.html")
+ build_gif("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
Example:
@@ -63,29 +80,40 @@ Example:
### Build PPTX
-Build a pptx file from a Rmd, html or pdf file, or a url to slides. The
-pptx file contains slides of png images of each rendered xaringan slide:
+Creates a pptx file where each slide contains a png image of each
+xaringan slide. While you won’t be able to edit the xaringan content
+from Powerpoint, you can at least annotate it.
+
+(See the [slidex](https://github.com/datalorax/slidex) package by
+@datalorax to do the opposite: pptx –> xaringan!)
+
+Input can be a Rmd file, html file, pdf file, or url:
build_pptx("slides.Rmd")
build_pptx("slides.html")
build_pptx("slides.pdf")
- build_pptx("http://www.mysite.com/myslides.html")
+ build_pptx("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
-(See the [slidex](https://github.com/datalorax/slidex) package by
-@datalorax to do the opposite: pptx –> xaringan!)
+### Build PNG
-### Build Thumbnail
+Build png image(s) of some or all slides. Useful for generating Youtube
+thumbnails, for example.
-Build a “thumbnail” png image of the first slide from a Rmd or html
-file, or a url to slides (useful for Youtube thumbnail):
+Input can be a Rmd file, html file, pdf file, or url:
- build_thumbnail("slides.Rmd")
- build_thumbnail("slides.html")
- build_thumbnail("http://www.mysite.com/myslides.html")
+ # By default, a png of only the first slide is built
+ build_png("slides.Rmd")
+ build_png("slides.html")
+ build_png("slides.pdf")
+ build_png("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html")
+
+ # Build zip file of multiple or all slides
+ build_png("slides.pdf", slides = c(1, 3, 5))
+ build_png("slides.pdf", slides = "all")
Example:
-
+
### Build Social
@@ -94,6 +122,10 @@ sharing on social media (e.g. Twitter).
build_social("slides.Rmd")
+**Note**: This option requires the
+[chromote](https://github.com/rstudio/chromote) and
+[pdftools](https://github.com/ropensci/pdftools) packages.
+
Example:
@@ -102,14 +134,15 @@ Example:
Use `build_all()` to build all output types from a Rmd file:
- build_all("slides.Rmd") # Builds every output by default
+ # Builds every output by default
+ build_all("slides.Rmd")
Use the `include` or `exclude` arguments to control which output types
to include or exclude:
# Both of these build html, pdf, and gif outputs
build_all("slides.Rmd", include = c("html", "pdf", "gif"))
- build_all("slides.Rmd", exclude = c("pptx", "thumbnail", "social"))
+ build_all("slides.Rmd", exclude = c("pptx", "png", "social"))
## “Complex” slides
@@ -117,31 +150,33 @@ to include or exclude:
[panelsets](https://pkg.garrickadenbuie.com/xaringanExtra/#/panelset) or
other html widgets / advanced features that might not render well as a
pdf. To render these, set `complex_slides = TRUE` in `build_pdf()`,
-`build_gif()`, `build_pptx()`, or `build_all()`.
+`build_png()`, `build_gif()`, `build_pptx()`, or `build_all()`.
For example:
build_pdf("slides_complex.Rmd", complex_slides = TRUE)
build_pdf("slides_complex.html", complex_slides = TRUE)
-**Note**: This option requires a local installation of Google Chrome as
-well as the [chromote](https://github.com/rstudio/chromote) package.
+**Note**: This option requires the
+[chromote](https://github.com/rstudio/chromote) and
+[pdftools](https://github.com/ropensci/pdftools) packages.
## Partial / incremental slides
For pdf, gif, and pptx output types, if you want to build a new slide
for each increment on [incremental
slides](https://slides.yihui.org/xaringan/incremental.html#1), set
-`partial_slides = TRUE` in `build_pdf()`, `build_gif()`, `build_pptx()`,
-or `build_all()`.
+`partial_slides = TRUE` in `build_pdf()`, `build_png()`, `build_gif()`,
+`build_pptx()`, or `build_all()`.
For example:
build_pdf("slides.Rmd", partial_slides = TRUE)
build_pdf("slides.html", partial_slides = TRUE)
-**Note**: This option requires a local installation of Google Chrome as
-well as the [chromote](https://github.com/rstudio/chromote) package.
+**Note**: This option requires the
+[chromote](https://github.com/rstudio/chromote) and
+[pdftools](https://github.com/ropensci/pdftools) packages.
## Build hierarchy
@@ -154,22 +189,21 @@ diagram of the build hierarchy:
|--> social (png)
|
|--> html
- |
- |--> thumbnail (png)
|
|--> pdf
|
- |--> gif
- |
- |--> pptx
+ |--> png
+ |
+ |--> gif
+ |
+ |--> pptx
## Local Chrome installation requirement
-Some build steps require a local installation on Chrome, which may not
+Building the PDF requires a local installation on Chrome, which may not
be available (e.g. on a computing cluster). If you are unable to install
Chrome, the recommended workflow is to build intermediate output formats
-and use an alternative method for the output format that requires
-Chrome.
+and use an alternative method for building the PDF.
For example, to build a pptx from a Rmd file without Chrome, you could:
@@ -184,7 +218,7 @@ For example, to build a pptx from a Rmd file without Chrome, you could:
- Author: *John Paul Helveston*
[www.jhelvy.com](http://www.jhelvy.com/)
- Date First Written: *September 27, 2020*
-- Most Recent Update: February 24 2021
+- Most Recent Update: February 25, 2021
- License:
[MIT](https://github.com/jhelvy/xaringanBuilder/blob/master/LICENSE.md)
@@ -203,5 +237,5 @@ A BibTeX entry for LaTeX users is
@Manual{, title = {xaringanBuilder: Functions for building xaringan
slides to different outputs.}, author = {John Paul Helveston}, year =
-{2021}, note = {R package version 0.0.4}, url =
+{2021}, note = {R package version 0.0.6}, url =
{
with xaringan"
-author: "Yihui Xie"
-institute: "RStudio, PBC"
+title: "{xaringanBuilder}"
+subtitle: "Build xaringan slides to different outputs"
+author: "John Paul Helveston"
date: "2016/12/12 (updated: `r Sys.Date()`)"
output:
xaringan::moon_reader:
@@ -17,6 +16,7 @@ background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/be/Sharin
```{r setup, include=FALSE}
options(htmltools.dir.version = FALSE)
+xaringanExtra::use_panelset() # So we can add some slides with fancy panelsets!
```
???
@@ -24,48 +24,101 @@ options(htmltools.dir.version = FALSE)
Image credit: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Sharingan_triple.svg)
---
-class: center, middle
-# xaringan
+## Installation
-### /ʃaː.'riŋ.ɡan/
+You can install the current version of xaringanBuilder from GitHub:
+
+```
+# install.packages("remotes")
+remotes::install_github("jhelvy/xaringanBuilder")
+```
+
+.pull-left[
+## Supported output types:
+
+- html
+- pdf
+- gif
+- pptx
+- png
+- social: png image of first slide sized for social media sharing (e.g. Twitter)
+
+]
+
+.pull-right[
+## Build hierarchy:
+
+```
+Rmd
+ |
+ |--> social (png)
+ |
+ |--> html
+ |
+ |--> pdf
+ |
+ |--> png
+ |
+ |--> gif
+ |
+ |--> pptx
+```
+
+]
---
-# Hello World
+## Partial / incremental slides
-Install the **xaringan** package from [Github](https://github.com/yihui/xaringan):
+For `pdf`, `png`, `gif`, and `pptx` output types, if you want to build a new slide for each increment on [incremental slides](https://slides.yihui.org/xaringan/incremental.html#1), set `partial_slides = TRUE` in any of the following build functions:
-```{r eval=FALSE, tidy=FALSE}
-devtools::install_github("yihui/xaringan")
+```
+build_pdf()
+build_png()
+build_gif()
+build_pptx()
+build_all()
```
--
-You are recommended to use the [RStudio IDE](https://www.rstudio.com/products/rstudio/), but you do not have to.
+For example, the following code would render this slide as two slides in a pdf instead of one:
-- Create a new R Markdown document from the menu `File -> New File -> R Markdown -> From Template -> Ninja Presentation`;1
+```
+build_pdf("slides.Rmd", partial_slides = TRUE)
+build_pdf("slides.html", partial_slides = TRUE)
+```
---
+> **Note**: This option requires the [chromote](https://github.com/rstudio/chromote) and [pdftools](https://github.com/ropensci/pdftools) packages.
-- Click the `Knit` button to compile it;
+---
---
+## Complex slides
-- or use the [RStudio Addin](https://rstudio.github.io/rstudioaddins/)2 "Infinite Moon Reader" to live preview the slides (every time you update and save the Rmd document, the slides will be automatically reloaded in RStudio Viewer.
+"Complex" slides are slides that contain [panelsets](https://pkg.garrickadenbuie.com/xaringanExtra/#/panelset) (like the one on this slide) or other html widgets / advanced features that might not render well as a pdf. To render these on separate slides, set `complex_slides = TRUE` in `build_pdf()`, `build_png()`, `build_gif()`, `build_pptx()`, or `build_all()`.
-.footnote[
-[1] 中文用户请看[这份教程](https://slides.yihui.org/xaringan/zh-CN.html)
+.panelset[
+.panel[.panel-name[Chunk]
-[2] See [#2](https://github.com/yihui/xaringan/issues/2) if you do not see the template or addin in RStudio.
+```{r, eval=FALSE}
+head(mtcars)
+```
]
----
+.panel[.panel-name[Output]
+
+```{r, echo=FALSE}
+head(mtcars)
+```
+]
+]
-class: center, middle
+---
+class: center, middle, inverse
# Thanks!
Slides created via the R package [**xaringan**](https://github.com/yihui/xaringan).
-The chakra comes from [remark.js](https://remarkjs.com), [**knitr**](https://yihui.org/knitr), and [R Markdown](https://rmarkdown.rstudio.com).
+More at https://jhelvy.github.io/xaringanBuilder
diff --git a/inst/example/slides.gif b/inst/example/slides.gif
index 6366ea5..11698f3 100644
Binary files a/inst/example/slides.gif and b/inst/example/slides.gif differ
diff --git a/inst/example/slides.html b/inst/example/slides.html
index e2c54c4..554cab3 100644
--- a/inst/example/slides.html
+++ b/inst/example/slides.html
@@ -1,22 +1,23 @@
is empty, we'll remove it + if ( + nameDiv.tagName === 'SPAN' && + nameDiv.parentNode.tagName === 'P' && + nameDiv.textContent === nameDiv.parentNode.textContent + ) { + name = nameDiv.textContent + item.removeChild(nameDiv.parentNode) + return name + } + + // If none of the above, remove the nameDiv and return the name + name = nameDiv.textContent + nameDiv.parentNode.removeChild(nameDiv) + return name + } + + const processPanelItem = (item) => { + const name = identifyPanelName(item) + return { name, content: item.children, id: uniquePanelId(name) } + } + + const getCurrentPanelFromUrl = (panelset) => { + const params = new URLSearchParams(window.location.search) + return params.get(panelset) + } + + const reflowPanelSet = (panels, idx) => { + const res = document.createElement('div') + res.className = 'panelset' + res.id = 'panelset' + (idx > 0 ? idx : '') + const panelSelected = getCurrentPanelFromUrl(res.id) + + // create header row + const headerRow = document.createElement('ul') + headerRow.className = 'panel-tabs' + headerRow.setAttribute('role', 'tablist') + panels + .map((p, idx) => { + const panelHeaderItem = document.createElement('li') + panelHeaderItem.className = 'panel-tab' + panelHeaderItem.setAttribute('role', 'tab') + const thisPanelIsActive = panelSelected ? panelSelected === p.id : idx === 0 + if (thisPanelIsActive) { + panelHeaderItem.classList.add('panel-tab-active') + panelHeaderItem.setAttribute('aria-selected', true) + } + panelHeaderItem.tabIndex = 0 + panelHeaderItem.id = res.id + '_' + p.id // #panelsetid_panelid + + const panelHeaderLink = document.createElement('a') + panelHeaderLink.href = '?' + res.id + '=' + p.id + '#' + panelHeaderItem.id + panelHeaderLink.setAttribute('onclick', 'return false;') + panelHeaderLink.tabIndex = -1 // list item is tabable, not link + panelHeaderLink.innerHTML = p.name + panelHeaderLink.setAttribute('aria-controls', p.id) + + panelHeaderItem.appendChild(panelHeaderLink) + return panelHeaderItem + }) + .forEach(el => headerRow.appendChild(el)) + + res.appendChild(headerRow) + + panels + .map((p, idx) => { + const panelContent = document.createElement('section') + panelContent.className = 'panel' + panelContent.setAttribute('role', 'tabpanel') + const thisPanelIsActive = panelSelected ? panelSelected === p.id : idx === 0 + panelContent.classList.toggle('panel-active', thisPanelIsActive) + panelContent.id = p.id + panelContent.setAttribute('aria-labelledby', p.id) + Array.from(p.content).forEach(el => panelContent.appendChild(el)) + return panelContent + }) + .forEach(el => res.appendChild(el)) + + return res + } + + const updateUrl = (panelset, panel) => { + let params = new URLSearchParams(window.location.search) + if (panel) { + params.set(panelset, panel) + } else { + params.delete(panelset) + } + params = params.toString() ? ('?' + params.toString()) : '' + const { pathname, hash } = window.location + const uri = pathname + params + hash + window.history.replaceState(uri, '', uri) + } + + const togglePanel = (clicked) => { + if (clicked.nodeName.toUpperCase() === 'A') { + clicked = clicked.parentElement + } + if (!clicked.classList.contains('panel-tab')) return + if (clicked.classList.contains('panel-tab-active')) return + + const tabs = clicked.parentNode + .querySelectorAll('.panel-tab') + const panels = clicked.parentNode.parentNode + .querySelectorAll('.panel') + const panelTabClicked = clicked.children[0].getAttribute('aria-controls') + const panelClicked = clicked.parentNode.parentNode.id + + Array.from(tabs) + .forEach(t => { + t.classList.remove('panel-tab-active') + t.removeAttribute('aria-selected') + }) + Array.from(panels) + .forEach(p => { + const active = p.id === panelTabClicked + p.classList.toggle('panel-active', active) + // make inactive panels inaccessible by keyboard navigation + if (active) { + p.removeAttribute('tabIndex') + p.removeAttribute('aria-hidden') + } else { + p.setAttribute('tabIndex', -1) + p.setAttribute('aria-hidden', true) + } + }) + + clicked.classList.add('panel-tab-active') + clicked.setAttribute('aria-selected', true) + + // update query string + updateUrl(panelClicked, panelTabClicked) + } + + const initPanelSet = (panelset, idx) => { + const panels = Array.from(panelset.querySelectorAll('.panel')) + if (!panels.length) return + + const contents = panels.map(processPanelItem) + const newPanelSet = reflowPanelSet(contents, idx) + panelset.parentNode.insertBefore(newPanelSet, panelset) + panelset.parentNode.removeChild(panelset) + + // click and touch events + const panelTabs = newPanelSet.querySelector('.panel-tabs'); + ['click', 'touchend'].forEach(eventType => { + panelTabs.addEventListener(eventType, function (ev) { + togglePanel(ev.target) + ev.stopPropagation() + }) + }) + panelTabs.addEventListener('touchmove', function (ev) { + ev.preventDefault() + }) + + // key events + newPanelSet + .querySelector('.panel-tabs') + .addEventListener('keydown', (ev) => { + const self = ev.currentTarget.querySelector('.panel-tab-active') + if (ev.code === 'Space' || ev.code === 'Enter') { + togglePanel(ev.target) + ev.stopPropagation() + } else if (ev.code === 'ArrowLeft' && self.previousSibling) { + togglePanel(self.previousSibling) + self.previousSibling.focus() + ev.stopPropagation() + } else if (ev.code === 'ArrowRight' && self.nextSibling) { + togglePanel(self.nextSibling) + self.nextSibling.focus() + ev.stopPropagation() + } + }) + + return panels + } + + // initialize panels + Array.from(document.querySelectorAll('.panelset')).map(initPanelSet) + + if (typeof slideshow !== 'undefined') { + const getVisibleActivePanelInfo = () => { + const slidePanels = document.querySelectorAll('.remark-visible .panel-tab-active') + + if (!slidePanels.length) return null + + return slidePanels.map(panel => { + return { + panel, + panelId: panel.children[0].getAttribute('aria-controls'), + panelSetId: panel.parentNode.parentNode.id + } + }) + } + + slideshow.on('hideSlide', slide => { + // clear focus if we had a panel-tab selected + document.activeElement.blur() + + // clear search query for panelsets in current slide + document.querySelectorAll('.remark-visible .panelset') + .forEach(ps => updateUrl(ps.id, null)) + }) + + slideshow.on('afterShowSlide', slide => { + const slidePanels = getVisibleActivePanelInfo() + + if (slidePanels) { + // only first panel gets focus + slidePanels[0].panel.focus() + // but still update the url to reflect all active panels + slidePanels.forEach(({ panelId, panelSetId }) => updateUrl(panelSetId, panelId)) + } + }) + } + }) +})() diff --git a/man/figures/libs/remark-css/default-fonts.css b/man/figures/libs/remark-css/default-fonts.css new file mode 100644 index 0000000..8d035fa --- /dev/null +++ b/man/figures/libs/remark-css/default-fonts.css @@ -0,0 +1,10 @@ +@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); +@import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); +@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700); + +body { font-family: 'Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; } +h1, h2, h3 { + font-family: 'Yanone Kaffeesatz'; + font-weight: normal; +} +.remark-code, .remark-inline-code { font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; } diff --git a/man/figures/libs/remark-css/default.css b/man/figures/libs/remark-css/default.css new file mode 100644 index 0000000..d37bfd2 --- /dev/null +++ b/man/figures/libs/remark-css/default.css @@ -0,0 +1,72 @@ +a, a > code { + color: rgb(249, 38, 114); + text-decoration: none; +} +.footnote { + position: absolute; + bottom: 3em; + padding-right: 4em; + font-size: 90%; +} +.remark-code-line-highlighted { background-color: #ffff88; } + +.inverse { + background-color: #272822; + color: #d6d6d6; + text-shadow: 0 0 20px #333; +} +.inverse h1, .inverse h2, .inverse h3 { + color: #f3f3f3; +} +/* Two-column layout */ +.left-column { + color: #777; + width: 20%; + height: 92%; + float: left; +} +.left-column h2:last-of-type, .left-column h3:last-child { + color: #000; +} +.right-column { + width: 75%; + float: right; + padding-top: 1em; +} +.pull-left { + float: left; + width: 47%; +} +.pull-right { + float: right; + width: 47%; +} +.pull-right + * { + clear: both; +} +img, video, iframe { + max-width: 100%; +} +blockquote { + border-left: solid 5px lightgray; + padding-left: 1em; +} +.remark-slide table { + margin: auto; + border-top: 1px solid #666; + border-bottom: 1px solid #666; +} +.remark-slide table thead th { border-bottom: 1px solid #ddd; } +th, td { padding: 5px; } +.remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee } + +@page { margin: 0; } +@media print { + .remark-slide-scaler { + width: 100% !important; + height: 100% !important; + transform: scale(1) !important; + top: 0 !important; + left: 0 !important; + } +} diff --git a/man/figures/slides.gif b/man/figures/slides.gif index 0fb12b4..11698f3 100644 Binary files a/man/figures/slides.gif and b/man/figures/slides.gif differ diff --git a/inst/example/slides_complex.html b/man/figures/slides.html similarity index 67% rename from inst/example/slides_complex.html rename to man/figures/slides.html index c401eaf..554cab3 100644 --- a/inst/example/slides_complex.html +++ b/man/figures/slides.html @@ -1,9 +1,9 @@
-