Introduction¶
A .hmd file is a Markdown file that has learned to do more. Reading one
requires nothing — any editor, any renderer, GitHub's file view all show you a
sensible page. Writing one is a single page of new syntax on top of what you
already know. And underneath both sits a toolchain that treats your writing the
way a compiler treats a program: names resolve, references are checked, and
ambiguity is an error rather than a guess.
This chapter is the format at a glance. Every layer appears here briefly, with a pointer to where it is treated properly; none is specified here.
Three layers of syntax¶
The Markdown you know. Paragraphs, emphasis, headings, lists, blockquotes, fenced code. All of it works, unchanged — hyper-markdown neither redefines nor restricts it, and a fenced block stays literal all the way down, which is the escape hatch for showing syntax instead of invoking it.
The rich layer. Tables, footnotes, task lists, callouts, TeX mathematics, D2 diagrams. None of these are original Markdown, and none are hyper-markdown's own — they are the conventional tier the wider Markdown world settled on, and the format assumes them present and renders them as first-class content:
This callout is real
So is \(e^{i\pi} + 1 = 0\) beside it. What a page can carry, shown working, is Features.
The hyper layer. What hyper-markdown itself adds, and the part that is genuinely new. It is all variations on one idea — naming another card, or a part of one:
| Written | Means |
|---|---|
[[card]] |
a link to a card, resolved by name |
[[card|words]] |
the same link, showing different words |
[[card#Heading]] |
a link to a section inside that card |
text ^name |
a block anchor, naming one block |
[[card#^name]] |
a link to that named block |
![[…]] |
an embed — any of the above, spliced in |
The surface hyper-markdown defines is kept deliberately small — small enough to specify, and small enough that the resolver behind it stays checkable. The richness comes from everywhere else on the page, bought from the Markdown ecosystem rather than rebuilt, which is why the feature set keeps growing while the table above does not have to.
Names, and how they are found¶
[[card]] is a name, not a path. A folder is a module, the card beside you
wins over a card far away, and a name that could mean two pages is an error
you are asked to qualify. This is the part that makes hyper-markdown feel like
a language rather than a convention, and it has its own chapter:
Namespaces.
Frontmatter¶
A card may open with a YAML block. Four keys mean something to the toolchain —
tags for what a card is about, use for per-subtree feature toggles,
import for explicit name bindings, nav for its place in a published site.
Every other key is yours, and nothing will inspect it.
The check¶
hmd lint reads the tree and reports what it could not resolve — file, line,
rule ID. The distinction it draws is a compiler's: a link to a card that does
not exist yet is a warning, because writing forward is how a wiki grows; a
link that is ambiguous or malformed is an error, because that is the one
thing the language refuses to guess at. Everything else about your prose is
left alone.
Adopting it¶
A .hmd file is still Markdown — that is the superset property, and it is why
adoption can be gradual: rename one .md to .hmd, add one link, run
hmd lint. Nothing you have written is ever wrong, and nothing forces the
rest of the tree to follow.
Where the full picture lives¶
- The hyper-markdown language teaches every construct, start to finish — read it once and you can write the format.
- The feature list is the exhaustive inventory: every feature, what provides it, and where it stands — including what is deferred or deliberately absent, so nothing gets re-argued from scratch.
- MD ↔ HMD interoperability makes the argument
that
.hmdstands to.mdas TypeScript stands to JavaScript. - HMD-0001 is the normative specification behind all of the above.