feat: parse markdown and custom directives into one representation

This commit is contained in:
randogoth 2026-10-04 19:21:48 +03:00
parent 3031b8acdd
commit e5583bbd89
8 changed files with 1410 additions and 2 deletions

View file

@ -8,13 +8,13 @@ A Rust re-implementation of [smolweb](https://code.randogoth.com/randogoth/smolw
## Status
Early. Configuration and path resolution are implemented and tested; nothing is served yet.
Early. Configuration, path resolution and Markdown parsing are implemented and tested; nothing is served yet.
| Area | State |
| --- | --- |
| Server configuration, virtual hosts, `--check` | implemented |
| Path resolution, traversal containment, live reload | implemented |
| Markdown parsing | planned |
| Markdown parsing, includes, ASCII art, card breaks | implemented |
| gemtext and HTML output | planned |
| HTTP, Spartan and Nex listeners | planned |
| 80-column text and Nex output | planned |
@ -70,6 +70,18 @@ formats rendered per page: html, xhtmlmp
Everything the schema cannot express is checked here rather than on first request: a format no enabled feature provides, two sites claiming one hostname, a content root that does not exist, a server file sitting inside a content root where it would be served.
## Markdown
Markdown is parsed once per document into one representation that every output format reads, rather than once per format. Four directives sit outside CommonMark and are recognised before parsing, each occupying a whole line:
| Directive | Means |
| --- | --- |
| `{.include path}` or `![[path]]` | splice that file's lines in here |
| `#[label](art.txt)` | a verbatim block read from that file |
| `{.card Title}` | a divider for formats that paginate; nothing for the rest |
Include and art targets resolve relative to the including file and must stay inside the content root. Expansion is bounded on three axes — nesting depth, total lines, and total bytes — because a cycle check alone does not stop a long chain, and neither stops a diamond where two branches include the same file without ever repeating one on a single path.
## URLs
Links should be root-relative and extensionless (`[about](/about)`, not `about.md`), so the same link resolves identically from every protocol.