Documents, not strings
A static site generator has to answer questions about a document. What is its title? When was it written? What does it link to? What should the excerpt on the front page say?
There are two places to get those answers from. One is the document. The other is the HTML you just rendered from it.
Why the second one is tempting
Reaching for the rendered HTML is easy, and it is how a surprising number of
tools work. Pull the first <p> out of the output for the excerpt. Regex the
<img src> attributes to find the images. Match <h1> to recover the title.
It works immediately and it decays quietly, because every pass is now reading
markup that a previous pass wrote.
The failure this avoids
The parser underneath anchor exists because of a bug of exactly that shape.
An earlier renderer built HTML by running regular expressions over a string,
one after another. The pass that turned _text_ into emphasis ran after the
pass that produced code spans, so it happily matched underscores that were by
then inside a <code> element, and foo_bar_baz came out corrupted.
The root cause is not that regular expressions are bad. It is that each pass read markup the previous pass wrote. Once that is the architecture, every fix is another special case about what to skip.
What the tree gets you
anchor never sees the HTML until it writes it. The pipeline runs in one direction and nothing reads back:
That image sits in this post's own directory, next to the file naming it, so the post and its media are one movable unit. Every question is answered from the parsed tree in the validate step:
- title
- The AsciiDoc title, read from the document. There is no
title:key anywhere in configuration. - excerpt
- The preamble, meaning the blocks before the first heading, rendered as a subtree of its own. No marker in the source and no truncation of rendered HTML.
- references
- Every link and image node, resolved against the filesystem while the tree is still a tree.
That last one is the interesting one. Because a reference is a node rather than an attribute in a string, anchor resolves it and then writes the resolved target back onto the node before rendering. A broken image is a build error rather than a broken page, and finding one is a hash-table lookup rather than a scan.
That one lives in a shared _media/ directory at the site root. A relative
reference is resolved by walking up from the page's own directory, so a file
beside the post is found on the first step and a shared one further up. It is
the same rule the configuration cascade uses, and it is the only place anchor
resolves a name by searching.
The part that is not a feature
None of this appears in the list of things anchor does, because none of it is a feature. They are all consequences of the same decision, and that is the test of whether the decision was worth making.