From 590c404e6edc546b9f38bdc76cd3bdb85d13baeb Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Mon, 5 Jul 2021 21:58:00 -0400 Subject: [PATCH] Add slide-source-panels --- static/slides/R/components.R | 34 ++++ .../slide-source-panels.css | 10 + .../slide-source-panels.js | 83 ++++++++ static/slides/demo-slide-source-panels.Rmd | 188 ++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 static/slides/assets/slide-source-panels/slide-source-panels.css create mode 100644 static/slides/assets/slide-source-panels/slide-source-panels.js create mode 100644 static/slides/demo-slide-source-panels.Rmd diff --git a/static/slides/R/components.R b/static/slides/R/components.R index 372ecf1..8b21eb4 100644 --- a/static/slides/R/components.R +++ b/static/slides/R/components.R @@ -302,3 +302,37 @@ live_coding <- function( ) knitr::asis_output(x) } + +#' Create Slide Source Panels +#' +#' Make sure that the slide to be included has a `name: ` property, +#' that's how the slide will be found. It also can't be a slide created with a +#' layout. +slide_source_panels <- function(slide_name, slide_panel = "Slide", source_panel = "Source") { + htmltools::tagList( + htmltools::withTags( + div( + class = "panel", + span(class = "panel-name", slide_panel), + div(`data-slide-name` = slide_name, `data-type` = "slide") + ) + ), + if (!is.null(source_panel)) { + htmltools::withTags( + div( + class = "panel", + span(class = "panel-name", source_panel), + div(`data-slide-name` = slide_name, `data-type` = "source") + ) + ) + }, + htmltools::htmlDependency( + name = "slide-source-panels", + version = "0.0.1", + src = here::here("static", "slides", "assets", "slide-source-panels"), + script = "slide-source-panels.js", + stylesheet = "slide-source-panels.css", + all_files = FALSE + ) + ) +} diff --git a/static/slides/assets/slide-source-panels/slide-source-panels.css b/static/slides/assets/slide-source-panels/slide-source-panels.css new file mode 100644 index 0000000..af36af0 --- /dev/null +++ b/static/slides/assets/slide-source-panels/slide-source-panels.css @@ -0,0 +1,10 @@ +[data-slide-name] .remark-slide-content { + --scale: 0.8; + position: absolute; + width: 1210px; + height: 681px; + transform: scale(var(--scale)); + transform-origin: top left; + border: 2px solid #ddd; + top: calc((681px - (681px * var(--scale))) / 2); +} diff --git a/static/slides/assets/slide-source-panels/slide-source-panels.js b/static/slides/assets/slide-source-panels/slide-source-panels.js new file mode 100644 index 0000000..2c4b85d --- /dev/null +++ b/static/slides/assets/slide-source-panels/slide-source-panels.js @@ -0,0 +1,83 @@ +(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 () { + const placeholders = document.querySelectorAll('.remark-slides-area [data-slide-name]') + + if (!placeholders.length) { + return; + } + + function getSlideSource (name, keepName) { + let src = '---\n' + src += document + .getElementById('source') + .textContent.split(/(^|\n)---\n/) + .filter(s => s.match(RegExp(`name: ?${name}`))) + .join() + + if (!keepName) { + src = src.replace(/\nname: ?[^\n]+/, '') + } + + return src + } + + function appendSlideSource (el) { + console.log(el.dataset) + const theCode = getSlideSource(el.dataset.slideName, el.dataset.keepName) + const pre = document.createElement('pre') + const code = document.createElement('code') + code.classList = 'markdown remark-code' + theCode.split('\n').forEach(function(line) { + const div = document.createElement('div') + div.classList = 'remark-code-line' + div.innerText = line + code.appendChild(div) + }) + // code.innerText = theCode + pre.appendChild(code) + + el.appendChild(pre) + return el + } + + function getSlideNodeClone (name) { + const slide = document.getElementById('slide-' + name) + const newSlide = slide.cloneNode(true) + newSlide.removeAttribute('id') + return newSlide + } + + function appendSlideNode (el) { + const slide = getSlideNodeClone(el.dataset.slideName) + el.appendChild(slide) + return el + } + + placeholders.forEach(function (el) { + switch (el.dataset.type) { + case 'source': + appendSlideSource(el) + break + case 'slide': + default: + appendSlideNode(el) + } + }) + }) +})() diff --git a/static/slides/demo-slide-source-panels.Rmd b/static/slides/demo-slide-source-panels.Rmd new file mode 100644 index 0000000..d650e39 --- /dev/null +++ b/static/slides/demo-slide-source-panels.Rmd @@ -0,0 +1,188 @@ +--- +scene: 0 +title: "Demo Slides" +subtitle: "A work in progress!" +author: "Garrick Aden-Buie & Silvia Canelón" +date: '2021-07-07' +output: + xaringan::moon_reader: + lib_dir: "assets/libs" + css: + - assets/css/js4shiny-xaringan-base.css + - assets/css/tachyons.min.css + - assets/css/js4shiny-xaringan-extra.css + includes: + after_body: assets/html/js4shiny-includes.html + seal: false + chakra: assets/js/remark.0.14.1.min.js + mathjax: NULL + nature: + ratio: 16:9 + slideNumberFormat: "%current%" + highlightStyle: docco + highlightLines: true + countIncrementalSlides: true +--- + +class: title + +```{r setup, include=FALSE} +options(htmltools.dir.version = FALSE) +knitr::opts_chunk$set( + fig.width = 10, + fig.height = 6, + fig.retina = 2, + warning = FALSE, + message = FALSE +) +source(here::here("static", "slides", "R", "components.R")) +# use_placeholders(TRUE, TRUE) +xaringanExtra::use_xaringan_extra(c("tile_view", "panelset", "share_again")) +xaringanExtra::use_editable(id = rmarkdown::metadata$title) +``` + +```{r js4shiny, echo=FALSE} +js4shiny::html_setup(stylize = c("fonts", "variables", "code")) +``` + +`r title_slide()` + +--- +name: first-demo +class: fullscreen + +.panelset.sideways.pl2.h-100[ + +```{r echo=FALSE} +# this function was added to components.R +# it creates two panels, one with a copy of the slide (found by name) +# and another panel with the markdown source for the slide (as seen by remark) +# (If the slide source is complicated, you can set source_panel = NULL and +# manually add the source code in a panel.) +slide_source_panels("fonts") +``` + +] + +--- +class: fullscreen + +.panelset.sideways.pl2.h-100[ + +```{r echo=FALSE} +slide_source_panels("html-resources") +``` + +.panel[.panel-name[Notes] + +## Good? + +## Bad? + +## What do you think? + +The slides are actually in the deck in a later section. +I put them at the end in an "Appendix". + +The source is pulled from the compiled source, so you can't see R Markdown bits. + +] + +] + +--- +class: fullscreen + +.panelset.sideways.pl2.h-100[ + +```{r echo=FALSE} +slide_source_panels("break-javascript") +``` + +.panel[.panel-name[Notes] + +This slide doesn't look _perfect_ so somethings that rely on absolute positioning may be a little bit weird. Most basic xaringan stuff will probably look okay, though. + +] + +] + +--- +class: fullscreen + +.panelset.sideways.pl2.h-100[ + +```{r echo=FALSE} +slide_source_panels("first-demo", source_panel = NULL) +``` + +.panel[.panel-name[Source] + +This is where it gets **meta**. +We're looking at a slide we saw earlier in the deck! + +This is the code I used to create that slide. + +````markdown +--- +name: first-demo +class: fullscreen + +.panelset.sideways.pl2.h-100[ + +```{r echo=FALSE}`r ''` +slide_source_panels("fonts") +``` + +] +```` + +I had to manually make this **Source** panel because it includes an Rmd chunk. + +] + +] +--- +class: center middle + +# Appendix + +--- +class: break break-javascript +name: break-javascript + +# JavaScript inspired break + +.absolute.top-1.left-1[break break-javascript] + +--- +name: fonts + +# Fonts + +.mh-auto.w-80.f5.mt4[ +.f-lato[Lato (body)] .fr.code[.f-lato] + +.f-nunito[Nunito Sans] .fr.code[.f-nunito] + +.f-marker[Marker] .fr.code[.f-marker] + +.f-source-code[Source Code Pro] .fr.code[.f-source-code] +] + +--- +name: html-resources + +# HTML Resources + +* Mastering Shiny: Advanced UI
+ https://mastering-shiny.org/advanced-ui.html + +* FrontEnd Masters Handbook
+ https://frontendmasters.com/books/front-end-handbook/2019/ + +* Interneting is Hard
+ https://internetingishard.com/ + +* HTML Semantics Cheat Sheet
+ https://learn-the-web.algonquindesign.ca/topics/html-semantics-cheat-sheet/