excluding certain slides while rendering
I often make slide decks (I still use Xaringan, but this will also be true when I move to Quarto for making my slides) that include several slides I do not want to include in a pdf handout. So, I'll make an extensive set of slides and render those to html for my actual live presentation. But, when I share a pdf handout of the presentation afterwards, I usually want to exclude several slides (e.g., slides with copyrighted material, slides with the password for the wifi at a conference, slides that contain video, etc.).
It would be great if I could add a class to a slide that renderthis uses to skip it when building the pdf. For example, something like this:
---
class: not_handout
blabla content blabla
---
and then use: renderthis::to_pdf("slides.Rmd", skip = "not_handout")
Of course, if there already is some way to hack this, that would be great too.
Hmm, adding some kind of class like that would probably require a change to the xaringan package as all renderthis does is call the package to render the slides. renderthis does have a slides argument in some functions, e.g. to_png("slides.pdf", slides = c(1, 3, 5)), but not to_pdf(). So if you knew the slide numbers you wanted to include this could be used, but it would only return a set of pngs, not the pdf. We could probably add this slides argument though to the to_pdf() function. It's certainly less ideal though because you'd have to keep track of all the slide numbers, and if you changed one thing like insert a single slide then all those numbers are off, so the class approach would really be much nicer. I just don't think that's something renderthis could address.
Btw this is a good idea, so I would reach out to the Quarto team too as they could probably add something like this to the revealjs slides.
Thanks! This helps. It should be fairly easy to write a helper function that returns the slides with the specific class. That way, it is not really much of an inconvenience to have to "manually" extract the slide numbers with the class. It could automatically return the slide numbers, so no bookkeeping is needed when slides are added to or removed to the whole deck.
It would be awesome if the slides argument could be included in to_pdf and in to_html so that published slide decks can be curated.
Here is one simple piece of code I whipped together to extract the slide numbers that have the class that I would like to exclude
slides_to_exclude <- function(rmd, class = "no_handout") {
txt <- readLines(rmd_file)
# identify the slides
all_slides <- which(txt == "---")
n_slides <- length(all_slides)
class_line <- which(grepl(paste0("class[:].*", class), txt))
# which slide is this class on
slides_no <- findInterval(class_line, all_slides)
# correct for opening slide and YAML
seal <- any(sapply(1:(all_slides[2] - 1), function(z) grepl("seal[:] false", txt[z])))
if (seal) {
slides_no <- slides_no - 2
} else {
slides_no <- slides_no - 1
}
slides_no
}
With the help of that, it would be straightforward to run something like:
renderthis::to_pdf(rmdfile, slides = -slides_to_exclude(rmdfile, class = "no_handout"))
renderthis::to_html(rmdfile, slides = -slides_to_exclude(rmdfile, class = "no_handout"))
Of course, the slides_to_exclude() function can be improved upon, but something like this should work and be a life-saver
It should be fairly easy to write a helper function that returns the slides with the specific class. That way, it is not really much of an inconvenience to have to "manually" extract the slide numbers with the class. It could automatically return the slide numbers, so no bookkeeping is needed when slides are added to or removed to the whole deck.
This is the kind of thing that's easy to get right for one particular slide deck and hard to get right for all slide decks all the time. We're using browser automation via chromote for complex slides and doing the filtering in the browser is the only reliable way to ensure you're hiding the slides you want to hide.
That said, this could be relatively easy with CSS that could be added to the slide deck. (To be clear, added by authors to their own stylesheets and not injected by renderthis.) A @media print {} query combined with an appropriate display: none would work:
@media print {
.remark-slide-container:has(.remark-slide-content.no_handout) {
display: none;
}
}
Yes, Garrick, I agree that the function may not work for every slide deck. The point was that I am OK with having to provide slide numbers to the to_pdf and to_html functions myself, because if I don't want to manually keep track of which slides I want to exclude (like the user has to do in to_png as well), I can easily write a little function that does it for me on my slide deck. I definitely did not expect you to include such a function in the package.
Anyway, I am suggesting that it would be very useful to have a slides argument in to_pdf and to_html, so users can decide to exclude certain slides when printing to pdf or to html, just like in the to_png function that is already in the renderthis package.
to fix your trouble check this solution click maybe this will solve your problem.
Ya'll is this spam?
Hi, I have been trying to use to_pdf to render panelsets in my xaringan slides and cannot figure out how to make it work with the changes to chrome (headless). I have updated my chromote package, not sure what else to do. Any help is appreciated.
to_pdf("u3-d01-viz-num.html", complex_slides = TRUE) Error in onRejected(reason) : code: -32000 message: Browser window not found
Have you looked over the setup configuration for your browser?
Thanks for the reply! I had not before writing, but tried what was suggested but still getting the same error. I am pretty sure it has something to do with chrome going headless (whatever that means... ). This function used to work for me before with panelsets
Sys.setenv(PAGEDOWN_CHROME = "C:\Program Files\Google\Chrome\Application\chrome.exe") Sys.setenv(CHROMOTE_CHROME = "C:\Program Files\Google\Chrome\Application\chrome.exe")
to_pdf("u3-d01-viz-num.html",complex_slides = TRUE) Error in onRejected(reason) : code: -32000 message: Browser window not found
There have been quite a few changes in Chrome in the last year. We just released a new version of chromote that may resolve your issues. You can read about it here: https://shiny.posit.co/blog/posts/chromote-0.5.0/
If just updating chromote doesn't do the trick, try this
library(chromote) #v0.5.0
local_chrome_version(binary = "chrome-headless-shell")
# ... renderthis code ...
Yay! Thanks so much! The local_chrome_version line did the trick. I had updated the chromote package to version 0.5.0 and also tried local_chrome_version earlier, but not with this particular binary "chrome-headless-shell".
Just to be sure, I notice that I need to use the local_chrome_version line before every call of renderthis, even within a single R session. Is this accurate?
Great to hear!
I notice that I need to use the local_chrome_version line before every call of renderthis, even within a single R session. Is this accurate?
No, you should only need to do this once per session.
Hm, ok. I did need to type it again but I am leaving it alone for now.. :) Thanks again