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 = {}, } diff --git a/_pkgdown.yml b/_pkgdown.yml index 6c7077f..4a690c0 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -29,6 +29,7 @@ reference: - build_all - build_html - build_pdf + - build_png + - build_social - build_gif - build_pptx - - build_thumbnail diff --git a/inst/CITATION b/inst/CITATION index 7f67b1d..7df0769 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -5,7 +5,7 @@ citEntry( title = "xaringanBuilder: Functions for building xaringan slides to different outputs.", author = "John Paul Helveston", year = "2021", - note = "R package version 0.0.5", + note = "R package version 0.0.6", url = "https://jhelvy.github.io/xaringanBuilder/", textVersion = "John Paul Helveston (2021). xaringanBuilder: Functions for building xaringan slides to different outputs." ) diff --git a/inst/example/examples.R b/inst/example/examples.R index 9bcd838..ce5e1cb 100644 --- a/inst/example/examples.R +++ b/inst/example/examples.R @@ -2,66 +2,64 @@ # remotes::install_github('jhelvy/xaringanBuilder') library(xaringanBuilder) -# Build All Output Types -------------- - -# Use `build_all()` to build all output types from a Rmd file: -build_all("slides.Rmd") # Builds every output by default - -# 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")) - -# Build an html file from a Rmd file -------------- +# Build an html file from a Rmd file build_html("slides.Rmd") -# Build a pdf file from a Rmd or html file -------------- +# Build pdf from Rmd, html, or url build_pdf("slides.Rmd") build_pdf("slides.html") +build_pdf("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.html") -# Build a gif file from a 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 a pptx file from a Rmd, html or pdf file -------------- -# pptx contains slides of png images of each rendered xaringan slide) +# Build pptx from Rmd, html, pdf, or url +# (pptx contains slides of png images of each rendered xaringan slide) build_pptx("slides.Rmd") build_pptx("slides.html") build_pptx("slides.pdf") +build_pptx("https://jhelvy.github.io/xaringanBuilder/reference/figures/slides.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 a "thumbnail" png image of first slide from a Rmd or html file ----- -build_thumbnail("slides.Rmd") -build_thumbnail("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 a png of the first slide from a Rmd file. -# Image is sized for sharing on social media (e.g. Twitter). +# Build png image of first xaringan slide from Rmd file +# sized for sharing on social media build_social("slides.Rmd") -# "Complex" slides -------------- +# Use `build_all()` to build all output types from a Rmd file: +build_all("slides.Rmd") # Builds every output by default + +# 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", "png", "social")) + +# "Complex" slides # "Complex" slides are slides that contain panelsets 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()`. **Note**: This option requires a local -# installation of Google Chrome as well as the chromote package. -build_pdf(input = "slides_complex.Rmd", - output_file = "slides_complex.pdf", - complex_slides = TRUE) -build_pdf(input = "slides_complex.html", +# these, set `complex_slides = TRUE`. **Note**: This option requires the +# chromote and pdftools packages. +build_pdf(input = "slides.html", output_file = "slides_complex.pdf", complex_slides = TRUE) -# Partial / incremental slides -------------- +# Partial / incremental slides -# For pdf, gif, and pptx output types, if you want to build a new slide for -# each increment on incremental slides set `partial_slides = TRUE` in -# `build_pdf()`, `build_gif()`, `build_pptx()`, or `build_all()`. **Note**: -# This option requires a local installation of Google Chrome as well as the -# chromote package. -build_pdf(input = "slides.Rmd", - output_file = "slides_partial.pdf", - partial_slides = TRUE) +# For pdf, png, gif, and pptx output types, if you want to build a new slide +# for each increment on incremental slides set `partial_slides = TRUE`. +# **Note**: This option requires the chromote and pdftools packages. build_pdf(input = "slides.html", output_file = "slides_partial.pdf", partial_slides = TRUE) diff --git a/inst/example/readme.md b/inst/example/readme.md index e64bf03..7cb7487 100644 --- a/inst/example/readme.md +++ b/inst/example/readme.md @@ -1,8 +1,3 @@ Open `examples.Rproj` to open RStudio, then open `examples.R` to run different examples of building slides to different output types. -The main two xaringan slide files are: - -- `slides.Rmd` -- `slides_complex.Rmd` - -Both contain the same example slides, including [incremental slides](https://slides.yihui.org/xaringan/incremental.html#1), except that `slides_complex.Rmd` has an additional slide with a [panelset](https://pkg.garrickadenbuie.com/xaringanExtra/#/panelset). If you want the panelset slide to render to a separate slide for each panel, set `complex_slides = TRUE` in `build_pdf()`, `build_gif()`, `build_pptx()`, or `build_all()`. +All output types are built from the main xaringan slide file: `slides.Rmd` diff --git a/inst/example/slides.Rmd b/inst/example/slides.Rmd index a85b9ee..51549f3 100755 --- a/inst/example/slides.Rmd +++ b/inst/example/slides.Rmd @@ -1,8 +1,7 @@ --- -title: "Presentation Ninja" -subtitle: "⚔
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 @@ - Presentation Ninja + {xaringanBuilder} - + + + diff --git a/inst/example/slides.pdf b/inst/example/slides.pdf index ffa46db..32735ba 100644 Binary files a/inst/example/slides.pdf and b/inst/example/slides.pdf differ diff --git a/inst/example/slides.png b/inst/example/slides.png new file mode 100644 index 0000000..3adde66 Binary files /dev/null and b/inst/example/slides.png differ diff --git a/inst/example/slides.pptx b/inst/example/slides.pptx index bf54399..d795b47 100644 Binary files a/inst/example/slides.pptx and b/inst/example/slides.pptx differ diff --git a/inst/example/slides_complex.Rmd b/inst/example/slides_complex.Rmd deleted file mode 100755 index cf55fd5..0000000 --- a/inst/example/slides_complex.Rmd +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "Presentation Ninja" -subtitle: "⚔
with xaringan" -author: "Yihui Xie" -institute: "RStudio, PBC" -date: "2016/12/12 (updated: `r Sys.Date()`)" -output: - xaringan::moon_reader: - lib_dir: libs - nature: - highlightStyle: github - highlightLines: true - countIncrementalSlides: false ---- - -background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/be/Sharingan_triple.svg) - -```{r setup, include=FALSE} -options(htmltools.dir.version = FALSE) -xaringanExtra::use_panelset() # So we can add some slides with fancy panelsets! -``` - -??? - -Image credit: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Sharingan_triple.svg) - ---- -class: center, middle - -# xaringan - -### /ʃaː.'riŋ.ɡan/ - ---- - -# Hello World - -Install the **xaringan** package from [Github](https://github.com/yihui/xaringan): - -```{r eval=FALSE, tidy=FALSE} -devtools::install_github("yihui/xaringan") -``` - --- - -You are recommended to use the [RStudio IDE](https://www.rstudio.com/products/rstudio/), but you do not have to. - -- Create a new R Markdown document from the menu `File -> New File -> R Markdown -> From Template -> Ninja Presentation`;1 - --- - -- Click the `Knit` button to compile it; - --- - -- 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. - -.footnote[ -[1] 中文用户请看[这份教程](https://slides.yihui.org/xaringan/zh-CN.html) - -[2] See [#2](https://github.com/yihui/xaringan/issues/2) if you do not see the template or addin in RStudio. -] - ---- - -# Panels! - -.panelset[ -.panel[.panel-name[Chunk] - -```{r, eval=FALSE} -head(mtcars) -``` -] - -.panel[.panel-name[Output] - -```{r, echo=FALSE} -head(mtcars) -``` -] -] - ---- - -class: center, middle - -# 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). diff --git a/inst/example/slides_complex.pdf b/inst/example/slides_complex.pdf index e04deee..9246fe4 100644 Binary files a/inst/example/slides_complex.pdf and b/inst/example/slides_complex.pdf differ diff --git a/inst/example/slides_partial.html b/inst/example/slides_partial.html deleted file mode 100644 index e2c54c4..0000000 --- a/inst/example/slides_partial.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - Presentation Ninja - - - - - - - - - - - - - - - - - diff --git a/inst/example/slides_partial.pdf b/inst/example/slides_partial.pdf index 17143e0..e4e8d2e 100644 Binary files a/inst/example/slides_partial.pdf and b/inst/example/slides_partial.pdf differ diff --git a/inst/example/slides_social.png b/inst/example/slides_social.png index 28cb8ed..170d790 100644 Binary files a/inst/example/slides_social.png and b/inst/example/slides_social.png differ diff --git a/inst/example/slides_thumbnail.png b/inst/example/slides_thumbnail.png deleted file mode 100644 index 159ee28..0000000 Binary files a/inst/example/slides_thumbnail.png and /dev/null differ diff --git a/man/build_all.Rd b/man/build_all.Rd index b358c75..57f45f4 100644 --- a/man/build_all.Rd +++ b/man/build_all.Rd @@ -6,22 +6,25 @@ \usage{ build_all( 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 ) } \arguments{ \item{input}{Path to Rmd file of xaringan slides.} \item{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")`.} \item{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.} \item{complex_slides}{For "complex" slides (e.g. slides with panelsets or @@ -37,21 +40,28 @@ is included in the PDF.} \item{delay}{Seconds of delay between advancing to and printing a new slide. Only used if `complex_slides = TRUE` or `partial_slides = TRUE`.} + +\item{density}{Resolution of the resulting png files used in the png, gif, +and pptx output types file. Defaults to `"72x72"`.} + +\item{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"`).} + +\item{fps}{Frames per second of the gif file.} } \description{ 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. } \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")) } } diff --git a/man/build_gif.Rd b/man/build_gif.Rd index 8823738..7c594ae 100644 --- a/man/build_gif.Rd +++ b/man/build_gif.Rd @@ -15,13 +15,14 @@ build_gif( ) } \arguments{ -\item{input}{Path to a Rmd, html, or pdf file, or a url of xaringan slides. +\item{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".} \item{output_file}{Name of the output gif file.} -\item{density}{Resolution of the resulting gif file.} +\item{density}{Resolution of the resulting gif file. Defaults to +`"72x72"`.} \item{fps}{Frames per second of the resulting gif file.} @@ -45,9 +46,10 @@ then converts it to a gif. } \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") } } diff --git a/man/build_pdf.Rd b/man/build_pdf.Rd index 6114142..459f18e 100644 --- a/man/build_pdf.Rd +++ b/man/build_pdf.Rd @@ -42,12 +42,10 @@ you will also need to install the {chromote} and {pdftools} packages. } \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) diff --git a/man/build_pdf_complex.Rd b/man/build_pdf_complex.Rd deleted file mode 100644 index b368674..0000000 --- a/man/build_pdf_complex.Rd +++ /dev/null @@ -1,27 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pdf.R -\name{build_pdf_complex} -\alias{build_pdf_complex} -\title{Print "complex" xaringan slides to PDF} -\usage{ -build_pdf_complex(input, output_file, partial_slides, delay) -} -\arguments{ -\item{input}{Path to Rmd or html file of xaringan slides.} - -\item{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.} - -\item{partial_slides}{Should partial (continuation) slides be -included in the output? If `FALSE`, the default, only the complete slide -is included in the PDF.} - -\item{delay}{Seconds of delay between advancing to and printing -a new slide.} -} -\description{ -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. -} diff --git a/man/build_pdf_simple.Rd b/man/build_pdf_simple.Rd deleted file mode 100644 index d62c559..0000000 --- a/man/build_pdf_simple.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pdf.R -\name{build_pdf_simple} -\alias{build_pdf_simple} -\title{Print "simple" xaringan slides to PDF} -\usage{ -build_pdf_simple(input, output_file = NULL) -} -\arguments{ -\item{input}{Path to Rmd or html file of xaringan slides.} - -\item{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.} -} -\description{ -Prints "simple" xaringan slides - those without panelsets or other html -widgets or advanced features, and also slides without partial slides. -} diff --git a/man/build_png.Rd b/man/build_png.Rd new file mode 100644 index 0000000..27ef4a2 --- /dev/null +++ b/man/build_png.Rd @@ -0,0 +1,65 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/png.R +\name{build_png} +\alias{build_png} +\title{Build xaringan slides as png file(s).} +\usage{ +build_png( + input, + output_file = NULL, + density = "72x72", + slides = 1, + complex_slides = FALSE, + partial_slides = FALSE, + delay = 1 +) +} +\arguments{ +\item{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".} + +\item{output_file}{Name of the output png or zip file.} + +\item{density}{Resolution of the resulting gif file. Defaults to +`"72x72"`.} + +\item{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"`).} + +\item{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.} + +\item{partial_slides}{Should partial (continuation) slides be +included in the output? If `FALSE`, the default, only the complete slide +is included in the PDF.} + +\item{delay}{Seconds of delay between advancing to and printing +a new slide. Only used if `complex_slides = TRUE` or `partial_slides = +TRUE`.} +} +\description{ +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"`). +} +\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") +} +} diff --git a/man/build_pptx.Rd b/man/build_pptx.Rd index 914e16f..d3be7c4 100644 --- a/man/build_pptx.Rd +++ b/man/build_pptx.Rd @@ -14,13 +14,14 @@ build_pptx( ) } \arguments{ -\item{input}{Path to a Rmd, html, or pdf file, or a url of xaringan slides. +\item{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".} \item{output_file}{Name of the output pptx file.} -\item{density}{Resolution of the resulting pptx file.} +\item{density}{Resolution of the resulting gif file. Defaults to +`"72x72"`.} \item{complex_slides}{For "complex" slides (e.g. slides with panelsets or other html widgets or advanced features), set `complex_slides = TRUE`. @@ -38,13 +39,15 @@ TRUE`.} } \description{ 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. +then converts it into png images that are inserted on each slide in the +pptx file. } \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") } } diff --git a/man/build_social.Rd b/man/build_social.Rd index 32d11a4..2b45b92 100644 --- a/man/build_social.Rd +++ b/man/build_social.Rd @@ -21,7 +21,7 @@ Requires a local installation of Chrome as well as the {webshot2} package: \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/man/build_thumbnail.Rd b/man/build_thumbnail.Rd index 5aad058..ad7d5d0 100644 --- a/man/build_thumbnail.Rd +++ b/man/build_thumbnail.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/thumbnail.R +% Please edit documentation in R/png.R \name{build_thumbnail} \alias{build_thumbnail} \title{Build png thumbnail image of first slide.} diff --git a/man/figures/libs/header-attrs/header-attrs.js b/man/figures/libs/header-attrs/header-attrs.js new file mode 100644 index 0000000..dd57d92 --- /dev/null +++ b/man/figures/libs/header-attrs/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/man/figures/libs/panelset/panelset.css b/man/figures/libs/panelset/panelset.css new file mode 100644 index 0000000..de73288 --- /dev/null +++ b/man/figures/libs/panelset/panelset.css @@ -0,0 +1,100 @@ +/* prefixed by https://autoprefixer.github.io (PostCSS: v7.0.23, autoprefixer: v9.7.3) */ + +.panelset { + width: 100%; + position: relative; + --panel-tabs-border-bottom: #ddd; + --panel-tab-foreground: currentColor; + --panel-tab-background: unset; + --panel-tab-active-foreground: currentColor; + --panel-tab-active-background: unset; + --panel-tab-hover-foreground: currentColor; + --panel-tab-hover-background: unset; + --panel-tab-active-border-color: currentColor; + --panel-tab-hover-border-color: currentColor; + --panel-tab-inactive-opacity: 0.5; + --panel-tab-font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; +} + +.panelset * { + box-sizing: border-box; +} + +.panelset .panel-tabs { + display: -webkit-box; + display: flex; + flex-wrap: wrap; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + flex-direction: row; + -webkit-box-pack: start; + justify-content: start; + -webkit-box-align: center; + align-items: center; + overflow-y: visible; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0 0 2px 0; + box-shadow: inset 0 -2px 0px var(--panel-tabs-border-bottom); +} + +.panelset .panel-tabs * { + -webkit-transition: opacity 0.5s ease; + transition: opacity 0.5s ease; +} + +.panelset .panel-tabs .panel-tab { + min-height: 50px; + display: -webkit-box; + display: flex; + -webkit-box-pack: center; + justify-content: center; + -webkit-box-align: center; + align-items: center; + padding: 0.5em 1em; + font-family: var(--panel-tab-font-family); + opacity: var(--panel-tab-inactive-opacity); + border-top: 2px solid transparent; + border-bottom: 2px solid transparent; + margin-bottom: -2px; + color: var(--panel-tab-foreground); + background-color: var(--panel-tab-background); + list-style: none; + z-index: 5; +} + +.panelset .panel-tabs .panel-tab > a { + color: currentColor; + text-decoration: none; +} + +.panelset .panel-tabs .panel-tab:hover { + border-bottom-color: var(--panel-tab-hover-border-color); + color: var(--panel-tab-hover-foreground); + background-color: var(--panel-tab-hover-background); + opacity: 1; + cursor: pointer; + z-index: 10; +} + +.panelset .panel-tabs .panel-tab:focus { + outline: none; + color: var(--panel-tab-hover-foreground); + border-bottom-color: var(--panel-tab-hover-border-color); + background-color: var(--panel-tab-hover-background); +} + +.panelset .panel-tabs .panel-tab.panel-tab-active { + border-top-color: var(--panel-tab-active-border-color); + color: var(--panel-tab-active-foreground); + background-color: var(--panel-tab-active-background); + opacity: 1; +} + +.panelset .panel { + display: none; +} + +.panelset .panel-active { + display: block; +} diff --git a/man/figures/libs/panelset/panelset.js b/man/figures/libs/panelset/panelset.js new file mode 100644 index 0000000..55f4aa2 --- /dev/null +++ b/man/figures/libs/panelset/panelset.js @@ -0,0 +1,270 @@ +/* global slideshow */ +(function () { + const ready = function (fn) { + /* MIT License Copyright (c) 2016 Nuclei */ + /* https://github.com/nuclei/readyjs */ + const completed = () => { + document.removeEventListener('DOMContentLoaded', completed) + window.removeEventListener('load', completed) + fn() + } + if (document.readyState !== 'loading') { + setTimeout(fn) + } else { + document.addEventListener('DOMContentLoaded', completed) + window.addEventListener('load', completed) + } + } + + ready(function () { + [...document.querySelectorAll('.panel-name')] + .map(el => el.textContent.trim()) + + const panelIds = {} + + const uniquePanelId = (name) => { + name = encodeURIComponent(name.toLowerCase().replace(/[\s]/g, '-')) + if (Object.keys(panelIds).includes(name)) { + name += ++panelIds[name] + } else { + panelIds[name] = 1 + } + return name + } + + const identifyPanelName = (item) => { + let name = 'Panel' + + // In R Markdown when header-attrs.js is present, we may have found a + // section header but the class attributes won't be duplicated on the tag + if ( + (item.tagName === 'SECTION' || item.classList.contains('section')) && + /^H[1-6]/.test(item.children[0].tagName) + ) { + name = item.children[0].textContent + item.classList.remove('panel-name') + item.removeChild(item.children[0]) + return name + } + + const nameDiv = item.querySelector('.panel-name') + if (!nameDiv) return name + + // In remarkjs the .panel-name span might be in a paragraph tag + // and if the

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 @@ - Presentation Ninja + {xaringanBuilder} - + @@ -14,11 +14,10 @@ diff --git a/man/figures/slides.png b/man/figures/slides.png new file mode 100644 index 0000000..3adde66 Binary files /dev/null and b/man/figures/slides.png differ diff --git a/man/figures/slides_social.png b/man/figures/slides_social.png index 0724914..170d790 100644 Binary files a/man/figures/slides_social.png and b/man/figures/slides_social.png differ diff --git a/man/figures/slides_thumbnail.png b/man/figures/slides_thumbnail.png deleted file mode 100644 index a6441b3..0000000 Binary files a/man/figures/slides_thumbnail.png and /dev/null differ