Introduce partner and funder logos
Change-Id: I71e00aaa51c2dffe74335c7c4f170e8d507356d6
diff --git a/R/revealjs_presentation.R b/R/revealjs_presentation.R
index 68d0733..05c8131 100644
--- a/R/revealjs_presentation.R
+++ b/R/revealjs_presentation.R
@@ -152,6 +152,28 @@
#' toggleNotesButton: true
#' toggleChalkboardButton: true
#' ```
+#' ## Title slide: QR code and additional logos
+#'
+#' Three optional yaml entries personalise the title slide for external
+#' audiences (ported from \pkg{posterdown.ids}):
+#'
+#' * `website: <url>` -- a linked QR code pointing to the URL is placed in
+#' the top left of the title slide. Uses the \pkg{qrcode} package.
+#' * `partner_logo: <path-or-url>` -- when a presentation is given by
+#' authors from two institutions, the partner institution's logo is shown
+#' next to the IDS logo, in the top right of every slide.
+#' * `funder_logo: <path-or-url>` -- a funder logo (e.g. "Text+") is placed
+#' in the bottom left of the title slide, opposite the Leibniz
+#' Gemeinschaft membership logo. It is lifted above the footer band on
+#' print (pdf) pages.
+#'
+#' Local logo files (svg, png, jpg, gif, webp) are embedded in the html as
+#' data URIs, so they do not need to be shipped with the presentation; http
+#' URLs are used as-is. A QR code anywhere else on a slide can be produced
+#' with [qrlink()] from inline R code. The navigation chrome (arrows, slide
+#' number, menu button) is hidden on the title slide for a bare first
+#' impression.
+#'
#' ## Bibliography and citations
#'
#' Documents with a `bibliography:` in their YAML header are formatted with
@@ -429,6 +451,21 @@
# highlight
args <- c(args, pandoc_highlight_args(highlight, default = "pygments"))
+ # website entry: place a linked QR code (inline SVG) in the top left of
+ # the title slide
+ if (!is.null(metadata$website)) {
+ args <- c(args, pandoc_variable_arg("website-qr", qrlink(metadata$website)))
+ }
+
+ # partner / funder institution logos: local files are inlined as data
+ # URIs so they resolve correctly in CSS and stay embedded in the output
+ if (!is.null(metadata$partner_logo)) {
+ args <- c(args, pandoc_variable_arg("partner-logo-src", logo_uri(metadata$partner_logo)))
+ }
+ if (!is.null(metadata$funder_logo)) {
+ args <- c(args, pandoc_variable_arg("funder-logo-src", logo_uri(metadata$funder_logo)))
+ }
+
# default to the bundled IDS citation style unless the document
# specifies a style of its own
if (is.null(metadata$csl)) {
diff --git a/R/utils.R b/R/utils.R
index 0c13ae5..4f2c21f 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -46,3 +46,76 @@
}
pandoc_variable_arg(option, value)
}
+
+# Resolve a logo image (yaml entries `partner_logo` / `funder_logo`) to a URL
+# usable inside CSS: http(s) and data URLs pass through unchanged, local
+# files are inlined as base64 data URIs. Inlining is required: CSS background
+# URLs would resolve relative to the theme stylesheet, and document-relative
+# files would be left behind when the rendered html is deployed elsewhere.
+logo_uri <- function(path) {
+ if (grepl("^(https?|data):", path)) {
+ return(path)
+ }
+ if (!file.exists(path)) {
+ stop("Logo file not found: ", path, call. = FALSE)
+ }
+ ext <- tolower(tools::file_ext(path))
+ mime <- switch(ext,
+ svg = "image/svg+xml", png = "image/png", jpg = , jpeg = "image/jpeg",
+ gif = "image/gif", webp = "image/webp",
+ stop("Unsupported logo format '", ext, "' (use svg, png, jpg, gif or webp)",
+ call. = FALSE
+ )
+ )
+ if (!requireNamespace("base64enc", quietly = TRUE)) {
+ stop("Package \"base64enc\" needed to embed local logo files. Please install it.",
+ call. = FALSE
+ )
+ }
+ sprintf("data:%s;base64,%s", mime, base64enc::base64encode(path))
+}
+
+#' HTML code for a linked QR code
+#'
+#' Generates a QR code (inline SVG) linking to the given URL and returns the
+#' corresponding HTML code, so a QR code can be placed anywhere in a
+#' presentation with inline R code.
+#'
+#' The `website` YAML entry of [revealjs_presentation()] uses this to
+#' place a linked QR code in the top left of the title slide.
+#'
+#' @param url Target URL for the QR code
+#' @param logo Optional path to a logo image to place in the center of the QR
+#' code
+#' @param text Optional caption displayed below the QR code (alias:
+#' `caption`)
+#' @param caption Alias for `text`
+#' @return Character string with HTML code for a linked QR code
+#' @export
+qrlink <- function(url, logo = NULL, text = NULL, caption = text) {
+ if (!requireNamespace("qrcode", quietly = TRUE)) {
+ stop("Package \"qrcode\" needed to generate QR codes. Please install it.",
+ call. = FALSE
+ )
+ }
+ tmp <- tempfile(fileext = ".svg")
+ qrcode <- qrcode::qr_code(url, ecl = if (is.null(logo)) "L" else "H")
+ if (!is.null(logo)) {
+ qrcode <- qrcode::add_logo(qrcode, logo, ecl = "L")
+ }
+ qrcode::generate_svg(qrcode, tmp, show = FALSE)
+
+ cap_html <- if (!is.null(caption) && nchar(trimws(caption)) > 0) {
+ sprintf('<span class="qrcode-caption">%s</span>', caption)
+ } else {
+ ""
+ }
+
+ svg <- gsub("\r?\n|\r", "", readChar(tmp, 1e7))
+ qr <- sprintf('<a class="qrcode" href="%s">%s</a>', url, svg)
+ if (nchar(cap_html) > 0) {
+ paste0('<div class="qrcode-container">', qr, cap_html, "</div>")
+ } else {
+ qr
+ }
+}