The goal of rithmatist is to get a course out of your head and into a Quarto book quickly.
This was developed using claude, specifically to help me with turning my courses into structured books based on a specific outline that I have, using the teaching practices that I tend to use.
I did not develop this for others to use really, so it might not be exactly what you are after.
The name
A Rithmatist draws chalk figures that come alive and act on their behalf. Which is roughly what a scaffolder does — you sketch an outline, and the drawing does the work.
Installation
You can install the development version of rithmatist from GitHub with:
# install.packages("pak")
pak::pak("njtierney/rithmatist")How it works
Write a schedule as markdown. Each level-two heading is a chapter, and each bullet under it is a section:
# Schedule
## Project Organisation
- Common project structures
- Pitfalls of organisation
- Understanding file paths
- RStudio and positron set up
- "Good Enough"/Common Sense principles of project organisation
- Always have a READMEThen draft the book:
library(rithmatist)
draft_book("schedule.md")Which writes one .qmd per chapter:
#> code-style-and-readability.qmd
#> project-organisation.qmd
#> putting-it-all-together.qmd
#> writing-a-reprex-getting-unstuck.qmd
#> writing-functions.qmd
#> writing-readable-code.qmdEach chapter arrives with its sections as headings, a duration, and a placeholder exercise per section, ready to be written over:
Keeping _quarto.yml in step
chapters_yaml() prints the chapter list in schedule order, so the book config follows the outline rather than being maintained by hand:
chapters_yaml(schedule)
chapters:
- "index.qmd"
- "project-organisation.qmd"
- "code-style-and-readability.qmd"
- "writing-readable-code.qmd"
- "writing-functions.qmd"
- "writing-a-reprex-getting-unstuck.qmd"
- "putting-it-all-together.qmd"Drafting over time
draft_book() skips chapters that already exist, so re-running it after adding a section to your schedule picks up only what’s new and leaves your written chapters alone. Pass overwrite = TRUE to regenerate from scratch — which discards hand-written content, so it’s for while the structure is still moving.
Customising the exercises
The default exercise is a TODO placeholder in a “Your Turn” callout. Pass any function that returns markdown lines, or NULL for no exercises at all:
cat(
draft_chapter(
title = "Writing Functions",
bullets = "- Anatomy of a function",
exercise = function() callout("Write a function.", title = "Exercise", type = "tip")
),
sep = "\n"
)
# Writing Functions
## Overview
* **Duration** 15 minutes
## Questions
## Anatomy of a function
::: {.callout-tip title="Exercise"}
Write a function.
:::