weft, a tool for Literate Driven Development
Literate Driven Development needs a tool that treats the narrative and the code as one artifact, not two files left to drift apart. That tool is weft — the metalanguage that binds a formatting language and one or more programming languages into a single source, then, with one command, produces both the document for humans and the source for compilers.
An experienced programmer who wants the best possible documentation of their software needs two things at once: a language like LaTeX, Markdown or HTML for formatting, and one or multiple programming languages simultaneously for the code. Neither can produce the best documentation on its own — but when the two are properly combined, the result is far more useful than either apart. Uniting them takes a metalanguage that binds the two into a single source — and that is weft. It weaves formatting and code together, and with one command produces both outputs from that one source: the document for humans and the source files for compilers. weft is, in the end, a language for humans and AI to write software together, as co-authors.
The structure of a program can be thought of as a web of many interconnected pieces. To document it, we explain each part and how it relates to its neighbors: the formatting language's typographic tools make the local structure of each part visible, while the programming languages let us state each algorithm formally and unambiguously. Combining the two maximizes our ability to perceive the structure of a complex piece of software — and the documented program still translates mechanically into a working system that matches the documentation.
Above all, weft lets you permute the pieces of a program, so a large system can be understood entirely through small sections and their local relationships. The algorithms can be expressed in "untangled" form — laid out in the logical sequence that explains them to a human, not the order the machine demands — with each section explained on its own. weft tangle then moves those sections out of their web structure into the order the compiler requires, while weft weave intertwines the prose and code of each section and knits the whole fabric into a structured document.
A real document, not comments
Weave turns your one source into a real document. You choose its format from the start — you write the narrative directly in LaTeX, Markdown, or HTML — and whichever you pick, the explanation your code becomes can carry the full richness of publishing: indices and cross-references, diagrams and charts, tables and equations, other writing systems and glyphs, bibliographies and citations — the full power of your chosen markup, brought to bear on explaining your code. Your explanation is not a comment buried in the source; it is a publishable document.
Dual usage of a WEFT file.
A literate programming source file can feed two toolchains at once. A single .weft file is passed to weave, which renders the human document, and to tangle, which emits the machine program.
Because both are generated from the very same source, the documentation and the code can never disagree. You never edit either output — every correction, every decision, every new feature flows through the narrative first.
Literate weft concept files
@o greeting.c
Explain the program in prose, then
define its parts by name.
@d Greeting @{
puts("Hello from a literate source");
@}
int main(void) { @<Greeting@> }
One document — the single input to both toolchains. Prose and code, interleaved in the order that builds understanding — a book and its source, bound as one.
Weave →
Documentation
weft -w renders the narrative into a typeset document, read front to back — not just what the system does, but why it was designed that way.
narrative.weft → weft -w → .tex / .md → PDF / web page
Tangle →
Software
weft extracts machine-ordered source — rearranged into the sequence the compiler needs, not the one that taught you — which your usual toolchain then builds and runs.
narrative.weft → weft → source → compile → run
Using weft
Literate programming inverts the usual order. Instead of code with the occasional comment, a .weft file is a document: sections of prose that explain the system, with the code for each idea embedded exactly where the explanation places it. You write in the order that teaches, not the order the machine demands — a piece of logic can be named, discussed, and defined long before it is needed, then pulled in by name (@<like this@>) wherever it belongs. The file's structure follows the argument, not the compiler.
weft reads one .weft file — prose with code woven in — and does two independent jobs. Tangle extracts the real source files a compiler runs (the default); weave typesets the document a human reads. The same source is both, so the two can never drift apart.
That interleaving is the whole point. The reasoning — why a decision was made, what a tricky branch guards against — lives beside the code instead of evaporating, so the source explains itself to the next engineer and to the AI writing alongside them. Where an ordinary codebase hands the compiler a rigid, tangled sequence built for the machine, a literate source hands a person — and a model — a narrative built for understanding; weft only rearranges it into the machine's order at the moment it tangles.
The directives you need
- @d name
- Define a named fragment of code.
- @o file
- Open an output file — a tangle target.
- @<name@>
- Reference a fragment; its body is spliced in.
- @{ … @}
- Delimit a code scrap; prose lives outside.
- @i file
- Include another .weft file.
- @@
- A literal @ in the output.
Two jobs, one source
- weft file.weft
- Tangle: write the code files. The default.
- weft -w tex file.weft
- Weave a LaTeX document, ready for PDF.
- weft -w md file.weft
- Weave Markdown that renders on GitHub.
- weft -w html file.weft
- Weave a self-contained HTML page.
A tiny example
This is a whole literate program — it greets the world, and the prose explains it as you read.
First, name the one line that does the talking:
@d Say hello @{
printf("hello, %s\n", name);
@}
Then the output file. main is defined here and pulls that fragment in by name, so the code reads in the order that explains it — not the order the compiler needs:
@o hello.c @{
int main(void) {
@<Say hello@>
}
@}
One source, two jobs: tangle writes the C for the compiler, weave writes the document for a reader.
$ weft hello.weft # tangle → hello.c
$ weft -w html hello.weft # weave → hello.html