clayoven is a beautiful static site generator with a carefully curated set of features. It has been built at a glacial pace, over a period of eight years, as my website expanded in content. I have a spread of mathematical notes, both typeset and handwritten, software-related posts, and some wider-audience articles; while clayoven is primarily aimed at math-heavy sites, it is good on all three fronts. The source files are written in “claytext”, a custom format built for elegance and speed.

rdoc documentation is available at

Unique features


A starter project is bundled with the following scratch.index.clay:

whose rendered output can be seen here).

Here's an excerpt of embedded MathJaX with IntelliSense powered by vsclay:

Getting started

There is no published gem. To get started, clone, run bundle to install the required gems, and put bin/clayoven in $PATH. Then, run clayoven init in a fresh directory. To start writing, install vsclay for vscode, which will provide the necessary syntax highlighting, IntelliSense support for MathJaX, and trigger-[incremental build]-on-save functionality.

The site-generation engine

All site content is split up into “topics”, to put in the sidebar, each of which can either serve as an index to a collection of ContentPages (as a bunch of .clay files in a subdirectory with the name #{topic}), or a single IndexPage (named #{topic}.index.clay). index.clay is special-cased to serve as the root of the site.

So, if you have these files,

.vscode/...             # provided by `init`
.htaccess               # provided by `init`
lib/...                 # provided by `init`
design/                 # provided by `init`
index.clay              # provided by `init`
scratch.index.clay      # provided by `init`
404.index.clay          # provided by `init`

clayoven automatically builds a sidebar with index, blog and colophon (each of which are instances of IndexPage). /blog will have links to the posts /blog/personal/1 and /blog/math/1 (each of which are instances of ContentPage), under the titles personal and math (the “subtopics”). If there multiple ContentPage entries under an IndexPage, the latter simply serves to give a introduction, with links to articles automatically appearing after the introduction. IndexPage and ContentPage are run through the same design/template.slim, and the template file has access to the accessors.

The engine works closely with the git object store, and builds are incremental by default; it mostly Just Works, and when it doesn't, there's an option to force a full rebuild. The engine also pulls out the created-timestamp (Page#crdate) and last-modified-timestamp (Page#lastmod) from git, respecting moves. ContentPages are sorted by crdate, reverse-chronologically, and IndexPages are sorted alphabetically.



  1. .clayoven/sitename is URL of the site, excluding the https:// prefix.

  2. .clayoven/hidden is a list of IndexFiles that should be built, but not displayed in the sidebar. You would want to use it for your 404 page and drafts.

  3. .clayoven/tz is a timezone-to-location mapper, with lines of the form +0000 London. clayoven digs through the git history for locations, and exposes a Page#locations.

  4. .clayoven/subtopic is a [subtopic directory]-to-subtitle mapper, with lines of the form inf ∞-categories.

The claytext processor

The claytext processor is, at its core, a paragraph-processor; all content must be split up into either plain paragraphs, or “fences” (multiple paragraphs delimited by start and end tokens). The function of most markers should be evident from the scratch.html produced by a clayoven init. The format is strict, and the processor doesn't like files with paragraphs wrapped using hard line breaks.

Clayoven::Claytext::Transforms::LINE matches paragraphs where all lines begin with some regex, and Clayoven::Claytext::Transforms::Fenced match fences (could be multiple paragraphs) that start and end with the specified tokens. In addition to this, there are inline markdown markers `...` and [...](...), for content that is to be put in <mark> and <a>, respectively.


Planned features, and anti-features