termdoc

View documents without leaving the terminal

A fast, terminal-native document viewer. Markdown, plain text and logs render today — more formats land milestone by milestone.

It is not an editor. It is not a converter. It is not an IDE.

v0.1.0 · M0 complete · M1 in progress

what it looks like

Release notes

A fast, terminal-native document viewer, with inline code and
a link[1].

Formats

• Markdown, plain text and logs
• Detection for JSON, YAML, TOML, XML, CSV
  ◦ and the Office/ZIP family
• PDF and EPUB are on the roadmap

┌──────────┬──────────┬───────────┐
│ Format   │  Status  │ Milestone │
├──────────┼──────────┼───────────┤
│ Markdown │  ready   │ M0        │
│ CSV      │ detected │ M1        │
│ PDF      │ pending  │ M3        │
└──────────┴──────────┴───────────┘

fn main() {
    println!("hello");
}

│ Streaming by default: a 488 MB log costs 1.4 MB of memory.

[1] https://termdoc.app

Not a mock-up. That block is generated by running termdoc over a Markdown file and translating the ANSI it emits — the colours, the wrapping and the box-drawing are the renderer’s own.

formats

FormatDetectedRenders
Markdown●●
Plain text●●
Logs●●
JSON · YAML · TOML●◐
XML · HTML · CSV●◐
Source code●◐
PDF · EPUB●✕
DOCX · ODT · XLSX · PPTX●✕

● works today · ◐ reader in development, shown as plain text with a warning on stderr · ✕ recognised, but this build refuses to display it rather than dumping bytes at your terminal.

The middle row is the honest one. A recognised text format still gets shown, because mid-roadmap that beats refusing to open the file — and --strict turns that warning into a non-zero exit if a script would rather stop. Run termdoc --formats to see what the binary you actually installed can read.

graceful degradation

box-drawing
┌──────────┬──────────┬─────┐
│ Format   │  Status  │ M   │
├──────────┼──────────┼─────┤
│ Markdown │  ready   │ M0  │
│ CSV      │ detected │ M1  │
│ PDF      │ pending  │ M3  │
└──────────┴──────────┴─────┘
--ascii
+----------+----------+-----+
| Format   |  Status  | M   |
+----------+----------+-----+
| Markdown |  ready   | M0  |
| CSV      | detected | M1  |
| PDF      | pending  | M3  |
+----------+----------+-----+
too narrow → tsv
Format	Status	M
Markdown	ready	M0
CSV	detected	M1
PDF	pending	M3

One table, three rungs down. Each gives up something the rung above it could afford, and the last one gives up the frame entirely: below a certain width a bordered table can only fit by truncating cells, so it stops being a table and becomes tab-separated values — output for cut and awk rather than for reading. Losing the borders is recoverable; losing the data is not.

Degradation is an input to the layout, not a chain of special cases bolted onto it. The terminal’s real capabilities are detected once, and every ladder — colour truecolor → 256 → 16 → none, hyperlinks, headings — reads from that same value. With colour off, not one escape byte is emitted.

features

install

# from crates.io
$ cargo install termdoc

# or a prebuilt binary — macOS · Linux · Windows
$ github.com/marturojt/termdoc/releases/latest

# then point it at anything
$ termdoc README.md
$ termdoc --explain odd.dat
$ cat README.md | termdoc

# Homebrew, AUR, Scoop — planned

Prebuilt binaries for macOS (universal), Linux (x86_64 and aarch64) and Windows are attached to every release, with SHA256SUMS.txt covering each archive — and CI unpacks and runs every one of them before the release is drafted. Building from source needs a Rust toolchain (rustup.rs). A Homebrew formula is still on the backlog.

what termdoc is not

status

3.9 msstartup
1.4 MBmemory · 488 MB input
258tests, 3 platforms

Readers exist for Markdown, plain text and logs. Detection recognises considerably more — JSON, YAML, TOML, XML, HTML, CSV, source code, PDF and the Office/ZIP family — and until each dedicated reader lands, a recognised-but-unreadable text format is shown as plain text with a warning on stderr. --strict turns that warning into an error.

→ design document → roadmap and backlog