Skip to content

Instantly share code, notes, and snippets.

@mattmoss
Last active October 5, 2017 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattmoss/f8fb4ec755bca137c74980240b576604 to your computer and use it in GitHub Desktop.
Save mattmoss/f8fb4ec755bca137c74980240b576604 to your computer and use it in GitHub Desktop.
Building a reveal.js slideshow w/ Groovy
import groovy.xml.MarkupBuilder
class Slideshow {
Map options
StringWriter writer = new StringWriter()
MarkupBuilder markup = new MarkupBuilder(writer)
boolean inGroup = false
boolean inSlide = false
static build(Map options, @DelegatesTo(Slideshow) Closure cl) {
def ss = new Slideshow()
ss.setOptions(options ?: [:])
ss.markup.doubleQuotes = true
ss.document cl
ss.export()
}
protected export() {
println writer.toString()
}
protected scripts() {
// TODO: generate more of the content here.
markup.script src: 'lib/js/head.min.js'
markup.script src: 'js/reveal.js'
markup.script """
Reveal.initialize({
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true,
callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
Reveal.configure({
slideNumber: true
});
"""
}
protected document(@DelegatesTo(Slideshow) Closure cl) {
cl.delegate = this
writer.println '<!doctype html>'
markup.html {
head {
meta(charset: 'utf-8')
meta(name: 'viewport',
content: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no')
if (options?.title) {
title(options.title)
}
link(rel: 'stylesheet', href: 'css/reveal.css')
link(rel: 'stylesheet', href: "css/theme/${options?.theme ?: 'white'}.css")
link(rel: 'stylesheet', href: 'lib/css/zenburn.css')
// TODO: mkp.comment printing/pdf exports
style {
}
}
body('') {
div('class': 'reveal') {
div('class': 'slides') {
cl.call()
}
}
scripts()
}
}
}
def group(@DelegatesTo(Slideshow) Closure cl) {
cl.delegate = this
if (inSlide) { throw new IllegalStateException('May not put groups in slides.') }
if (inGroup) { throw new IllegalStateException('May not nest groups.') }
inGroup = true
markup.section cl
inGroup = false
}
def slide(@DelegatesTo(Slideshow) Closure cl) {
cl.delegate = this
if (inSlide) { throw new IllegalStateException('May not nest slides.') }
inSlide = true
if (!inGroup) {
markup.section { section { cl.call() } }
}
else {
markup.section { cl.call() }
}
inSlide = false
}
protected speakerImpl(Closure cl) {
if (!inSlide) { throw new IllegalStateException('Speaker notes must be in a slide.') }
markup.aside('class': 'notes', cl)
}
def speaker(String text) {
speakerImpl { p text }
}
def speaker(@DelegatesTo(Slideshow) Closure cl) {
cl.delegate = this
speakerImpl cl
}
}
//________ Create slideshow below this line. _______
Slideshow.build(
title: 'Grails 3 + Firebase',
theme: 'beige'
) {
group {
slide {
speaker 'This talk should take about 40 minutes.'
h1 {
mkp.yield 'Grails 3 '
img id: 'titleLogo', src: 'grails-on-fire.png'
mkp.yield ' Firebase'
}
p 'St. Louis Groovy and Grails Meetup &mdash; Jun 7, 2017'
p {
strong 'Matthew Moss'
br()
small { strong 'OCI Grails Team' }
br()
small {
mkp.yield '[twitter: '
strong '"@mattdmoss"'
mkp.yield ', github: '
strong '"mattmoss"'
mkp.yield ']'
}
}
}
slide {
h3 'About Matthew'
ul {
li 'Member of the OCI Grails Team'
li 'Joined OCI in early 2014'
li 'Doing Grails and web dev for several years'
li 'Coding over 20 years, wide experience'
li 'Most visible: Guitar Hero and Rock Band'
li 'Husband (2.5 years) and father (16 months)'
li 'Pianist, board gamer (Star Wars: Rebellion, anyone?)'
li 'Learning woodworking, gardening, and beekeeping'
}
}
slide {
h3 'This talk will cover...'
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment