Erik Zaadi

The tales of a coding manager addicted to dad jokes

Markdown My Words! S3 You Later PowerPoint

Markdown is life

So why not use it for presentations?

I do a fair bit of internal presentations, and like most good things, they’re powered by Markdown, duct tape, and a sprinkle of automation magic.

For a long time, I was using reveal-md for all my slides. But once that got deprecated, I moved to the absolutely AMAZONG Slidev (sli.dev) project.

It’s markdown-first, extensible, and works brilliantly with my workflow.

Slidev is a simple as separating slides with --- and just good old markdown:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

# ZOMG

## My subtitle

[Mandatory gif](https://media.giphy.com/media/11RgbBSgomKx6o/giphy.gif)

<b>Whatever custom html I want as well</b>

---

Second slide FTW

With some superb advanced features like layouts, animations and MOAR.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

# ZOMG

## My subtitle

---
layout: image-right
image: https://media.giphy.com/media/11RgbBSgomKx6o/giphy.gif
backgroundSize: contain
---

Second slide with image on the right

Why is this interesting you ask?

This allows for a rapid feedback iterative work on your presentation.

Crank out your story fast, then re-iterate with puns gifs and memes.


🛠️ Bootstrapping Presentations Like a Procrastination-Driven Pro

Creating a presentation from scratch every time?

I’ve automated the whole process so I can go from “Oh, I should present this” to “Slides are up!” in seconds.

It starts with a little shell function:

1
2
3
4
5
6
pwo () {
    PRESENTATION_NAME="$*" tmuxp load -y presentation
}

# Auto complete existing presentations
compdef '_path_files -/ -W ${PRESENTATIONDIR}' pwo

This spins up a tmuxp session defined like so:

1
2
3
4
5
6
7
8
9
# ~/.config/tmuxp/presentation.yaml
session_name: "El Presento - ${PRESENTATION_NAME}"
windows:
  - panes:
      - cd $(init-presentation ${PRESENTATION_NAME}); ${EDITOR} ./presentation.md
    window_name: editor
  - panes:
      - cd $(init-presentation ${PRESENTATION_NAME}); slidev --open ./presentation.md
    window_name: slidev

Why El Presento? Because it was a pun I thought of when spinning up this script and it stuck ;)


🧙 The init-presentation script

This script does a lot (EVEN ALOT):

  • Slugifies the presentation name
  • Creates the directory
  • Writes the initial presentation.md with Slidev frontmatter
  • Adds image assets and an HTML file for local fallback

It expects there to be a template folder with my avatar, base template and snippets.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/env bash
PRESENTATION_NAME="$*"
PRESENTATION_NAME_FORMATTED="$(echo "${PRESENTATION_NAME}" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g')"
PRESENTATION_FINAL_DIR="${PRESENTATIONDIR}/${PRESENTATION_NAME_FORMATTED}"
PRESENTATION_TEMPLATE_DIR="${PRESENTATIONDIR}/template"

TEMPLATE="""---
author: Erik Zaadi
browserExporter: false
contextMenu: false
download: false
favicon: './images/avatar.png'
mdc: true
monaco: false
monacoTypesSource: none
presenter: false
record: false
routerMode: hash
title: ${PRESENTATION_NAME}
titleTemplate: '%s'
drawings:
  enabled: false

defaults:
  transition: slide-left
  layout: center
---

## ${PRESENTATION_NAME}

#### FTW!

----

Here be dragons!

---
src: ../template/fin.md
---
"""

if [[ ! -d "${PRESENTATION_FINAL_DIR}" ]]; then
    mkdir -p "${PRESENTATION_FINAL_DIR}/images" > /dev/null
    echo "${TEMPLATE}" > "${PRESENTATION_FINAL_DIR}/presentation.md"
    ln "${PRESENTATION_TEMPLATE_DIR}/index.html" "${PRESENTATION_FINAL_DIR}/index.html"
    ln "${PRESENTATION_TEMPLATE_DIR}/avatar-512.png" "${PRESENTATION_FINAL_DIR}/images/avatar.png"
fi

echo "${PRESENTATION_FINAL_DIR}"

Basically: run pwo 'My Awesome Topic', and I’m in a Slidev editing session with nvim and live preview.


🌍 Deploying slides (FTW)

No workflow is complete without CI/CD — even for slides.

I host all my slides at AWS (a S3 bucket behind a cloudfront distribution for ssl).

Here’s my slidev-deploy script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env bash
PRESENTATION=${1:-'presentation.md'}
CURR_DIR=$(basename "${PWD}" | tr '[:upper:]' '[:lower:]')
# Expects AWS_PROFILE=SOMETHING_SUPER_SECRET
ZE_BUCKET=slides.erikzaadi.com
ZE_CLOUDFRONT_ID=SOMETHING_GUID_ISH
rm -rf ./dist > /dev/null
slidev build --base "/${CURR_DIR}/" "${PWD}/${PRESENTATION}"
aws s3 sync --follow-symlinks --acl public-read ./dist "s3://${ZE_BUCKET}/${CURR_DIR}/"
if [[ -d ./images ]]; then
    aws s3 cp --recursive --acl public-read ./images "s3://${ZE_BUCKET}/${CURR_DIR}/images/"
fi
# create cloudfront invalidation in case it's re-deployed
aws cloudfront create-invalidation --distribution-id "${ZE_CLOUDFRONT_ID}" --paths "/${CURR_DIR}/*" | jq '.Invalidation | .Status'
open "https://${ZE_BUCKET}/${CURR_DIR}/?random=${RANDOM}" # random as a quick cache buster

It:

  • Builds the Slidev presentation
  • Uploads to an S3 bucket
  • Invalidates the CloudFront cache
  • Opens it in my browser, because why not

🐉 Slides Should Be Punny

After all the setup is done, I finally get to the real work:

  • Adding way too many puns (can that even be a thing?!?!?!)
  • Including way too many GIFs (MOAAAR)
  • And probably one meme too many (NEVAH)

If it doesn’t make people laugh and learn at the same time, I’m not doing it right.


💭 TL;DR

  • I use Slidev for all internal presentations
  • Everything’s markdown-first
  • Automated setup with tmuxp and shell scripts
  • Deploys to slides.erikzaadi.com
  • Powered by caffeine and dad jokes

Share on: