Skip to content

Commit

Permalink
Merge pull request #64 from jhelvy/fix/63-find-chrome
Browse files Browse the repository at this point in the history
Reduce exposure to CRAN checks and add initial Quarto support
  • Loading branch information
jhelvy authored Sep 29, 2022
2 parents 221e050 + 41121e6 commit 5b4c726
Show file tree
Hide file tree
Showing 47 changed files with 617 additions and 295 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/check-standard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ jobs:
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-pandoc@v2
- uses: quarto-dev/quarto-actions/setup@v2
- run: 'quarto --version'

- if: runner.os == 'Linux'
run: |
Expand Down
3 changes: 3 additions & 0 deletions CRAN-SUBMISSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Version: 0.2.0
Date: 2022-09-23 16:01:37 UTC
SHA: 16da193173108b915de47e58503aa51459bb8e1c
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: renderthis
Title: Render Slides to Different Formats
Version: 0.1.0
Version: 0.2.0
Authors@R:
c(person(given = "John",
family = "Helveston",
Expand Down Expand Up @@ -32,6 +32,7 @@ Imports:
magick (>= 2.7.1),
pagedown,
progress,
quarto,
rmarkdown,
withr,
xaringan,
Expand All @@ -48,6 +49,6 @@ Suggests:
Config/testthat/edition: 3
Config/Needs/website: xaringanExtra
Encoding: UTF-8
RoxygenNote: 7.2.0
RoxygenNote: 7.2.1
Roxygen: list(markdown = TRUE)
VignetteBuilder: knitr
11 changes: 9 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# renderthis 0.1.0
# renderthis 0.2.0

- Addresses several previous issues related to a note about a Crashpad file being generated from CI checks on Ubuntu.
- Implements initial support for rendering Quarto revealjs presentations.

# renderthis 0.1.1

# renderthis 0.0.1
- Fixes a bug (#63) by checking that the path returned by find_chrome() actually exists.

# renderthis 0.1.0

* Initial version, most functionality copied / modified from v0.0.9 of xaringanBuilder
* Added a `NEWS.md` file to track changes to the package.
12 changes: 6 additions & 6 deletions R/all.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#' Build xaringan slides to multiple outputs.
#' Build slides to multiple outputs.
#'
#' @description
#' `r lifecycle::badge("deprecated")`
#'
#' Build xaringan slides to multiple outputs. Options are `"html"`, `"social"`
#' `"pdf"`, `"png"`, `"gif"`, `"mp4"`, and `"pptx"`. See each individual
#' build_*() function for details about each output type.
#' Build slides to multiple outputs. Options are `"html"`, `"social"` `"pdf"`,
#' `"png"`, `"gif"`, `"mp4"`, and `"pptx"`. See each individual build_*()
#' function for details about each output type.
#'
#' @param input Path to Rmd file of xaringan slides.
#' @param input Path to an `.Rmd` or `.qmd` file of slides.
#' @param include A vector of the different output types to build. Options are
#' `"html"`, `"social"`, `"pdf"`, `"png"`, `"gif"`, `"mp4"`, and `"pptx"`.
#' Defaults to `c("html", "social", "pdf", "png", "gif", "mp4", "pptx")`.
Expand Down Expand Up @@ -37,7 +37,7 @@ build_all <- function(
lifecycle::deprecate_warn("0.1.0", "build_all()")

# Check that input file has the correct extension
assert_path_ext(input, "rmd")
assert_path_ext(input, c("rmd", "qmd"))

# Build hierarchy:
#
Expand Down
25 changes: 12 additions & 13 deletions R/gif.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#' Render slides as a gif file.
#' Render slides as a GIF file.
#'
#' Render slides as a gif video file. The function renders to the pdf,
#' converts each slide in the pdf to a png, and then converts the deck of
#' png files to a gif file.
#' Render slides as a GIF video file. The function renders to the PDF,
#' converts each slide in the PDF to a PNG, and then converts the deck of
#' PNG files to a GIF file.
#'
#' @param from Path to a Rmd file, html file, pdf file, or a url. If `from`
#' is a url to slides on a website, you must provide the full url
#' @param from Path to an `.Rmd`, `.qmd`, `.html`, `.pdf` file, or a URL. If
#' `from` is a URL to slides on a website, you must provide the full URL
#' ending in `".html"`.
#' @param to Name of the output gif file.
#' @param density Resolution of the resulting pngs in each slide file. Defaults
#' @param to Name of the output `.gif` file.
#' @param density Resolution of the resulting PNGs in each slide file. Defaults
#' to `100`.
#' @param slides A numeric or integer vector of the slide number(s) to include
#' in the gif, or one of `"all"`, `"first"`, or `"last"`. Negative integers
#' in the GIF, or one of `"all"`, `"first"`, or `"last"`. Negative integers
#' select which slides _not_ to include. Defaults to `"all"`, in which case
#' all slides are included.
#' @param fps Frames per second of the resulting gif file.
#' @param fps Frames per second in the animated GIF.
#' @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
Expand All @@ -27,7 +27,7 @@
#' Only used if `complex_slides = TRUE` or `partial_slides = TRUE`.
#' @inheritParams to_png
#'
#' @return Slides are rendered as a gif file.
#' @return Slides are rendered as a `.gif` file.
#'
#' @example man/examples/examples_gif.R
#'
Expand All @@ -52,8 +52,7 @@ to_gif <- function(
}

# Check input and output files have correct extensions
assert_path_ext(input, c("rmd", "html", "pdf"))
assert_path_ext(output_file, "gif")
assert_path_ext(output_file, "gif", arg = "to")

# Render html and / or pdf (if input is not pdf)
step_pdf <- input
Expand Down
66 changes: 48 additions & 18 deletions R/html.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#' Render slides as html file.
#'
#' Render xaringan or quarto slides as an html file. For xaringan slides, it
#' is the same thing as [rmarkdown::render()] with
#' `output_format = "xaringan::moon_reader"` except that the `self_contained`
#' option is forced to `TRUE` if the HTML file is built into a directory other
#' than the one containing `from`.
#' Render xaringan or Quarto slides as an html file. In generally, it is the
#' same thing as [rmarkdown::render()] or [quarto::quarto_render()] except that
#' the `self_contained` option is forced to `TRUE` if the HTML file is built
#' into a directory other than the one containing `from`.
#'
#' @param from Path to an Rmd file of xaringan slides.
#' @param from Path to an `.Rmd` or `.qmd` file.
#' @param to The name of the output file. If using `NULL` then the
#' output file name will be based on file name for the `from` file. If a file
#' name is provided, a path to the output file can also be provided.
Expand All @@ -16,14 +15,15 @@
#' you can share with others, but it may be very large. This feature is
#' enabled by default when the `to` file is written in a directory other
#' than the one containing the `from` R Markdown file.
#' @param rmd_args A list of arguments passed to [rmarkdown::render()].
#' @param render_args A list of arguments passed to [rmarkdown::render()] or
#' [quarto::quarto_render()].
#'
#' @return Slides are rendered as an html file.
#' @return Slides are rendered as an `.html` file.
#'
#' @example man/examples/examples_html.R
#'
#' @export
to_html <- function(from, to = NULL, self_contained = FALSE, rmd_args = NULL) {
to_html <- function(from, to = NULL, self_contained = FALSE, render_args = NULL) {

input <- from
output_file <- to
Expand All @@ -35,14 +35,21 @@ to_html <- function(from, to = NULL, self_contained = FALSE, rmd_args = NULL) {
}

# Check input and output files have correct extensions
assert_path_ext(input, "rmd")
assert_path_ext(output_file, "html")
assert_path_ext(input, c("rmd", "qmd"), arg = "from")
assert_path_ext(output_file, "html", arg = "to")

input <- fs::path_abs(input)
output_file <- fs::path_abs(output_file)

rmd_args <- build_html_rmd_args(input, output_file, self_contained, rmd_args)
self_contained <- rmd_args$output_options$self_contained
if (test_path_ext(input, "rmd")) {
render_args <- build_html_rmd_args(input, output_file, self_contained, render_args)
self_contained <- render_args$output_options$self_contained
render_fn <- rmarkdown::render
} else {
render_args <- build_html_qmd_args(input, output_file, self_contained, render_args)
self_contained <- "--self-contained" %in% render_args$pandoc_args
render_fn <- quarto::quarto_render
}

# Render html from rmd
#
Expand All @@ -55,20 +62,21 @@ to_html <- function(from, to = NULL, self_contained = FALSE, rmd_args = NULL) {
withr::local_dir(fs::path_dir(input))

if (self_contained) {
rmd_args$output_file <- path_from(
fs::path_file(rmd_args$output_file), "html", temporary = TRUE
render_args$output_file <- path_from(
fs::path_file(render_args$output_file), "html", temporary = TRUE
)
withr::defer(
fs::file_move(rmd_args$output_file, output_file),
fs::file_move(render_args$output_file, output_file),
priority = "first"
)
}


do.call(rmarkdown::render, rmd_args)
do.call(render_fn, render_args)
},
error = cli_build_failed(proc)
)

invisible(output_file)
}

build_html_rmd_args <- function(input, output_file, self_contained = FALSE, rmd_args = NULL) {
Expand All @@ -90,6 +98,28 @@ build_html_rmd_args <- function(input, output_file, self_contained = FALSE, rmd_
rmd_args
}

build_html_qmd_args <- function(input, output_file, self_contained = FALSE, qmd_args = NULL) {
qmd_args <- c(list(), qmd_args)
qmd_args$input <- fs::path_file(input)
qmd_args$output_file <- fs::path_file(output_file)

self_contained <-
isTRUE(self_contained) ||
self_contained_is_required(input, output_file)

if (self_contained) {
# TODO: this argument is deprecated in latest pandoc, we should check
# for pandoc version and pick best version
qmd_args$pandoc_args <- c("--self-contained")
}

if (is.null(qmd_args$quiet)) {
qmd_args$quiet <- TRUE
}

qmd_args
}

self_contained_is_required <- function(input, output_file) {
if (in_same_directory(input, output_file)) {
return(FALSE)
Expand Down
19 changes: 8 additions & 11 deletions R/mp4.R
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
#' Render slides as a mp4 video file.
#' Render slides as an MP4 video file.
#'
#' Render slides as a mp4 video file. The function renders to the pdf,
#' Render slides as an MP4 video file. The function renders to the pdf,
#' converts each slide in the pdf to a png, and then converts the deck of
#' png files to a mp4 video file.
#' png files to a MP4 video file.
#'
#' @param from Path to a Rmd file, html file, pdf file, or a url. If `from`
#' is a url to slides on a website, you must provide the full url
#' ending in `".html"`.
#' @param to Name of the output mp4 file.
#' @param to Name of the output `.mp4` file.
#' @param slides A numeric or integer vector of the slide number(s) to include
#' in the mp4, or one of `"all"`, `"first"`, or `"last"`. Negative integers
#' select which slides _not_ to include. Defaults to `"all"`, in which case
#' all slides are included.
#' @param fps Frames per second of the resulting mp4 file.
#' @param fps Frames per second of the resulting `.mp4` file.
#' @inheritParams to_gif
#' @inheritParams to_png
#' @inheritParams to_pdf
#'
#' @return Slides are rendered as an mp4 file.
#' @return Slides are rendered as an `.mp4` file.
#'
#' @example man/examples/examples_mp4.R
#'
Expand Down Expand Up @@ -44,8 +42,7 @@ to_mp4 <- function(
}

# Check input and output files have correct extensions
assert_path_ext(input, c("rmd", "html", "pdf"))
assert_path_ext(output_file, "mp4")
assert_path_ext(output_file, "mp4", arg = "to")

# Render html and / or pdf (if input is not pdf)
step_pdf <- input
Expand Down
31 changes: 20 additions & 11 deletions R/pdf.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#' Render slides as pdf file.
#' Render slides as PDF file.
#'
#' Render slides as a pdf file. Requires a local installation of Chrome.
#' Render slides as a PDF file. Requires a local installation of Chrome.
#' If you set `complex_slides = TRUE` or `partial_slides = TRUE`, you will also
#' need to install the {chromote} and {pdftools} packages.
#'
#' @param from Path to a Rmd file, html file, pdf file, or a url. If `from`
#' is a url to slides on a website, you must provide the full url
#' ending in `".html"`.
#' @param to The name of the output file. If `NULL` (the default) then
#' @param from Path to an `.Rmd`, `.qmd`, `.html` file, or a URL. If `from` is a
#' URL to slides on a website, you must provide the full URL ending in
#' `".html"`.
#' @param to The name of the output `.pdf` file. If `NULL` (the default) then
#' the output filename will be based on filename for the `from` file. If a
#' filename is provided, a path to the output file can also be provided.
#' @param complex_slides For "complex" slides (e.g. slides with panelsets or
Expand All @@ -25,7 +25,7 @@
#' if the `to` file is written into the same directory as the `from` argument,
#' otherwise the intermediate file isn't kept.
#'
#' @return Slides are rendered as a pdf file.
#' @return Slides are rendered as a `.pdf` file.
#'
#' @example man/examples/examples_pdf.R
#'
Expand All @@ -46,29 +46,38 @@ to_pdf <- function(

assert_path_exists(input)

complex_slides <- complex_slides || partial_slides

if (complex_slides && test_path_ext(input, "qmd")) {
cli::cli_abort(c(
"Complex PDF rendering is currently only available for xaringan slides in {.path .Rmd} documents.",
"x" = "{.strong input}: {.val {input}}"
))
}

if (is.null(output_file)) {
output_file <- path_from(input, "pdf")
}

# Check input and output files have correct extensions
assert_path_ext(input, c("rmd", "html"))
assert_path_ext(output_file, "pdf")
assert_path_ext(output_file, "pdf", arg = "to")

if (is.null(keep_intermediates)) {
keep_intermediates <- in_same_directory(input, output_file)
}

# Render html (if input is rmd)
step_html <- input
if (test_path_ext(input, "rmd")) {
if (!test_path_ext(input, "html")) {
step_html <- path_from(output_file, "html", temporary = !keep_intermediates)
to_html(from = input, to = step_html)
}

# Render pdf from html
if (complex_slides | partial_slides) {
if (complex_slides) {
to_pdf_complex(path_from(step_html, "url"), output_file, partial_slides, delay)
} else {
assert_path_ext(input, c("qmd", "rmd", "html"), arg = "from")
to_pdf_simple(step_html, output_file)
}
}
Expand Down
Loading

0 comments on commit 5b4c726

Please sign in to comment.