feat: add figlet banners and hyphenation behind features

This commit is contained in:
randogoth 2026-10-04 20:53:20 +03:00
parent 9e1cfed284
commit 36b868e094
13 changed files with 4282 additions and 29 deletions

View file

@ -18,6 +18,7 @@ It serves. HTTP, Spartan and Nex are working, with gemtext, XHTML-MP and HTML ou
| gemtext, XHTML-MP and HTML output | implemented |
| HTTP, Spartan and Nex listeners, virtual hosting | implemented |
| Fixed-width text output (Nex, later Gopher) | implemented |
| FIGlet banners and hyphenation, behind features | implemented |
| WML and XHTML-MP decks | planned |
| Gemini and Gopher | planned |
@ -62,7 +63,7 @@ max_age = 300
`[defaults]` applies to every Markdown file in the directory; a `[page."name.md"]` table overrides it for one file. `title` is per-page by nature, so setting it in `[defaults]` is an error; left unset, it is derived from the page's first level-1 heading.
The fixed-width text format reads `margin_left`, `margin_right`, `paragraph_spacing`, `h1_style` through `h6_style`, `blockquote_bars`, `list_indent`, `code_block_line_numbers` and `wrap_code_blocks`. A heading style is `underline`, `underline:<char>`, `markers` or `plain`; by default the first three levels are underlined with `=`, `-` and `~`, and deeper ones keep their `#` markers, since underline characters run out before heading levels do. Editing the file re-renders that directory's pages on the next request, and a file that fails to parse makes them error rather than silently falling back to defaults.
The fixed-width text format reads `margin_left`, `margin_right`, `paragraph_spacing`, `h1_style` through `h6_style`, `blockquote_bars`, `list_indent`, `code_block_line_numbers` and `wrap_code_blocks`. A heading style is `underline`, `underline:<char>`, `figlet`, `figlet:<font>`, `markers` or `plain`; by default the first three levels are underlined with `=`, `-` and `~`, and deeper ones keep their `#` markers, since underline characters run out before heading levels do. Editing the file re-renders that directory's pages on the next request, and a file that fails to parse makes them error rather than silently falling back to defaults.
Because the name begins with a dot, the same rule that keeps `.secret.md` out of the URL space keeps this file out of it too.
@ -121,6 +122,22 @@ HTTP negotiates between them from `Accept`. Only a literal media type counts as
A third party adds a format by writing a crate that depends on `itsybitsy-core`, adding it to the workspace and one `#[cfg]` arm in the binary's registry, then naming its id in `formats`. Every listener's formats are checked against the registry at startup, so a format switched off by a feature is a configuration error naming the missing id rather than a server error on the first request.
## Optional features
Two decorative capabilities for the text format are off by default, because most pages leave them alone and both cost binary size:
| Feature | Adds | Cost |
| --- | --- | --- |
| `figlet` | `h1_style = "figlet"` banners, fonts `small` and `standard` | +60 KiB |
| `hyphenation` | `hyphenate = true`, English patterns | +127 KiB |
| `hyphenation-all` | every language the pattern crate carries | +3.0 MiB |
```bash
cargo build --release --features "figlet hyphenation"
```
A banner that will not fit the line, names a font this build lacks, or is asked for by a build without `figlet` falls back to the level's underline — a heading that cannot be decorated should not be lost. An unknown font name is logged, since that is almost always a typo. Likewise `hyphenate` has no effect without the feature, and an unknown `hyphen_lang` leaves the text unhyphenated; a ragged right edge is the plain-text convention anyway.
## URLs
Links should be root-relative and extensionless (`[about](/about)`, not `about.md`), so the same link resolves identically from every protocol.