Meeting agendas
a template using typst and yaml
My colleagues use docx like it’s a working standard, but I could not use this wretched program if clippy’s life depended on it. I author my documents in plain text instead and allow the possibility of producing a docx — should it be absolutely requested of me. Recently I had to tackle the ominous “Meeting agenda” challenge.
Meetings are more efficient when people come prepared; to that effect, I’ve decided to use a 3-column template for the agenda listing for each agenda item:
- the basic info: purpose (for discussion, sharing information, action point), who is leading it, how long we’ll discuss the topic
- prep’ work to do before the meeting (reading documents, gathering info, drafting ideas)
- proposed process for the discussion, to make sure action points aren’t forgotten, and that discussions don’t veer off-track for too long
Since these items are typically concise and text-based, and well-structured, a plain text input format is ideal. I’ve opted for YAML, as it has minimal markup interference, and can be reused programmatically. For instance, the data can be read by a script and wrangled to produce annual summaries, extract all action points, produce different output formats such as a webpage, etc.
With some help on Typst Discord I’ve put together a Typst template to turn such YAML data into a formatted table. The user-facing interface is quite straight-forward:
The input file simply parses the external YAML file with yaml("agenda.yaml")
, and passes those data to the #agenda-table()
function to produce the table. The agenda()
template also takes care of the page layout (it is best to use landscape for these tables, as the description can be a bit long) and of the page heading.
#import "@preview/agenda-yaml:0.1.0": *
#show: agenda.with(
name: "Pumpkins and peanuts committee",
date: "03/01/2000",
time: "2 pm",
location: "baseball field",
invited: [Sally, Shroeder, Pig-pen, Marcie]
)
// load external yaml
#let topics = yaml("agenda.yaml")
#agenda-table(topics)
The data could also be defined in-place, as a Typst dictionary, or as raw YAML to be decoded. A useful trick to avoid problems with \"
needing to be quoted etc. is to define the inline YAML as raw (between #let content = `content goes here` `) and extract the text with
content
.text `when passing it to
#yaml.decode()`. I find that I prefer using an external YAML file, as it’s more versatile (I can reuse it with different scripts for different purposes).
Quarto
Instead of using typst directly, we can author the document with markdown and have quarto produce the typst output using our template. I played around with 3 or 4 different strategies,
- Only use the qmd for the surrounding text and metadata, but keep the YAML as an external file
- Embed the YAML into the qmd file, using a custom knitr engine
- Have the YAML inline, but wrap it in a custom div and use a Lua filter to feed it to the Typst template
I’m sticking with pure Typst for the time being, and I’m only using quarto to produce a bare-bones Word version of the agenda (useful for admins taking notes at the meeting), using R to parse the external YAML file and glue()
the required items.
---
meeting: "Pumpkins and peanuts committee",
date: "03/01/2000",
time: "2 pm",
location: "baseball field",
agenda: "agenda.yaml"
format:
docx:
reference-doc: "_tpl.docx"
keep-md: false
from: markdown-implicit_figures
engine: knitr
---
```{r, echo=FALSE, results='hide'}
library(glue)
meta <- rmarkdown::metadata
```
![ ](VUWlogo.png){width=40% fig-align="center"}
```{glue, results = 'asis', echo = FALSE}
## {meta$meeting} meeting agenda
```
```{glue, results = 'asis', echo = FALSE}
{meta$date} {meta$time} {meta$location} <br/> Zoom link: https://vuw.zoom.us/j/zzz
```
```{r}
#| echo: false
#| results: asis
library(yaml)
library(glue)
library(purrr)
d <- yaml::yaml.load_file(meta$agenda)
format_item <- function(.i){
r <- glue("1. **{.i$Topic}** ({.i$Time}) • _{.i$Lead}_\n\n")
cat(r, "\n")
}
walk(d, format_item)
```