Convert plain text to HTML, inferring structure from conventions authors already use: indentation for lists, blank lines for paragraphs, underlines and setext rules for headings, trailing punctuation for link labels. No markup language is required — the input is plain text, the output is HTML through templates you control.
textrill began as a Rust port of
HTML::TextToHTML 3.0 and its
txt2html script, by Seth Golub. It has moved on from byte-parity with that
reference as its default; the legacy --xhtml/--no-html5 modes and the
frozen corpus still reproduce the reference byte for byte, and the Perl
original is kept as an on-demand cross-check (make diff, in the non-gating
parity/ directory).
This is a fork. It is not affiliated with or endorsed by the upstream
txt2html project.
- Setext headings and explicit heading rules
- Bullet, ordered and definition lists from layout
- Capitalised runs →
<strong>; short lines →<br> - Tables (
--make_tables), mail headers (--mailmode) - Links from URLs,
mailto:and a user link dictionary - Encoding detection: BOM → UTF-16 evidence → UTF-8 → CP1252
- Output modes:
--toc,--section,--chunk,--extract,--stream - Templates:
--template_library article|book|manpage|slide|bare,--body_template,--document_template,--var name=value - HTML5 by default;
--xhtml/--no-html5for the older modes
rust-toolchain.toml pins the compiler and the rustfmt/clippy components.
make build # the CLI (release build)
make musl # the CLI as a static musl binary (needs the musl target)
printf 'Hello *world*.\n' | ./textrill/target/release/textrill
make verify # fmt, clippy, tests, properties, acceptance — the gate
make bench # criterion benchmarks for large-document conversion
make repro # two clean CLI builds must match byte for byte
make deny # supply chain: cargo-deny + cargo-audit, both crates
make sbom # CycloneDX SBOMs under dist/sbommake verify needs no Perl and means the same thing here and on CI. CI also
runs make deny in a separate supply-chain job, checks that two clean builds
are byte-identical, and validates the desktop metadata; a v* tag triggers
.github/workflows/release.yml, which rechecks reproducibility with
make repro-all and publishes the Flatpak, AppImage, deb/rpm, Windows/macOS
artifacts and CycloneDX SBOMs (and the engine crate when a crates.io token is
configured).
The gate compares every corpus case and real example against a recorded golden. Goldens are a record of approved behaviour, not a wall. When output changes on purpose:
make accept-write # recapture the corpus goldens
make examples-write # recapture the example goldens
git diff # the diff of the recapture is the reviewCommit the goldens with the change that recaptured them. The properties that
cannot regress (no dropped text, well-formed output, determinism, bounded
resources) are gated separately by proptest and alloctest.
| Path | What it is |
|---|---|
textrill/ |
Engine and CLI; the user contract is textrill/README.md. |
textrill-gui-rs/ |
The native GUI (egui/eframe). |
examples/ |
Real documents used as acceptance inputs, with a license record. |
textrill/tests/ |
Unit tests, corpus and goldens. |
packaging/ |
Flatpak manifest, desktop metadata, AppImage and package notes. |
.github/workflows/ |
The CI gate and the tag-triggered release artifacts. |
See CONTRIBUTING.md for the workflow.
Code is GPL-3.0-or-later. Example documents are CC0 / public domain
(examples/README.md); the GUI bundles fonts under their own licenses
(LICENSE-NOTICE.md). Upstream copyright is preserved:
Copyright 1994-2000 Seth Golub
Copyright 2002-2013 Kathryn Andersen
Copyright 2018-2019 Joao Eriberto Mota Filho