slide timing: per-speaker timing comments activate speaker view pacing
Port the Google-Docs slide workflow convention: timing comments like
<!-- JD 00:30 --> (speaker code plus MM:SS/HH:MM:SS/seconds duration, or
just <!-- 00:30 --> for single-speaker talks) are converted into
data-timing attributes on the rendered slides' <section> elements, and
the calculated grand total is passed to reveal.js as the totalTime
config value, activating the pacing timer in the speaker view. A
document-supplied totalTime or defaultTiming takes precedence.
A per-speaker time summary is printed during rendering; the new
slide_timing() function computes slide, speaker, and grand totals
directly from an .Rmd source file without rendering it.
Change-Id: I89d37baab06c6ee8be7ab777a70b9b21295c8780
diff --git a/R/revealjs_presentation.R b/R/revealjs_presentation.R
index 21212a7..c35cdeb 100644
--- a/R/revealjs_presentation.R
+++ b/R/revealjs_presentation.R
@@ -33,6 +33,47 @@
#' ```
#' to create notes only viewable in presentation mode.
#'
+#' ## Slide timing
+#'
+#' Speaker time can be planned per slide and per speaker by adding a comment
+#' with a speaker code and the expected duration (in `MM:SS`, `HH:MM:SS`, or
+#' plain seconds format) anywhere inside a slide:
+#'
+#' ```markdown
+#' ## My slide title
+#'
+#' Some content
+#'
+#' <!-- MK 00:30 -->
+#' ```
+#'
+#' This means Marc Kupietz will need 30 seconds for that slide. For talks
+#' presented by a single speaker, the speaker code can be omitted:
+#' `<!-- 00:30 -->`.
+#'
+#' Typically you start from a known total time budget and adjust the
+#' individual slides to it. You can set this budget yourself with the
+#' reveal.js `totalTime` option (in seconds):
+#'
+#' ```yaml
+#' output:
+#' revealjs.ids::revealjs_presentation:
+#' reveal_options:
+#' totalTime: 3600 # one hour
+#' ```
+#'
+#' During rendering, comments are converted into `data-timing` attributes on
+#' the slides' `<section>` elements (several speakers per slide are summed
+#' up), and the calculated grand total is passed to reveal.js as the
+#' `totalTime` config value. This activates the pacing timer in the
+#' [speaker view](https://revealjs.com/speaker-view/), which shows how you
+#' are doing relative to your plan. A summary of the total time per speaker
+#' is printed during rendering. If the document sets `totalTime` or
+#' `defaultTiming` itself (via `reveal_options`), those take precedence.
+#'
+#' The function [slide_timing()] computes these totals directly from an
+#' `.Rmd` source file without rendering it.
+#'
#' ### Search
#'
#' When opt-in, it is possible to show a search box when pressing `CTRL + SHIFT +
@@ -343,6 +384,21 @@
args
}
+ # post-processor converting <!-- MK 00:30 --> speaker timing comments into
+ # data-timing attributes on the enclosing sections (activating the pacing
+ # timer of the notes plugin) and reporting per-speaker totals
+ post_processor <- function(metadata, input_file, output_file, clean, verbose) {
+ lines <- readLines(output_file, warn = FALSE, encoding = "UTF-8")
+ result <- apply_timing_attributes(lines)
+ comments <- attr(result, "comments")
+ if (nrow(comments) > 0) {
+ result <- inject_total_time(result, sum(comments$seconds))
+ writeLines(enc2utf8(result), output_file, useBytes = TRUE)
+ message(timing_report_message(comments))
+ }
+ output_file
+ }
+
# return format
output_format(
knitr = knitr_options_html(fig_width, fig_height, fig_retina, keep_md),
@@ -354,6 +410,7 @@
keep_md = keep_md,
clean_supporting = self_contained,
pre_processor = pre_processor,
+ post_processor = post_processor,
base_format = html_document_base(
lib_dir = lib_dir,
self_contained = self_contained,