DevOps for Presentations: Reveal.js, Markdown, Pandoc, GitLab CI

Benji Fisher // March 2019

I have been looking for an easy way to generate presentations, or slide decks. I am pretty happy with the system I have now, which combines

These tools make it possible to create well organized, visually compelling, and informative presentations, but the tools do not guarantee any of that.

The goal of DevOps, and what these tools do provide, is a smooth, reliable process I can use when preparing a presentation. Once I know how I am going to generate my slide deck and make it available on the web, I can devote my attention to the hard parts and the fun parts, like adding a few dumb jokes.

I have enough confidence in my tools that I could fix a typo during a presentation, update the slides on my computer in a few seconds, and the version on the web would be updated about a minute later.

Reveal.js

Reveal.js is a framework for creating beautiful presentations with HTML, CSS, and javascript. Have a look at its Home page and its GitHub repo.

When I use Reveal.js, I can connect my laptop to a projector and show the audience the version on my computer. I do not have to worry about whether the conference’s wifi is overloaded. I can also give people a link to the same file on the web, and they will see the same slides that I use.

The Reveal.js home page is an example of a presentation using the framework. It shows off a lot of features that I do not use. For another example, have a look at the slides version of this blog post, suitable for a 5-10 minute lightning talk.

Markdown

Markdown is a simple, text-based format that can be translated into HTML or other formats. If you leave comments on GitHub or GitLab, then you can use Markdown format. I use it for taking notes during client meetings and when attending conferences. Some day soon, I will switch to using Markdown for my e-mail, too.

Here are a few examples of Markdown formatting, and how they look after being translated into HTML:

Markdown: lists

For numbered lists, you can use the same number for each item. This makes it easy to add, remove, or rearrange the items. For nested lists, just indent four spaces:

1. First
1. Second
    7. nested
    7. nested
  1. First
  2. Second
    1. nested
    2. nested

You can also use either - or * to generate bulleted lists.

Markdown: links

For links, put the link text in square brackets and the URL in parentheses:

[Drupal](https://www.drupal.org)

Drupal

Markdown: subheadings

For headings, just start the line with a few # characters and a space. It is important for accessibility to keep a consistent structure, so I will only demonstrate the headings that make sense in the current context (after an H3-level heading):

#### H4 heading

##### H5 heading

###### H6 heading

H4 heading

H5 heading
H6 heading

Pandoc

Pandoc is a document converter. Its goal is to convert anything to anything, and it gets close to this goal by converting anything to Markdown and Markdown to anything:

Pandoc: input formats

$ pandoc --list-input-formats
commonmark
creole
docbook
docx
dokuwiki
epub
fb2
gfm
haddock
html
ipynb
jats
json
latex
man
markdown
markdown_github
markdown_mmd
markdown_phpextra
markdown_strict
mediawiki
muse
native
odt
opml
org
rst
t2t
textile
tikiwiki
twiki
vimwiki

Pandoc: output formats

$ pandoc --list-output-formats
asciidoc
asciidoctor
beamer
commonmark
context
docbook
docbook4
docbook5
docx
dokuwiki
dzslides
epub
epub2
epub3
fb2
gfm
haddock
html
html4
html5
icml
ipynb
jats
json
latex
man
markdown
markdown_github
markdown_mmd
markdown_phpextra
markdown_strict
mediawiki
ms
muse
native
odt
opendocument
opml
org
plain
pptx
revealjs
rst
rtf
s5
slideous
slidy
tei
texinfo
textile
zimwiki

Pandoc: usage

Pandoc is a command-line tool. If I have the Markdown file devops-slides.md in my markdown/ directory, and I want to create an HTML version in my html/ directory, then I would use this command:

$ pandoc \
 --standalone \
 -t revealjs \
 -o html/devops-slides.html \
 markdown/devops-slides.md

The -t revealjs option tells Pandoc to produce HTML output using the Reveal.js framework.

GitLab CI

Technically, continuous integration (CI) refers to a practice, not a tool: the practice of frequently integrating current code changes with the larger codebase. The term is often used to refer to tools that enable that practice by automating the process, making it so easy that it does not slow you down.

GitLab CI is an automation tool that is built into GitLab. It is often used to automate tasks like compiling code and running automated tests. I use it to “compile” Markdown into HTML using Pandoc.

GitLab CI is free and flexible. Here are some of its features:

  • fully integrated with GitLab
  • free for public repositories
  • use any Docker image
  • supports jobs and pipelines
  • can be triggered by branches, tags, commits

GitLab CI: pages

One of the ways that GitLab CI integrates with GitLab is that you can use it to generate your GitLab Pages. This gives you a lot more flexibility than GitHub Pages. I think that GitHub only gives you three options: commit HTML files to your repository; commit GitHub flavored Markdown (GFM) to be processed using GitHub’s rules; commit Markdown to be processed with Jekyll.

There are three steps to setting up GitLab Pages:

  1. Create a CI job called pages.
  2. In that job, add files to public/.
  3. Save this directory as an artifact.

GitLab CI: example .gitlab-ci.yml

Here is the configuration I use for those three steps in my Slide Decks repository:

variables:
  GIT_SUBMODULE_STRATEGY: recursive
before_script:
  - apt-get update -qq && apt-get install -qq -y pandoc
  - pandoc --version
pages:
  stage: deploy
  script:
    - make build
    - cp -R html public
  artifacts:
    paths:
      - public

You can check the live version of .gitlab-ci.yml in my repository.

Pandoc is not a standard tool available on CI, but it takes just a few lines to install it. Instead of putting the pandoc command into the CI config file, I run a make command. (Call me old fashioned, but I think make is the right tool to use here. It certainly gets the job done!)

Here is how I configure make:

# .SUFFIXES: .html .md
SRCS := $(wildcard markdown/*.md)
HTML := $(SRCS:markdown/%.md=%.html)
vpath %.md markdown
vpath %.html html

%.html: %.md
    pandoc --standalone -t revealjs -o html/$@ $<

default: example.html

build: $(HTML) index.md
    pandoc --standalone -o html/index.html index.md
    cp -R images reveal.js html

You can also see the live version of Makefile in my repository.

Putting it all together

Now that my automated system is set up, this is the process if I need to fix a typo or make some other change to my slides:

  1. edit
  2. make
  3. commit
  4. push

A few seconds after the first two steps, my local copy has been updated. All I have to do is refresh my web browser.

About a minute after pushing the update to my GitLab repository, the version on GitLab Pages gets updated.

There are a couple of variants on the make step.

I sometimes change the default target in Makefile to whatever presentation I am currently editing. (I do not commit this change.) Then I can just use the command make (no arguments) in a shell. Easy peasy.

I can also combine the first two steps. I do all my editing in Vim, so I can save and run make with the command

:w | !make %:r.html

That is a bit much to type the first time around, but once it is in my command history, all I actually type is :w <Tab><CR>, or maybe just @:. In other words, these steps are really quick and easy.

References

For convenience, here are some of the links from the body of this post:

Filed under: