Add WML renderer for WAP decks
Adds a `wml` renderer plugin converting Markdown into WML decks for
old WAP browsers, following the existing parser -> BlockEvent stream
-> renderer plugin architecture (see gemini/micron/ama renderers).
WML content is idiomatically short and button/link-navigated rather
than one long page, so unlike the other renderers, `wml` can split a
document into multiple <card>s -- but only opt-in:
- Manual `{.card}` / `{.card Title}` divider directives (new,
format-agnostic BlockKind.CARD_BREAK; silently ignored by every
other renderer via their existing unhandled-kind no-op path).
- Heading-level splitting via `--renderer-option split_level=N`,
ignored when manual dividers are present.
- Plain documents with neither stay a single card (the safe default).
When a document resolves to 2+ cards, a hub-and-spoke menu card is
built by default (button/link choices -> section, Back to menu), or
`menu=false` switches to a linear Next/Back chain. A byte-overflow
safety net (`max_card_bytes`, default 1400) paginates any single
section that's still too large.
Also adds GFM pipe-table support (BlockKind.TABLE) via the same
sentinel-injection preprocessing trick already used for ASCII art
blocks, so the parser's line-by-line loop needed no lookahead rework.
Rendered as `<table>` in wml, silently ignored elsewhere.
No new dependencies. No devbox/jj/test-suite additions -- decided
against for this repo (see README for the full option reference).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
b539d037c6
commit
d5046543b3
9 changed files with 641 additions and 3 deletions
39
README.md
39
README.md
|
|
@ -19,7 +19,7 @@ uv tool install --from git+https://codeberg.org/randogoth/md2txt/ md2txt
|
|||
|
||||
## CLI
|
||||
|
||||
- `md2txt` – converts Markdown into plain text with extensive formatting support. It ships with the default `markdown` parser and `text` renderer plugins, registers optional `micron`, `ama`, and `gemini` renderers for Micron/Ancient Machine Book or Gemtext output, and exposes the core pipeline so you can add your own parser or renderer modules:
|
||||
- `md2txt` – converts Markdown into plain text with extensive formatting support. It ships with the default `markdown` parser and `text` renderer plugins, registers optional `micron`, `ama`, `gemini`, and `wml` renderers for Micron/Ancient Machine Book, Gemtext, or WML (WAP) output, and exposes the core pipeline so you can add your own parser or renderer modules:
|
||||
- FIGlet-rendered headings.
|
||||
- Emphasis styles converted to spaced or delimited characters.
|
||||
- Optional alignment and margin controls via HTML `<p>` attributes or MultiMarkdown attribute blocks (e.g. `{:.center margin=20px}`) applied as leading spaces.
|
||||
|
|
@ -36,6 +36,7 @@ md2txt input.md --width 72 # override column width
|
|||
md2txt input.md --renderer micron # emit Micron-formatted output for NomadNet
|
||||
md2txt input.md --renderer ama # emit AMA markup for Ancient Machine Book
|
||||
md2txt input.md --renderer gemini # emit Gemtext for Gemini capsules
|
||||
md2txt input.md --renderer wml # emit a single-card WML deck for WAP browsers
|
||||
md2txt input.md --renderer-option width=68 # pass column width to a renderer
|
||||
```
|
||||
|
||||
|
|
@ -122,6 +123,40 @@ Inline or block-level ASCII art can be embedded directly in Markdown:
|
|||
|
||||
Generated text uses CRLF line endings to maintain DOS compatibility.
|
||||
|
||||
## WML Decks
|
||||
|
||||
The `wml` renderer converts Markdown into a [WML](https://en.wikipedia.org/wiki/Wireless_Markup_Language) deck for old WAP browsers. WML screens are idiomatically short and button/link-navigated rather than one long scrolling page, so unlike the other renderers, `wml` can split a document into multiple `<card>`s — but only when you ask it to; a plain document with no options stays a single card.
|
||||
|
||||
Two independent, both-optional ways to define card boundaries:
|
||||
|
||||
- **Manual dividers** — insert a `{.card}` or `{.card Title}` line wherever you want a new card to start, regardless of heading structure:
|
||||
|
||||
```markdown
|
||||
Intro shown on the menu card...
|
||||
|
||||
{.card Weather}
|
||||
Cold and clear...
|
||||
|
||||
{.card Trail Status}
|
||||
- North Loop: open
|
||||
```
|
||||
|
||||
- **Heading-level splitting** — opt in with `--renderer-option split_level=N` to start a new card at every heading of level `N` (e.g. `split_level=2` for the common one-H1-title-plus-H2-sections pattern). Ignored if the document contains any `{.card}` markers.
|
||||
|
||||
When a document resolves to two or more cards, `wml` builds a "menu" card by default — the classic WAP-portal pattern: a list of button/link choices leading to each section, each with a Back control (`--renderer-option menu=false` switches to a linear book instead, chaining cards with Next/Back). A section whose content would still be too large for one card even after splitting is automatically paginated further (`--renderer-option max_card_bytes=N`, default 1400 — a nod to classic WAP 1.x per-deck cache limits; `0` disables it).
|
||||
|
||||
| Renderer option | Default | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `title` | *(none)* | Overall deck title, used on the menu card (or the single card, if never split). |
|
||||
| `split_level` | `0` (disabled) | Heading level that starts a new card. Ignored if `{.card}` markers are present. |
|
||||
| `max_card_bytes` | `1400` | Byte safety-net per card; `0` disables. |
|
||||
| `menu` | `true` | Hub-and-spoke menu card vs. linear Next/Back chaining (`menu=false`). |
|
||||
| `nav_next_label` | `More` | Label for forward navigation (linear mode / overflow pagination). |
|
||||
| `nav_prev_label` | `Prev` | Label for backward navigation between overflow pagination parts. |
|
||||
| `nav_back_label` | `Back` | Label for backward navigation from a section back to the menu/previous section. |
|
||||
|
||||
WML 1.3 is the only supported DTD (fixed by design, not a flag). Since WML uses `$` for variable substitution, a literal `$` in your Markdown is escaped to `$$` in the output automatically. Images pass through as `<img src="..." alt="..."/>` referencing the original path/URL — no WBMP conversion is performed.
|
||||
|
||||
## Plugin Architecture
|
||||
|
||||
The conversion pipeline lives in `src/md2txt/conversion/core.py` and is exposed via `run_conversion`. It is designed around lightweight factories:
|
||||
|
|
@ -149,7 +184,7 @@ register_renderer("ansi", my_renderer_factory)
|
|||
|
||||
Once registered (for example in a small module that imports `md2txt.cli`), the new plugins are available via `--parser my-markdown` or `--renderer ansi`. The CLI lists registered plugin names in `--help`, and the helper functions `available_parsers()` / `available_renderers()` return the sorted names if you need to build higher-level tooling.
|
||||
|
||||
The shared preprocessing helpers—YAML frontmatter parsing, recursive include expansion, and ASCII art sentinels—also live in `src/md2txt/conversion/core.py`, allowing alternate front-ends to reuse exactly the same behaviour without duplicating code.
|
||||
The shared preprocessing helpers—YAML frontmatter parsing, recursive include expansion, ASCII art sentinels, and pipe-table sentinels—also live in `src/md2txt/conversion/core.py`, allowing alternate front-ends to reuse exactly the same behaviour without duplicating code.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue