diff --git a/CHANGELOG.md b/CHANGELOG.md
index 868fbda..c8212a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog
+## 0.11.1 — 2026-10-04
+
+### Fixed
+- **Inline code in table cells no longer shows its backticks.** `` `GET /sync` `` in a cell printed with the markdown backticks around it; it now shows just the code, as inline code does everywhere else.
+
+### Changed
+- **Shorter README, fuller docs.** The README is now a quick tour: the main features, install, a quick start and links. The detail moved to focused pages under `docs/`: install, features, themes and color, configuration and keybindings, command line, and troubleshooting. The themes page adds a complete custom-theme template, and the configuration page lists every keybinding action name.
+- **New website.** [borghei.github.io/ink](https://borghei.github.io/ink/) is redesigned around fresh recordings of the current release: a demo you can pause, install commands with copy buttons, screenshots of diagrams, the table of contents, the theme picker and the terminal theme on light and dark terminals, and links into the docs. It also gets a favicon, a 404 page and a new social preview image.
+
## 0.11.0 — 2026-10-03
### Added
diff --git a/Cargo.lock b/Cargo.lock
index 6c362e9..7dc30cb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1520,7 +1520,7 @@ dependencies = [
[[package]]
name = "ink-md"
-version = "0.11.0"
+version = "0.11.1"
dependencies = [
"anyhow",
"assert_cmd",
diff --git a/Cargo.toml b/Cargo.toml
index 6e6e4d4..88efe86 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "ink-md"
-version = "0.11.0"
+version = "0.11.1"
edition = "2021"
# Highest rust-version declared by any resolved dependency (quantette, via
# ratatui-image). CI's msrv job builds with exactly this toolchain.
diff --git a/README.md b/README.md
index 11394c9..8643cbc 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-ink renders markdown in your terminal with syntax highlighting, inline images, mermaid diagrams, themes, tabs, search, and a table of contents. It's fast on large documents, safe with untrusted files, and works as both an interactive reader and a `bat`-style pager. One binary. No dependencies. Built in Rust.
+---
-## Install
+ink renders markdown in your terminal: code, tables, images, diagrams and math, in a reader with search, tabs and a table of contents. It also works as a `bat`-style pager for scripts and git. One binary, no dependencies, written in Rust.
-### Quick install (macOS / Linux)
+## Features
-```bash
-curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh
-```
+- **Proper rendering.** Headings, tables with alignment, task lists, footnotes, admonitions, frontmatter and wikilinks.
+- **Highlighted code.** Every major language, in bordered blocks. Press `c` to copy a block's raw source.
+- **Inline images.** Real pixels on Kitty, iTerm2, WezTerm, Ghostty and Sixel terminals, half-blocks everywhere else. SVG too.
+- **Mermaid diagrams.** Flowcharts, state, class and ER diagrams drawn as boxes and arrows. Gantt charts, mindmaps, sequence diagrams and pie charts too.
+- **Math and emoji.** LaTeX renders as Unicode (`√(b² - 4ac)`) and `:rocket:` becomes 🚀.
+- **Made for reading.** Search, a table of contents you can filter, tabs, a file browser, link hints and watch mode.
+- **Select and copy.** Keyboard or mouse selection, copy a section as markdown, and it works over SSH and tmux.
+- **9 themes.** Including `terminal`, which follows your terminal's own color scheme. Or write your own.
+- **Pager mode.** `ink --plain` pages long output, prints clean text into pipes and handles `--line-range`, fzf previews and git diffs.
+- **Safe with untrusted files.** Escape sequences are stripped, and remote images stay off unless you ask for them.
-The installer picks the right binary for your OS, CPU and libc (static musl build on Alpine, Raspberry Pi and older-glibc systems), checks it against `SHA256SUMS` and installs to `/usr/local/bin` (using `sudo` only if it has to). Pin a version with `INK_VERSION=v0.8.0` or change the target with `INK_INSTALL_DIR="$HOME/.local/bin"`:
+## Install
```bash
-curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | INK_VERSION=v0.11.0 INK_INSTALL_DIR="$HOME/.local/bin" sh
-```
-
-### Quick install (Windows PowerShell)
-
-```powershell
-irm https://raw.githubusercontent.com/borghei/ink/main/install.ps1 | iex
-```
-
-Installs `ink.exe` (x64 or ARM64) to `%LOCALAPPDATA%\Programs\ink` and adds it to your user `PATH`. Set `$env:INK_VERSION = "v0.11.0"` first to pin a version.
-
-### Homebrew (macOS / Linux)
+# macOS, Linux
+curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh
-```bash
+# Homebrew
brew tap borghei/tap
-brew trust borghei/tap # recent Homebrew requires trusting third-party taps
+brew trust borghei/tap
brew install ink
-```
-
-### Conda / Pixi
-The community-maintained [conda-forge package](https://anaconda.org/conda-forge/ink-md) can be installed with:
-
-```bash
-conda install -c conda-forge ink-md
-# or
-pixi global install ink-md
-```
-
-### Cargo
-
-```bash
-cargo install ink-md # build from source
-cargo binstall ink-md # or grab the prebuilt binary (needs cargo-binstall)
-```
-
-### mise
-
-```bash
-mise use -g cargo:ink-md # via crates.io
-mise use -g ubi:borghei/ink # or straight from GitHub releases
-```
-
-### Debian / Ubuntu (.deb) and Fedora / openSUSE (.rpm)
-
-Download from the [releases page](https://github.com/borghei/ink/releases), then:
-
-```bash
-sudo apt install ./ink-md_*_amd64.deb # Debian/Ubuntu
-sudo dnf install ./ink-md-*.x86_64.rpm # Fedora/openSUSE
+# Cargo
+cargo install ink-md
```
-### Scoop (Windows)
-
```powershell
-scoop bucket add borghei https://github.com/borghei/scoop-bucket
-scoop install ink
-```
-
-### Pre-built binaries
-
-Grab the latest binary for your platform from the [releases page](https://github.com/borghei/ink/releases):
-
-| Platform | Asset |
-|---|---|
-| Linux x86_64 / arm64 (glibc 2.35+: Ubuntu 22.04, Debian 12 and newer) | `ink-linux-amd64`, `ink-linux-arm64` |
-| Linux x86_64 / arm64 / armv7, static (any distro: Alpine, Debian 11, Ubuntu 20.04, RHEL 8, NixOS, containers, Raspberry Pi) | `ink-linux-amd64-musl`, `ink-linux-arm64-musl`, `ink-linux-armv7-musl` |
-| macOS Intel / Apple Silicon | `ink-macos-amd64`, `ink-macos-arm64` |
-| Windows x64 / ARM64 | `ink-windows-amd64.exe`, `ink-windows-arm64.exe` |
-
-The glibc builds need glibc 2.35 or newer; older and musl-based systems use the static builds, and the install script picks for you. The Windows builds link the C runtime statically, so no Visual C++ redistributable is needed. Each binary also comes as an archive (`ink---.tar.gz`, `.zip` on Windows) bundling the man page and bash/zsh/fish completions, and the `.deb`/`.rpm` packages install those too.
-
-`SHA256SUMS` is published alongside, and every asset carries a signed build provenance attestation you can check with the GitHub CLI:
-
-```bash
-gh attestation verify ink-linux-amd64 --repo borghei/ink
+# Windows
+irm https://raw.githubusercontent.com/borghei/ink/main/install.ps1 | iex
```
-The static musl builds and Windows ARM64 binaries are new in v0.9.0; earlier releases only have the glibc, macOS and Windows x64 binaries.
-
-### From source
-
-```bash
-git clone https://github.com/borghei/ink.git
-cd ink
-cargo build --release
-# binary is at ./target/release/ink
-```
+Scoop, conda, mise, `.deb`, `.rpm`, prebuilt binaries and source builds are covered in the [install guide](https://github.com/borghei/ink/blob/main/docs/install.md).
## Quick start
```bash
-# Read a file
-ink README.md
-
-# Browse all markdown files in a directory
-ink .
-
-# Read from a URL
-ink https://raw.githubusercontent.com/borghei/ink/main/README.md
-
-# Pipe from stdin (or name it explicitly with -)
-cat notes.md | ink
-cat notes.md | ink -
-
-# Plain output (no TUI, pipe-friendly)
-ink --plain README.md
-```
-
-## Features
-
-### Renders markdown the way it should look
-
-Headings, bold, italic, strikethrough, links, blockquotes, lists, task lists, tables, footnotes, horizontal rules — all rendered with proper styling and colors.
-
-Tables follow their column alignment (`:--`, `:-:`, `--:`), wide CJK and emoji cells included. HTML superscript `x2` and subscript `H2O` come out as `x²` and `H₂O` (`x^(2)` and `H_(2)O` with `--ascii`); when a character has no Unicode form, or the tag holds links or other markup (a `` caption), its content is shown as written. Carets and double bars in prose (`2^10`, `a||b`) are shown as written: `^x^` and `||x||` are not GitHub markdown. Single and double tildes, `~x~` and `~~x~~`, strike through as on GitHub, and definition lists (`Term` then `: definition`) get a bold term with its definitions indented underneath.
-
-### Syntax-highlighted code blocks
-
-Language-aware highlighting for every major language. Code blocks get clean borders with the language label shown at the top.
-
-### Inline images
-
-Images in your markdown render directly in the terminal. On terminals with a graphics protocol (Kitty, iTerm2, WezTerm, Ghostty, or Sixel) ink draws real pixels — auto-detected at startup; everywhere else it falls back to Unicode half-blocks, which work in any true-color terminal. Images scroll with the document and clip cleanly at the edges. If an image can't load, ink shows a placeholder instead of crashing.
-
-Pick a renderer explicitly with `--image-protocol ` (default `auto`).
-
-Supported formats: PNG, JPEG, GIF, WebP, BMP, TIFF, ICO, TGA, QOI, PNM, HDR, OpenEXR, farbfeld — and SVG (including gzipped `.svgz`), rasterized at load time so vector diagrams render like any other image.
-
-Remote (`http`/`https`) images are **not** fetched by default — a document you didn't write shouldn't be able to phone home or probe your network. Pass `--remote-images` to enable them (private, loopback, and cloud-metadata addresses stay blocked even then).
-
-### Mermaid diagrams
-
-Flowcharts (every node shape, link style and direction, with subgraphs drawn as frames), state diagrams, class diagrams and ER diagrams are laid out as real box-and-arrow drawings that fit your terminal width; Gantt charts get a scaled time axis, mindmaps a tree, and sequence diagrams and pie charts a compact text form. Other diagram types show their source in a labelled box. Box-drawing characters by default, plain ASCII with `--ascii`. No external tools needed.
-
-### GitHub-style admonitions
-
-`[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, and `[!CAUTION]` blocks render with distinct colors and icons. A custom title (`> [!NOTE] Read this first`) replaces the type name, and Obsidian callouts (`> [!info]- Title`, `[!bug]`, `[!example]`, …) map onto the same five colours, fold markers ignored.
-
-### Frontmatter
-
-YAML (`---`) and TOML (`+++`) frontmatter is hidden by default. With `--frontmatter` (or `frontmatter = true`) it shows as a small key/value box at the top of the document — lists comma-joined, nested values as written — instead of being read as markdown. A leading JSON object (`{` on the first line) is never hidden: with `--frontmatter` it gets the same box when markdown follows it, and otherwise it is shown as document text.
-
-### Wikilinks
-
-`[[page]]` and `[[page|display text]]` syntax works out of the box. Great for browsing Obsidian vaults and personal wikis.
-
-### File browser
-
-Run `ink` with no arguments or point it at a directory. You'll get an interactive file picker that lists every `.md` file, with filtering and keyboard navigation.
-
-### Multi-tab support
-
-Open multiple files at once:
-
-```bash
-ink README.md CHANGELOG.md docs/guide.md
+ink README.md # read a file
+ink . # browse markdown files in a folder
+ink a.md b.md # one tab per file
+cat notes.md | ink # read stdin
+ink --plain README.md | head # plain output for pipes
+ink --theme terminal README.md # use your terminal's colors
```
-Switch between them with `Tab` and `Shift+Tab`.
-
-### Search
-
-Press `/` to search within a document. Matches highlight inline; press Enter to lock in the search, then `n`/`N` to cycle forward and backward through results. `Esc` clears the highlights.
-
-### Select text and copy it
-
-ink captures the mouse for wheel-scroll, which used to mean giving up your terminal's own text
-selection. Now it does the job itself, and does it better — it knows where a code block starts and
-where ink's own decoration ends. If you'd rather keep your terminal's own selection and link
-clicking, run `ink --no-mouse` (one session) or set `mouse_capture = false` (always); both apply to
-the reader and the file browser.
-
-- **`v`** starts a character-wise selection, **`V`** a line-wise one. Move with `h j k l`, arrows,
- `w`/`b` (word), `0`/`$` (line ends), `g`/`G` (document ends), `Ctrl+d`/`Ctrl+u` (half page).
- **`y`** copies and exits; `Esc` cancels.
-- **Drag with the mouse** to select, release to copy. Double-click takes the word, triple-click the
- line. A single click on a link follows it instead (see below).
-- **`c`** labels every code block on screen — press its letter to copy the block's *raw* source: no
- borders, no line numbers, no syntax-highlighting escapes.
-- **`Y`** copies the markdown source of the section you are reading (heading included, down to the
- next heading of the same level). Inside link-hint mode (`f`), `Y` switches the labels from
- "open this link" to "copy this URL".
-
-Copied text reaches the clipboard two ways at once: an OSC 52 escape sequence, which works over
-SSH and inside tmux, and a native helper (`pbcopy`, `wl-copy`, `xclip`, `xsel`, `clip.exe`) when one
-is installed locally. No extra dependencies, nothing to configure. Set `clipboard` in your config to
-narrow it down or turn it off.
-
-`v` and `V` copy lines the way they are drawn, ink's heading bars and code-box borders included —
-they select what you can see. Reach for `c` and `Y` when you want the source instead.
-
-### Open links from the keyboard
-
-Press `f` to label every link on screen with a letter; the popup lists each link's text next to its URL, so you can tell which is which. Press that letter to open web and mail links in your browser, or to follow a relative `.md` link or `#heading` anchor right inside ink (`[` goes back).
-
-Clicking works too: a plain click on a link (press and release without moving) does exactly what its letter would. Dragging across a link still selects it. With `--no-mouse` ink leaves clicks to your terminal, which opens links its own way (usually Cmd- or Ctrl-click).
-
-### Help overlay
+Press `?` in the reader for every key. The basics: `j` `k` scroll, `/` search, `t` table of contents, `f` open a link, `T` themes, `q` quit.
-Press `?` any time for a popup listing every active keybinding — including your own overrides.
+## Documentation
-### Table of contents
-
-Press `t` to toggle a sidebar showing every heading in the document. Tracks your position as you scroll.
-
-Press `o` to move into it (it opens if it was closed). `j`/`k` or the arrows move, `g`/`G` go to the first and last heading, `Ctrl+d`/`Ctrl+u` page, and `Enter` jumps there — `[` brings you back. `h`/`l` fold and unfold a section's subheadings in the sidebar, and `/` filters the list as you type (every word you type must appear, case doesn't matter). `Esc` clears the filter; `Esc` again, or `o`, goes back to the document without moving. With the mouse, click a heading to jump to it; the wheel over the sidebar scrolls the sidebar, not the page.
-
-### 9 built-in themes
-
-Dark, Light, Dracula, Catppuccin, Nord, Tokyo Night, Gruvbox, Solarized, and Terminal. Press `T` to open the theme picker and preview each one live.
-
-`terminal` uses your terminal's own colour scheme instead of fixed colours — the 16 palette colours and the default foreground, no background of its own, and code highlighted with the palette too (like `bat --theme=ansi`). It looks right on light and dark terminals without switching themes.
-
-With no theme set, ink asks the terminal for its background colour (an OSC 11 query, answered by nearly every modern terminal and passed through by tmux) and picks Light or Dark to match, falling back to `COLORFGBG` and then Dark. An explicit `--theme` or `theme =` in the config always wins, and never triggers the query.
-
-Themes adapt to what the terminal can show: 24-bit colour where it is advertised, the 256-colour palette on `*-256color` terminals, and the 16 ANSI colours on the Linux console and other 16-colour terminals (`TERM=linux`, `xterm`, `vt100`, `screen`, …) — there ink uses your terminal's own palette, so your colour scheme applies. With `--color=never` or `NO_COLOR` the reader draws without colour at all, using bold, underline and reverse video for headings, links, search hits and selections.
-
-On the Linux console, a non-UTF-8 locale, a legacy console font or a screen reader, box-drawing and symbol characters come out as junk. `ink --ascii` (or `ascii = true` under `[behavior]`) draws every border, bullet, task box, quote bar, rule and status-bar marker in plain 7-bit ASCII instead — `+--+`, `|`, `*`, `[x]`, `#` — and turns off smart quotes and emoji shortcodes, so an ASCII document prints as pure ASCII. It switches on by itself for `TERM=linux` and non-UTF-8 locales; `ascii = false` in the config keeps Unicode regardless.
-
-### Math and emoji
-
-Inline `$E=mc^2$`, block `$$...$$` and ```` ```math ```` render as Unicode text: `$x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$` reads `x = (-b ± √(b² - 4ac))/2a`. Greek letters, operators, `\mathbb{R}` → ℝ, super- and subscripts, fractions, roots, and matrix, `cases` and `aligned` environments (drawn on several lines with brackets) are covered; anything else is shown as written. A lone `$` in prose (`costs $5 and $10`) stays a dollar sign. With `--ascii` the LaTeX source is shown instead. `:emoji:` shortcodes resolve to their glyph (`:rocket:` → 🚀).
-
-### Presentation mode
-
-Split any markdown file into slides on `---` separators and navigate with ←/→/Space:
-
-```bash
-ink --slides deck.md
-```
-
-### Works as a pager
-
-Point `ink --plain` at a long document on an interactive terminal and it pages the output through `$PAGER` (default `less -R`) — a drop-in markdown replacement for `cat`/`less`. Piped or redirected output prints straight through, so it stays friendly for scripts, fzf previews, and git. Use `--no-pager` to always print directly. When stdout is not a terminal, `ink file.md` behaves like `ink --plain file.md`, as `bat` and `glow` do.
-
-`--line-range` works like `bat`'s: `ink --line-range 40:80 README.md` renders only those lines of the markdown *source* (1-based, inclusive; also `40:`, `:80`, a single line, or several `--line-range`s). A range that cuts through a fenced code block keeps the block intact and highlighted, inside a blockquote too. It always prints plain output.
-
-Color follows `--color ` (default `auto`). In `auto` mode, `--plain` and `ink diff` emit color and OSC 8 hyperlinks only when stdout is a terminal, so redirects, pipes, and `git` textconv get clean text. Precedence: an explicit `--color` wins; then `NO_COLOR` turns color off; then `CLICOLOR_FORCE=1` or `FORCE_COLOR` turns it on; then `TERM=dumb` turns it off; then the terminal check. Tools that display ANSI from a pipe need `--color=always`:
-
-```bash
-fzf --preview 'ink --plain --color=always {}'
-ink --plain --color=always notes.md | less -R
-
-# Render markdown in git diffs (clean text, no escapes)
-git config --global diff.markdown.textconv "ink --plain"
-echo '*.md diff=markdown' >> ~/.gitattributes
-```
-
-24-bit colors are downgraded to the 256-color palette on terminals that don't advertise truecolor (`COLORTERM`, Windows Terminal, VS Code, Ghostty, WezTerm and iTerm2 are detected).
-
-### Watch mode
-
-Auto-reload when the file changes on disk. Edit in another terminal, see the rendered view update within ~100ms. Scroll position is preserved.
-
-```bash
-ink --watch draft.md
-```
-
-Works with editors that save by replacing the inode (vim, IntelliJ) — ink watches the parent directory, not the file handle.
-
-### Document stats and outline
-
-```bash
-# Heading structure
-ink outline README.md
-
-# Word count, reading time, element counts
-ink stats README.md
-
-# Diff two markdown files
-ink diff old.md new.md
-```
-
-## Keybindings
-
-| Key | Action |
+| | |
|---|---|
-| `j` / `k` / `↑` / `↓` | Scroll up/down |
-| `Space` / `Page Down` | Page down |
-| `Page Up` | Page up |
-| `G` / `End` | Jump to end |
-| `Home` | Jump to start |
-| `Ctrl+f` / `Ctrl+b` | Page down / up |
-| `Ctrl+d` / `Ctrl+u` | Half-page down / up |
-| `n` / `N` | Next / previous heading (cycles search matches after a search) |
-| `/` | Search |
-| `f` | Link-hint mode (open links by letter, `Y` to copy one instead) |
-| `v` / `V` | Select text — character-wise / line-wise (`y` copies, `Esc` cancels) |
-| `c` | Copy a code block by letter |
-| `Y` | Copy the current section as markdown |
-| `e` | Edit the file in `$VISUAL` / `$EDITOR` (opens at the heading you are reading, reloads when you quit the editor) |
-| `t` | Toggle table of contents |
-| `o` | Focus the table of contents (`j`/`k` move, `Enter` jumps, `h`/`l` fold, `/` filters, `Esc` returns) |
-| `T` | Theme picker (choice is saved to config) |
-| `?` | Help overlay |
-| `Enter` | Follow first visible link |
-| `[` / `]` | Navigation back / forward |
-| `Tab` / `Shift+Tab` | Next / previous tab |
-| `Shift+B` | Back to file browser (when launched via browser) |
-| `q` / `Esc` / `Ctrl+C` | Quit ink (first press clears an active search) |
-
-### Customizing keybindings
-
-Pick a preset or override individual bindings in your config file (see [Configuration](#configuration)):
-
-```toml
-[keybindings]
-preset = "emacs" # default | vim | emacs
-
-[keybindings.bindings]
-# Per-action overrides, applied on top of the preset.
-toggle_toc = ["ctrl-t"]
-toc_focus = ["ctrl-o"]
-edit = ["alt-e"]
-```
-
-The **emacs** preset binds `Ctrl+N`/`Ctrl+P` (line nav), `Ctrl+V`/`Alt+V` (page nav), `Ctrl+A`/`Ctrl+E` (home/end), `Ctrl+S` (search), `Ctrl+F`/`Ctrl+B` (next/prev heading), and `Ctrl+X Ctrl+C` (chord exit).
-
-Two-key chord bindings work — write them with a space: `"ctrl-x ctrl-c"`.
-
-Run `ink keybindings` to print the active map. Run `ink config init` to drop a commented starter config in the right place for your platform.
-
-## Configuration
-
-ink reads `$XDG_CONFIG_HOME/ink/config.toml` when `XDG_CONFIG_HOME` is set, otherwise `~/.config/ink/config.toml` on Linux, `~/Library/Application Support/ink/config.toml` on macOS, and `%APPDATA%\ink\config.toml` on Windows. If you already have a config in the platform folder and nothing under `$XDG_CONFIG_HOME/ink` yet, ink keeps using the existing one until you move it. Run `ink config path` to print the resolved location.
-
-Create the file:
-
-```toml
-# Default theme (dark, light, dracula, catppuccin, nord, tokyo-night, gruvbox, solarized, terminal)
-theme = "catppuccin"
-
-# Max rendering width in columns
-width = 90
-
-# Line spacing: compact, normal, relaxed
-spacing = "normal"
-
-# Show table of contents on startup
-toc = false
-
-# Show YAML/TOML/JSON frontmatter as a metadata box at the top
-frontmatter = false
-
-# Behavior
-[behavior]
-# Set true to restore the old "return to file browser after closing a doc" behavior
-browser_loop = false
-
-# Set false to let your terminal handle the mouse (click-to-open links, text
-# selection) instead of ink capturing it for wheel-scroll. Default: true
-mouse_capture = true
-
-# How copied text reaches the clipboard:
-# auto - OSC 52 escape (crosses SSH and tmux) plus a native helper, if present
-# osc52 - escape sequence only
-# native - pbcopy / wl-copy / xclip / xsel / clip.exe / termux-clipboard-set only
-# off - copying is disabled
-clipboard = "auto"
-
-# Plain-ASCII borders, bullets and markers (Linux console, legacy fonts,
-# screen readers). Unset: automatic on TERM=linux and non-UTF-8 locales.
-# ascii = false
-```
-
-### Custom themes
-
-Drop a `.toml` file in the `themes/` folder next to your config file (e.g. `$XDG_CONFIG_HOME/ink/themes/` or `~/.config/ink/themes/`) and use it by name:
-
-```bash
-ink --theme mytheme README.md
-```
-
-Every color is customizable — headings, code, links, blockquotes, admonitions, status bar, and more. Check any built-in theme in `src/theme/builtin.rs` for the full list of color keys.
-
-A color is a hex value (`"#7aa2f7"`), one of your terminal's palette colours (`"ansi:blue"`, `"ansi:bright-black"`, or `"ansi:0"` through `"ansi:15"`), or `"default"` for the terminal's own foreground/background. Set `code_theme = "ansi"` to highlight code with the palette.
-
-## Shell integration
-
-```bash
-ink shell-setup bash # or zsh, fish
-```
-
-Prints config snippets you can add to your shell profile — aliases, fzf preview, git pager setup.
-
-### Shell completions and man page
-
-```bash
-ink completions zsh > ~/.zfunc/_ink # bash | zsh | fish | powershell | elvish
-ink man > /usr/local/share/man/man1/ink.1 # man page (troff)
-```
-
-## CLI reference
-
-```
-ink [OPTIONS] [FILE|URL]...
-
-Options:
- -t, --theme Color theme [default: auto]
- -w, --width Max width (columns, or: narrow, wide, full)
- -s, --slides Presentation mode
- -p, --plain Plain output (no TUI); automatic when stdout is not a terminal
- --color auto | always | never [default: auto]
- --watch Watch file for changes
- --toc Show table of contents on startup
- --no-images Disable image rendering
- --remote-images Allow fetching remote (http/https) images
- --image-protocol
auto | kitty | iterm2 | sixel | halfblocks
- --list-themes List available themes and exit
- --no-pager Never page --plain output, even on a TTY
- --frontmatter Show YAML/TOML/JSON frontmatter as a metadata box
- --line-range Render only these source lines (N, START:, :END;
- repeatable; implies --plain)
- --spacing Line spacing: compact, normal, relaxed
- --no-mouse Don't capture the mouse (overrides mouse_capture in config)
- --ascii Draw borders, bullets and markers in plain ASCII
-
-Subcommands:
- outline Show document heading structure
- stats Show document statistics
- diff Diff two markdown files
- shell-setup Print shell integration snippets
- completions Generate shell completions
- man Generate a man page
- config Config helpers (init, path)
- keybindings Print the active keybinding map
- doctor Print a diagnostic report to attach to an issue
-```
-
-## How it compares
-
-| Feature | ink | glow | mdcat | frogmouth |
-|---|---|---|---|---|
-| Interactive TUI | Yes | Yes | No | Yes |
-| Multi-tab | Yes | No | No | No |
-| In-document search | Yes | No | No | No |
-| Table of contents | Yes | No | No | Yes |
-| Inline images (graphics protocols) | Yes | No | Yes | No |
-| Inline images (half-block fallback) | Yes | No | No | No |
-| Mermaid diagrams | Yes | No | No | No |
-| Admonitions | Yes | No | No | No |
-| Wikilinks | Yes | No | No | No |
-| File browser | Yes | Yes | No | Yes |
-| Watch mode | Yes | No | No | No |
-| Presentation mode | Yes | No | No | No |
-| Pager mode | Yes | Yes | No | No |
-| Shell completions + man page | Yes | Yes | Yes | No |
-| Math + emoji | Yes | No | No | No |
-| Themes | 8 | 2 | 0 | 0 |
-| Single binary | Yes | Yes | Yes | No |
-
-## Troubleshooting images
-
-Terminal graphics support varies wildly. If an image is blank, garbled, or missing:
-
-1. **Try the universal renderer:** `ink --image-protocol halfblocks file.md`. If the image appears as coarse colored blocks, decoding is fine — the problem is your terminal's pixel graphics protocol.
-2. **Try a specific protocol:** `--image-protocol iterm2` (iTerm2, WezTerm, VS Code, Warp and friends) or `--image-protocol sixel`. Some terminals advertise protocols they only partially implement — auto-detection already works around the known cases (e.g. iTerm2 claiming kitty support), but new terminal versions ship new quirks.
-3. **Collect a diagnostic report:** run `ink doctor` in the affected terminal — it prints your platform and terminal identity, the colour depth and theme ink picked (and which signal decided each), the clipboard helper and OSC 52 wrapping it would use, mouse capture, config warnings, what the graphics negotiation chose, and decoder self-tests. It leaves out anything that identifies you (no hostnames, user names, IPs or session IDs; your home directory shows as `~`), so it is safe to paste into an issue. `ink doctor --save ink-doctor.txt` writes it to a file. The same report helps with colour, theme and clipboard problems.
-4. **Send it to us:** open an [image rendering issue](https://github.com/borghei/ink/issues/new?template=image-rendering.yml) with the report attached. That output usually pinpoints the problem immediately.
-
-## Security model
-
-ink treats every document as untrusted input: control bytes and escape
-sequences are stripped before anything reaches the terminal, link schemes are
-restricted to `http`/`https`/`mailto`, and remote image fetching is **off by
-default** (`--remote-images` opts in). Local images referenced by a document
-— absolute paths included — are read and rendered, but only ever as pixels:
-image bytes must decode as an image and are never shown as text, so a hostile
-document cannot use an image tag to put file *contents* on screen.
-
-**Note for Windows authors:** markdown treats `\` as an escape character, so
-a path like `C:\pics\.cache\x.png` loses its separators in any CommonMark
-renderer. Write image paths with forward slashes (`C:/pics/.cache/x.png`) —
-they work everywhere, including on Windows.
+| [Install](https://github.com/borghei/ink/blob/main/docs/install.md) | Every install route, binaries, verifying downloads |
+| [Features](https://github.com/borghei/ink/blob/main/docs/features.md) | Everything ink renders and does, plus how it compares to glow, mdcat and frogmouth |
+| [Themes and color](https://github.com/borghei/ink/blob/main/docs/themes.md) | Built-in themes, the terminal theme, custom themes |
+| [Configuration](https://github.com/borghei/ink/blob/main/docs/configuration.md) | Config file, settings, keybindings and presets |
+| [Command line](https://github.com/borghei/ink/blob/main/docs/cli.md) | Flags, subcommands, pager use, recipes, shell setup |
+| [Troubleshooting](https://github.com/borghei/ink/blob/main/docs/troubleshooting.md) | `ink doctor`, images, colors, clipboard, security model |
## Contributing
-Contributions are welcome. Check out [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
+Bug reports and pull requests are welcome. Read [CONTRIBUTING.md](https://github.com/borghei/ink/blob/main/CONTRIBUTING.md) first, and attach `ink doctor` output to bug reports.
-## License
-
-Free to use, modify, and distribute. Cannot be sold — not the original, not forks, not derivatives. See [LICENSE](LICENSE) for the full text.
-
-## Author
+Thanks to everyone who has sent a pull request:
-Made by [borghei](https://github.com/borghei) — who got tired of reading raw markdown like a caveman.
+- [@mariusrueve](https://github.com/mariusrueve) for the Conda and Pixi instructions ([#9](https://github.com/borghei/ink/pull/9)) and the [conda-forge package](https://github.com/conda-forge/ink-md-feedstock) behind them
-## Contributors
+## License
-Thanks to everyone who has sent a pull request:
+Free to use, modify and share. It can't be sold: not the original, not forks, not derivatives. See [LICENSE](https://github.com/borghei/ink/blob/main/LICENSE).
-- [@mariusrueve](https://github.com/mariusrueve) — Conda and Pixi install instructions ([#9](https://github.com/borghei/ink/pull/9)), and the [conda-forge package](https://github.com/conda-forge/ink-md-feedstock) behind them
+Made by [borghei](https://github.com/borghei), who got tired of reading raw markdown like a caveman.
diff --git a/docs/404.html b/docs/404.html
new file mode 100644
index 0000000..4c10f4a
--- /dev/null
+++ b/docs/404.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+ Page not found: ink
+
+
+
+
+
+
+
+
+
+
$ ink this-page.md
+error: no such file
+
This page doesn't exist.
+
The link may be old, or the docs moved. Everything lives on the home page or in the docs on GitHub.
+ Back to ink
+
+
+
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..d000d52
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,12 @@
+# ink documentation
+
+| Page | What's in it |
+|---|---|
+| [Install](install.md) | Every install route, prebuilt binaries, verifying downloads |
+| [Features](features.md) | What ink renders and everything you can do in the reader |
+| [Themes and color](themes.md) | Built-in themes, the terminal theme, color depth, ASCII mode, custom themes |
+| [Configuration](configuration.md) | The config file, every setting, keybindings and presets |
+| [Command line](cli.md) | Flags, subcommands, pager use, scripting recipes, shell setup |
+| [Troubleshooting](troubleshooting.md) | `ink doctor`, images, colors, clipboard, security model |
+
+Release notes are in the [changelog](../CHANGELOG.md). Want to help? Read [CONTRIBUTING](../CONTRIBUTING.md).
diff --git a/docs/assets/demo.gif b/docs/assets/demo.gif
index 2a3ba58..873f0d0 100644
Binary files a/docs/assets/demo.gif and b/docs/assets/demo.gif differ
diff --git a/docs/assets/demo.mp4 b/docs/assets/demo.mp4
new file mode 100644
index 0000000..85436ad
Binary files /dev/null and b/docs/assets/demo.mp4 differ
diff --git a/docs/assets/og-image.png b/docs/assets/og-image.png
index a5d13fd..525ef52 100644
Binary files a/docs/assets/og-image.png and b/docs/assets/og-image.png differ
diff --git a/docs/assets/shot-mermaid.png b/docs/assets/shot-mermaid.png
new file mode 100644
index 0000000..6ca3f5e
Binary files /dev/null and b/docs/assets/shot-mermaid.png differ
diff --git a/docs/assets/shot-reader.png b/docs/assets/shot-reader.png
new file mode 100644
index 0000000..b1c9782
Binary files /dev/null and b/docs/assets/shot-reader.png differ
diff --git a/docs/assets/shot-terminal-dark.png b/docs/assets/shot-terminal-dark.png
new file mode 100644
index 0000000..9718cbd
Binary files /dev/null and b/docs/assets/shot-terminal-dark.png differ
diff --git a/docs/assets/shot-terminal-light.png b/docs/assets/shot-terminal-light.png
new file mode 100644
index 0000000..2fe571c
Binary files /dev/null and b/docs/assets/shot-terminal-light.png differ
diff --git a/docs/assets/shot-themes.png b/docs/assets/shot-themes.png
new file mode 100644
index 0000000..61701fb
Binary files /dev/null and b/docs/assets/shot-themes.png differ
diff --git a/docs/assets/shot-toc.png b/docs/assets/shot-toc.png
new file mode 100644
index 0000000..524354f
Binary files /dev/null and b/docs/assets/shot-toc.png differ
diff --git a/docs/assets/showcase.md b/docs/assets/showcase.md
new file mode 100644
index 0000000..ee56dce
--- /dev/null
+++ b/docs/assets/showcase.md
@@ -0,0 +1,50 @@
+# Release checklist
+
+Shipping **v2.4** of the sync service on Friday. Everything below has to be
+green first. Build notes live in `docs/release.md`, and the on-call rota is
+on the [team wiki](https://example.com/wiki/oncall).
+
+> [!WARNING]
+> The schema change locks the `events` table. Run it outside peak hours.
+
+## Tasks
+
+- [x] Freeze the `main` branch
+- [x] Run the load test against staging
+- [ ] Rotate the API signing key
+- [ ] Post the changelog in #releases
+
+## Latency budget
+
+| Endpoint | p50 | p99 | Status |
+|:-------------|:-----:|------:|:------:|
+| GET /sync | 12 ms | 48 ms | ok |
+| POST /push | 31 ms | 95 ms | ok |
+| GET /diff | 54 ms | 210 ms| slow |
+
+## Retry logic
+
+```rust
+fn backoff(attempt: u32) -> Duration {
+ let base = Duration::from_millis(100);
+ base * 2u32.pow(attempt.min(6))
+}
+```
+
+Worst-case wait after $n$ retries is $\sum_{k=0}^{n} 100 \cdot 2^k$ ms.
+
+## Rollout
+
+```mermaid
+flowchart LR
+ A[Build] --> B[Staging]
+ B --> C{Load test}
+ C -->|pass| D[Canary 5%]
+ C -->|fail| A
+ D --> E[Everyone]
+```
+
+## After the release
+
+Watch the error budget for 24 hours. If p99 on `/sync` goes over
+**100 ms**, roll back first and debug second.
diff --git a/docs/cli.md b/docs/cli.md
new file mode 100644
index 0000000..2b954c8
--- /dev/null
+++ b/docs/cli.md
@@ -0,0 +1,132 @@
+# Command line
+
+- [Usage](#usage)
+- [Options](#options)
+- [Subcommands](#subcommands)
+- [Using ink as a pager](#using-ink-as-a-pager)
+- [Color in plain output](#color-in-plain-output)
+- [Rendering part of a file](#rendering-part-of-a-file)
+- [Recipes](#recipes)
+- [Shell integration](#shell-integration)
+
+## Usage
+
+```
+ink [OPTIONS] [FILE|URL]... [COMMAND]
+```
+
+With no file, ink reads stdin when something is piped in and opens the file browser otherwise. `-` means stdin explicitly.
+
+## Options
+
+| Option | What it does |
+|---|---|
+| `-t`, `--theme ` | Color theme. Default `auto`, which matches the terminal background. See [Themes](themes.md). |
+| `-w`, `--width ` | Max text width: 20 to 1000 columns, or `narrow`, `wide`, `full` |
+| `-s`, `--slides` | Presentation mode, split on `---` |
+| `-p`, `--plain` | Print rendered output instead of opening the reader. Automatic when stdout isn't a terminal. |
+| `--color ` | `auto`, `always` or `never`. Default `auto`. See [Color in plain output](#color-in-plain-output). |
+| `--watch` | Re-render when the file changes |
+| `--toc` | Open with the table of contents showing |
+| `--no-images` | Don't render images |
+| `--remote-images` | Allow `http` and `https` images. Off by default. |
+| `--image-protocol
` | `auto`, `kitty`, `iterm2`, `sixel` or `halfblocks` |
+| `--list-themes` | List built-in and custom themes, then exit |
+| `--no-pager` | Never page `--plain` output, even on a terminal |
+| `--frontmatter` | Show frontmatter as a box at the top |
+| `--line-range ` | Render only these source lines. Repeatable. Implies `--plain`. |
+| `--spacing ` | `compact`, `normal` or `relaxed` |
+| `--no-mouse` | Leave the mouse to your terminal for this session |
+| `--ascii` | Plain ASCII borders, bullets and markers |
+| `-h`, `--help` | Help. `--help` is longer than `-h`. |
+| `-V`, `--version` | Version |
+
+Most options have a config equivalent. See [Configuration](configuration.md).
+
+## Subcommands
+
+| Command | What it does |
+|---|---|
+| `ink outline ` | Print the heading structure |
+| `ink stats ` | Word count, reading time and element counts |
+| `ink diff ` | Diff two markdown files |
+| `ink keybindings` | Print the active key map, preset plus your overrides |
+| `ink config init` | Write a commented starter config |
+| `ink config path` | Print where the config lives |
+| `ink doctor [--save FILE]` | Diagnostic report for bug reports. See [Troubleshooting](troubleshooting.md). |
+| `ink shell-setup ` | Print shell snippets: aliases, fzf preview, git setup |
+| `ink completions ` | Shell completions: `bash`, `zsh`, `fish`, `powershell`, `elvish` |
+| `ink man` | Man page (troff) on stdout |
+
+## Using ink as a pager
+
+`ink --plain` renders the document and prints it, styled, without the interactive reader.
+
+- On a terminal, long output goes through `$PAGER` (default `less -R`), so ink works as a markdown `cat` or `less`.
+- Piped or redirected, it prints straight through. Scripts, fzf previews and git get clean output.
+- `--no-pager` always prints directly.
+
+You rarely need the flag: when stdout isn't a terminal, `ink file.md` already behaves like `ink --plain file.md`, as `bat` and `glow` do.
+
+## Color in plain output
+
+`--color` decides whether `--plain` and `ink diff` emit color and OSC 8 hyperlinks. In order:
+
+1. `--color=always` or `--color=never` wins.
+2. `NO_COLOR` turns color off.
+3. `CLICOLOR_FORCE=1` or `FORCE_COLOR` turns it on.
+4. `TERM=dumb` turns it off.
+5. Otherwise, color only when stdout is a terminal.
+
+So redirects, pipes and `git` textconv get clean text by default. A tool that shows ANSI from a pipe, like fzf or `less -R`, needs `--color=always`.
+
+24-bit colors drop to the 256-color palette on terminals that don't advertise truecolor.
+
+## Rendering part of a file
+
+`--line-range` works like `bat`'s. It picks lines of the markdown source (1-based, inclusive) and always prints plain output.
+
+```bash
+ink --line-range 40:80 README.md # lines 40 to 80
+ink --line-range 40: README.md # line 40 to the end
+ink --line-range :80 README.md # start to line 80
+ink --line-range 12 README.md # one line
+ink --line-range 1:5 --line-range 40:50 README.md
+```
+
+A range that cuts through a fenced code block keeps the block intact and highlighted, inside a blockquote too.
+
+## Recipes
+
+```bash
+# fzf with a rendered preview
+fzf --preview 'ink --plain --color=always {}'
+
+# page a file yourself
+ink --plain --color=always notes.md | less -R
+
+# readable markdown in git diffs (clean text, no escapes)
+git config --global diff.markdown.textconv "ink --plain"
+echo '*.md diff=markdown' >> ~/.gitattributes
+
+# read a README from the web
+ink https://raw.githubusercontent.com/borghei/ink/main/README.md
+```
+
+## Shell integration
+
+```bash
+ink shell-setup zsh # or bash, fish
+```
+
+This prints snippets for your shell profile: aliases, an fzf preview and git setup. Read them, then paste the parts you want.
+
+Completions and the man page:
+
+```bash
+ink completions zsh > ~/.zfunc/_ink
+ink completions fish > ~/.config/fish/completions/ink.fish
+ink man > /usr/local/share/man/man1/ink.1
+```
+
+The release archives and the `.deb` and `.rpm` packages already include both.
diff --git a/docs/configuration.md b/docs/configuration.md
new file mode 100644
index 0000000..504a7a4
--- /dev/null
+++ b/docs/configuration.md
@@ -0,0 +1,144 @@
+# Configuration
+
+- [Where the config lives](#where-the-config-lives)
+- [Settings](#settings)
+- [Keybindings](#keybindings)
+- [Custom keybindings](#custom-keybindings)
+
+## Where the config lives
+
+| Platform | Path |
+|---|---|
+| `XDG_CONFIG_HOME` set (any platform) | `$XDG_CONFIG_HOME/ink/config.toml` |
+| Linux | `~/.config/ink/config.toml` |
+| macOS | `~/Library/Application Support/ink/config.toml` |
+| Windows | `%APPDATA%\ink\config.toml` |
+
+If you already have a config in the platform folder and nothing under `$XDG_CONFIG_HOME/ink` yet, ink keeps using the existing one until you move it.
+
+```bash
+ink config path # print the location in effect
+ink config init # write a commented starter config there
+```
+
+Command-line flags override the config for one run.
+
+## Settings
+
+Every setting is optional. These are the defaults:
+
+```toml
+# dark, light, dracula, catppuccin, nord, tokyo-night, gruvbox, solarized,
+# terminal, or the name of a custom theme. Unset: match the terminal background.
+# theme = "dark"
+
+# Max text width in columns, 20 to 1000. Unset: the terminal width, up to 120.
+# Plain output uses 80.
+# width = 90
+
+# Line spacing: compact, normal, relaxed
+spacing = "normal"
+
+# Open with the table of contents showing
+toc = false
+
+# Show YAML/TOML/JSON frontmatter as a box at the top
+frontmatter = false
+
+[behavior]
+# true: quitting a document returns to the file browser instead of exiting
+browser_loop = false
+
+# false: leave the mouse to your terminal, so its own selection and link
+# clicking keep working. You lose wheel-scroll inside ink.
+mouse_capture = true
+
+# How copied text reaches the clipboard:
+# auto - OSC 52 escape (works over SSH and tmux) plus a native helper
+# osc52 - escape sequence only
+# native - pbcopy, wl-copy, xclip, xsel, clip.exe or termux-clipboard-set only
+# off - copying is disabled
+clipboard = "auto"
+
+# Plain ASCII borders, bullets and markers. Unset: automatic on TERM=linux
+# and non-UTF-8 locales.
+# ascii = false
+
+[keybindings]
+preset = "default"
+```
+
+Themes have their own page: [Themes and color](themes.md).
+
+`ink doctor` reports config problems, such as an unknown key or a bad value, without touching the file.
+
+## Keybindings
+
+The default preset is vim-flavored. Press `?` in the reader for this list, including your own changes, or run `ink keybindings` to print it.
+
+| Key | Action |
+|---|---|
+| `j` `k`, `↓` `↑` | Scroll |
+| `Alt+↓` `Alt+↑` | Scroll faster |
+| `Space`, `Page Down`, `Ctrl+f`, `Ctrl+d` | Page down |
+| `Page Up`, `Ctrl+b`, `Ctrl+u` | Page up |
+| `Home` | Top |
+| `G`, `End` | Bottom |
+| `n` `N` | Next, previous heading. After a search, next and previous match. |
+| `/` | Search |
+| `t` | Toggle the table of contents |
+| `o` | Move focus into the table of contents |
+| `f` | Label links. Press a letter to open one, or `Y` then a letter to copy its URL. |
+| `Enter` | Follow the first visible link |
+| `[` `]`, `Alt+←` `Alt+→` | Back, forward |
+| `v` `V` | Select by character, by line. `y` copies. |
+| `c` | Copy a code block by letter |
+| `Y` | Copy the current section as markdown |
+| `e` | Open the file in `$VISUAL` or `$EDITOR` |
+| `T` | Theme picker |
+| `?` | Help |
+| `Tab` `Shift+Tab` | Next, previous tab |
+| `B` | Back to the file browser |
+| `q`, `Esc`, `Ctrl+c` | Quit. The first press clears an active search. |
+
+## Custom keybindings
+
+Pick a preset, then override single actions on top of it:
+
+```toml
+[keybindings]
+preset = "emacs" # default, vim or emacs
+
+[keybindings.bindings]
+toggle_toc = ["ctrl-t"]
+toc_focus = ["ctrl-o"]
+edit = ["alt-e"]
+exit_app = ["ctrl-x ctrl-c"] # two-key chord: separate the keys with a space
+```
+
+The **emacs** preset adds `Ctrl+n` `Ctrl+p` to move by line, `Ctrl+v` `Alt+v` to page, `Ctrl+a` `Ctrl+e` for top and bottom, `Ctrl+s` to search, `Ctrl+f` for the next heading and the chord `Ctrl+x Ctrl+c` to quit. The arrow keys, `j` `k`, `/` and most single letters keep working.
+
+Action names:
+
+| Action | Default keys |
+|---|---|
+| `scroll_down`, `scroll_up` | `j` `down`, `k` `up` |
+| `scroll_down_fast`, `scroll_up_fast` | `alt-down`, `alt-up` |
+| `page_down` | `space` `pagedown` `ctrl-f` `ctrl-d` |
+| `page_up` | `pageup` `ctrl-b` `ctrl-u` |
+| `home`, `end` | `home`, `G` `end` |
+| `next_heading`, `prev_heading` | `n`, `N` |
+| `search` | `/` |
+| `toggle_toc`, `toc_focus` | `t`, `o` |
+| `link_mode`, `follow_link` | `f`, `enter` |
+| `nav_back`, `nav_forward` | `[` `alt-left`, `]` `alt-right` |
+| `select_mode`, `select_line_mode` | `v`, `V` |
+| `copy_code`, `copy_section` | `c`, `Y` |
+| `edit` | `e` |
+| `theme_picker` | `T` |
+| `help` | `?` |
+| `next_tab`, `prev_tab` | `tab`, `backtab` |
+| `open_browser` | `B` |
+| `exit_app` | `q` `esc` `ctrl-c` |
+
+Key names are lowercase, joined with `-`: `ctrl-t`, `alt-e`, `shift-v`, `shift-tab`, `pagedown`. A capital letter (`V`) is the same as `shift-v`.
diff --git a/docs/demo.tape b/docs/demo.tape
index f49d14f..7b724a9 100644
--- a/docs/demo.tape
+++ b/docs/demo.tape
@@ -1,81 +1,57 @@
+# Hero recording for the README and the site. Run from the repo root with a
+# v0.11+ `ink` on PATH: vhs docs/demo.tape
+# Screenshots (docs/assets/shot-*.png) use the same settings plus `Screenshot`.
Output docs/assets/demo.gif
Set Shell "bash"
-Set FontSize 14
-Set Width 960
-Set Height 600
+Set FontFamily "Geist Mono"
+Set FontSize 15
+Set Width 1200
+Set Height 720
+Set Padding 20
+Set Framerate 20
Set Theme "Catppuccin Mocha"
-Set Padding 16
-Set TypingSpeed 40ms
+Set TypingSpeed 60ms
-Type "ink tests/fixtures/demo.md"
+Hide
+Type "cd docs/assets && clear"
Enter
-Sleep 2s
+Sleep 500ms
+Show
-# Scroll down slowly
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
-Sleep 400ms
-Down
Sleep 400ms
+Type "ink --theme catppuccin showcase.md"
+Sleep 300ms
+Enter
+Sleep 2s
+# Scroll
+Down 6
+Sleep 300ms
+Down 6
Sleep 1s
-# Open TOC
+# Table of contents
Type "t"
-Sleep 1.5s
-
-# Close TOC
+Sleep 1.8s
Type "t"
-Sleep 500ms
+Sleep 600ms
# Search
Type "/"
Sleep 300ms
-Type "theme"
-Sleep 1s
-Escape
-Sleep 500ms
+Type "rollout"
+Sleep 400ms
+Enter
+Sleep 1.8s
-# Open theme picker
+# Theme picker, ending on `terminal`
Type "T"
-Sleep 1s
-Down
-Sleep 500ms
-Down
-Sleep 500ms
-Down
-Sleep 500ms
-Up
-Sleep 500ms
+Sleep 900ms
+Down 5
+Sleep 2s
Escape
Sleep 1s
-# Quit
Type "q"
Sleep 500ms
diff --git a/docs/favicon.svg b/docs/favicon.svg
new file mode 100644
index 0000000..3d8f91b
--- /dev/null
+++ b/docs/favicon.svg
@@ -0,0 +1,5 @@
+
diff --git a/docs/features.md b/docs/features.md
new file mode 100644
index 0000000..ca0ea01
--- /dev/null
+++ b/docs/features.md
@@ -0,0 +1,235 @@
+# Features
+
+Everything ink does, grouped by what you're trying to do. For flags and config keys, see the [CLI reference](cli.md) and [Configuration](configuration.md).
+
+- [Opening documents](#opening-documents)
+- [Markdown rendering](#markdown-rendering)
+- [Code blocks](#code-blocks)
+- [Images](#images)
+- [Mermaid diagrams](#mermaid-diagrams)
+- [Math and emoji](#math-and-emoji)
+- [Admonitions and callouts](#admonitions-and-callouts)
+- [Frontmatter](#frontmatter)
+- [Wikilinks](#wikilinks)
+- [Moving around](#moving-around)
+- [Search](#search)
+- [Table of contents](#table-of-contents)
+- [Links](#links)
+- [Selecting and copying](#selecting-and-copying)
+- [Editing](#editing)
+- [Tabs and the file browser](#tabs-and-the-file-browser)
+- [Watch mode](#watch-mode)
+- [Presentation mode](#presentation-mode)
+- [Outline, stats and diff](#outline-stats-and-diff)
+- [How ink compares](#how-ink-compares)
+
+## Opening documents
+
+```bash
+ink README.md # one file
+ink README.md CHANGELOG.md # several files, one tab each
+ink . # browse every markdown file under a folder
+ink # same as ink .
+ink https://raw.githubusercontent.com/borghei/ink/main/README.md
+cat notes.md | ink # stdin (or name it with -)
+```
+
+When stdout isn't a terminal, `ink file.md` prints plain output instead of opening the reader, the way `bat` and `glow` do. More on that in [using ink as a pager](cli.md#using-ink-as-a-pager).
+
+## Markdown rendering
+
+Headings, emphasis, strikethrough, links, blockquotes, nested lists, task lists, tables, footnotes and horizontal rules all get proper styling.
+
+A few details worth knowing:
+
+- **Tables** follow their column alignment (`:--`, `:-:`, `--:`), with wide CJK and emoji cells measured correctly.
+- **`` and ``** become real superscript and subscript when every character has a Unicode form: `x2` is `x²` and `H2O` is `H₂O`. With `--ascii` they read `x^(2)` and `H_(2)O`. Anything else is shown as written.
+- **Strikethrough** works with one or two tildes, as on GitHub. Carets and double bars in prose (`2^10`, `a||b`) stay as typed, since `^x^` and `||x||` aren't GitHub markdown.
+- **Definition lists** (`Term`, then `: definition`) get a bold term with the definitions indented underneath.
+
+## Code blocks
+
+Fenced code is syntax highlighted for every major language. Each block gets a border with the language label on top. Long lines wrap inside the box instead of breaking it.
+
+Press `c` to copy a block's raw source. See [Selecting and copying](#selecting-and-copying).
+
+## Images
+
+Images render inside the document and scroll with it.
+
+| Terminal | What you get |
+|---|---|
+| Kitty, iTerm2, WezTerm, Ghostty, anything with Sixel | Real pixels, picked automatically at startup |
+| Any other true-color terminal | Unicode half-blocks |
+
+Force a renderer with `--image-protocol auto|kitty|iterm2|sixel|halfblocks`, or turn images off with `--no-images`.
+
+Supported formats: PNG, JPEG, GIF, WebP, BMP, TIFF, ICO, TGA, QOI, PNM, HDR, OpenEXR and farbfeld. SVG and gzipped `.svgz` are rasterized at load time, so vector diagrams render like any other image. An image that can't load shows a placeholder.
+
+**Remote images are off by default.** A document you didn't write shouldn't be able to phone home or probe your network. Pass `--remote-images` to allow `http` and `https` images. Private, loopback and cloud-metadata addresses stay blocked even then.
+
+Blank or garbled images? See [Troubleshooting](troubleshooting.md#images).
+
+## Mermaid diagrams
+
+` ```mermaid ` blocks are drawn as text that fits your terminal width. No external tools needed.
+
+| Diagram | How it's drawn |
+|---|---|
+| Flowchart | Boxes and routed arrows in every direction (TD, BT, LR, RL), all node shapes and link styles, edge labels, subgraphs as frames |
+| State, class, ER | The same box-and-arrow layout |
+| Gantt | Bars on a scaled time axis |
+| Mindmap | A tree |
+| Sequence, pie | A compact text form |
+| Anything else | The source, in a titled box |
+
+Box-drawing characters by default, plain ASCII with `--ascii`.
+
+## Math and emoji
+
+Inline `$...$`, block `$$...$$` and ` ```math ` blocks render as Unicode text. `$x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$` reads:
+
+```
+x = (-b ± √(b² - 4ac))/2a
+```
+
+Greek letters, operators, `\mathbb{R}` (ℝ), superscripts, subscripts, fractions and roots are covered. Matrices and the `cases` and `aligned` environments draw across several lines with brackets. Anything ink doesn't know is shown as written.
+
+A lone `$` in prose stays a dollar sign, so `costs $5 and $10` is safe. With `--ascii` you get the LaTeX source.
+
+`:emoji:` shortcodes become the glyph: `:rocket:` is 🚀.
+
+## Admonitions and callouts
+
+GitHub's `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]` and `[!CAUTION]` blocks get their own color and icon.
+
+```markdown
+> [!NOTE] Read this first
+> A custom title replaces the type name.
+```
+
+Obsidian callouts (`> [!info]- Title`, `[!bug]`, `[!example]` and friends) map onto the same five colors. Fold markers are ignored.
+
+## Frontmatter
+
+YAML (`---`) and TOML (`+++`) frontmatter is hidden by default. With `--frontmatter`, or `frontmatter = true` in the config, it shows as a small key/value box at the top. Lists are comma-joined and nested values are shown as written.
+
+A leading JSON object is never hidden. With `--frontmatter` it gets the same box when markdown follows it. Otherwise it's document text.
+
+## Wikilinks
+
+`[[page]]` and `[[page|display text]]` work out of the box, which makes ink a good way to read Obsidian vaults and personal wikis.
+
+## Moving around
+
+Vim-style keys, arrows and the usual paging keys all work. `n` and `N` jump between headings. Press `?` at any time for a popup of every active binding, your own overrides included.
+
+The full list is in [Configuration: keybindings](configuration.md#keybindings).
+
+## Search
+
+Press `/` and type. Matches highlight as you go. `Enter` locks the search in, `n` and `N` cycle through results, and `Esc` clears them.
+
+## Table of contents
+
+`t` toggles a sidebar with every heading. It follows your position as you scroll.
+
+`o` moves focus into the sidebar, opening it if needed:
+
+| Key | Action |
+|---|---|
+| `j` `k`, arrows | Move |
+| `g` `G` | First, last heading |
+| `Ctrl+d` `Ctrl+u` | Page |
+| `Enter` | Jump to the heading (`[` brings you back) |
+| `h` `l` | Fold, unfold a section |
+| `/` | Filter headings. Every word you type must appear, case ignored. |
+| `Esc` | Clear the filter, then return to the document |
+
+With the mouse, click a heading to jump to it. The wheel over the sidebar scrolls the sidebar, not the page.
+
+## Links
+
+Press `f` and every link on screen gets a letter. The popup lists each link's text next to its URL so you can tell them apart. Press the letter to:
+
+- open a web or mail link in your browser
+- follow a relative `.md` link or a `#heading` anchor inside ink (`[` goes back, `]` forward)
+
+Press `Y` while the labels are up to copy a link's URL instead.
+
+Clicking works too. A plain click on a link does what its letter would, and dragging across a link still selects text. With `--no-mouse`, clicks go to your terminal, which opens links its own way (usually Cmd-click or Ctrl-click).
+
+Only `http`, `https` and `mailto` links are ever opened.
+
+## Selecting and copying
+
+ink captures the mouse so the wheel scrolls the document. It makes up for taking over your terminal's selection by doing a better job of it: it knows where a code block starts and where its own decoration ends.
+
+| Key | What it copies |
+|---|---|
+| `v`, `V` | Start a character or line selection. Move with `h j k l`, arrows, `w` `b`, `0` `$`, `g` `G`, `Ctrl+d` `Ctrl+u`. `y` copies, `Esc` cancels. |
+| Mouse drag | Selects. Release to copy. Double-click takes a word, triple-click a line. |
+| `c` | Labels every code block on screen. Press a letter to copy that block's raw source, with no borders or highlighting. |
+| `Y` | The markdown source of the section you're reading, from its heading down to the next heading of the same level |
+
+`v` and `V` copy what you see, borders and heading bars included. Use `c` and `Y` when you want the source.
+
+Copied text goes out two ways at once: an OSC 52 escape sequence, which works over SSH and inside tmux, and a native helper (`pbcopy`, `wl-copy`, `xclip`, `xsel`, `clip.exe`, `termux-clipboard-set`) when one is installed. Nothing to set up. The `clipboard` setting narrows this down or turns it off.
+
+Prefer your terminal's own selection and link clicking? Run `ink --no-mouse` for one session, or set `mouse_capture = false` for good.
+
+## Editing
+
+Press `e` to open the file in `$VISUAL` or `$EDITOR`, at the section you're reading. ink reloads it when the editor exits. On Windows, editors installed as `.cmd` shims (VS Code, Cursor) are found.
+
+## Tabs and the file browser
+
+Open several files and each gets a tab. `Tab` and `Shift+Tab` switch between them.
+
+Run `ink` with no arguments, or point it at a folder, and you get a file picker listing every `.md` file, with filtering and keyboard navigation. Opening a file from the browser exits back to the shell when you quit. `Shift+B` returns to the browser, or set `browser_loop = true` to come back every time.
+
+## Watch mode
+
+```bash
+ink --watch draft.md
+```
+
+The view re-renders within about 100 ms of a save and keeps your scroll position. It works with editors that save by replacing the file (vim, IntelliJ), because ink watches the folder rather than the file handle.
+
+## Presentation mode
+
+```bash
+ink --slides deck.md
+```
+
+Slides split on `---`. Move with the arrow keys or `Space`.
+
+## Outline, stats and diff
+
+```bash
+ink outline README.md # heading structure
+ink stats README.md # word count, reading time, element counts
+ink diff old.md new.md # diff two markdown files
+```
+
+## How ink compares
+
+| | ink | glow | mdcat | frogmouth |
+|---|---|---|---|---|
+| Interactive reader | Yes | Yes | No | Yes |
+| Tabs | Yes | No | No | No |
+| Search in a document | Yes | No | No | No |
+| Table of contents | Yes | No | No | Yes |
+| Images, graphics protocols | Yes | No | Yes | No |
+| Images, half-block fallback | Yes | No | No | No |
+| Mermaid diagrams | Yes | No | No | No |
+| Math and emoji | Yes | No | No | No |
+| Admonitions | Yes | No | No | No |
+| Wikilinks | Yes | No | No | No |
+| File browser | Yes | Yes | No | Yes |
+| Watch mode | Yes | No | No | No |
+| Presentation mode | Yes | No | No | No |
+| Pager mode | Yes | Yes | No | No |
+| Completions and man page | Yes | Yes | Yes | No |
+| Built-in themes | 9 | 2 | 0 | 0 |
+| Single binary | Yes | Yes | Yes | No |
diff --git a/docs/index.html b/docs/index.html
index 4193899..e7812f3 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -2,407 +2,1066 @@
-
- ink — terminal markdown reader
-
-
+
+ ink: a terminal markdown reader
+
+
+
+
-
-
-
+
+
-
-
-
+
-
-
+
+
+
-
-
-
-
-
-
-
ink
-
A terminal markdown reader that actually looks good.
ink renders code, tables, images, diagrams and math in a fast reader with search, tabs and a table of contents. It pages like bat when you pipe it. One binary, no dependencies.
-
-
What it does
-
-
-
Syntax highlighting
-
Language-aware code block highlighting for every major language.
-
-
-
Inline images
-
Real pixels via Kitty / iTerm2 / Sixel where supported, Unicode half-blocks everywhere else.
-
-
-
Mermaid diagrams
-
Flowcharts, state, class and ER diagrams laid out as boxes and arrows, plus sequence, pie, Gantt and mindmaps.
-
-
-
9 themes
-
Dark, Light, Dracula, Catppuccin, Nord, Tokyo Night, Gruvbox, Solarized, and Terminal, which follows your terminal's own palette. Or make your own.
-
-
-
File browser
-
Run ink . to browse and open markdown files in any directory.
+
+
+
+
+
+
+
+
+ curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh
+
+
Open several files at once and switch between them with Tab.
-
-
-
Search
-
Full-text search with highlighted matches; cycle results with n/N.
-
-
-
Table of contents
-
Sidebar showing every heading. Press o to move through it, filter, fold, and jump.
-
-
-
Select & copy
-
v/V or a mouse drag selects text, y copies it. c copies a code block's raw source, Y the current section.
+
+
+
ink showcase.md
+
+
-
-
Open links by keyboard
-
Press f to label links, each listed with its text and URL, then a letter to open or follow them. Or just click one.
+
+
+
+
+
+
1
binary, nothing else to install
+
9
themes, plus any you write
+
9
prebuilt targets, Raspberry Pi included
+
0
network calls unless you ask
+
+
+
+
+
+
+
Diagrams and math
+
Boxes, arrows and equations, drawn in text.
+
Mermaid flowcharts, state, class and ER diagrams come out as real boxes and routed arrows, sized to your window. Gantt charts get a time axis, mindmaps a tree.
+
LaTeX turns into Unicode you can read: \sqrt{b^2-4ac} is √(b² - 4ac). No browser, no plugins, no external tools.
-
-
Math & emoji
-
Renders $math$ as Unicode text (Greek, fractions, roots, matrices) and resolves :emoji: shortcodes.
+
+
mermaid flowchart
+
-
-
Admonitions
-
GitHub-style NOTE, TIP, WARNING, IMPORTANT, and CAUTION blocks.
+
+
+
+
+
+
+
Built for long documents
+
Find your place, keep your place.
+
A table of contents follows you as you scroll. Search highlights as you type. Every link on screen gets a letter, so you never reach for the mouse.
+
+
toShow the contents, then filter, fold and jump
+
/nSearch and step through matches
+
fOpen or follow any link by its letter
+
cYCopy a code block or a whole section as markdown
+
eEdit in $EDITOR at the section you're reading
+
-
-
Wikilinks
-
[[page]] and [[page|text]] syntax for Obsidian vaults and wikis.
+
+
table of contents
+
-
-
Presentation mode
-
Turn any markdown file into slides with --slides.
+
+
+
+
+
+
+
Themes
+
Your colors, or nine of ours.
+
Press T and every theme previews live. The new terminal theme borrows your terminal's own palette, so the same setting fits light and dark setups.
+
Writing your own takes one TOML file. Colors can be hex, palette slots like ansi:blue, or default.
-
-
Works as a pager
-
ink --plain pages long docs through $PAGER, like bat, and writes clean text when piped.
+
+
+
theme picker
+
+
+
+
+
+
+
+
+ --theme terminal, light scheme
+
+
+
+
+
+
+ same setting, dark scheme
+
+
-
-
Safe with untrusted files
-
Strips terminal escape sequences and never phones home for remote images by default.
+
+
+
+
+
+
+
Pager mode
+
A pager when you pipe it.
+
ink --plain pages long files like bat and prints clean text into pipes, so it drops into fzf previews, git diffs and scripts.
+
Pull out just the lines you need with --line-range. Code blocks cut in half stay highlighted.
-
-
Fast on big documents
-
Virtualized rendering and zero idle CPU. 5,000-line files scroll without lag.
+
+
zsh
+
# preview markdown in fzf
+$ fzf --preview 'ink --plain --color=always {}'
+
+# readable markdown in git diffs
+$ git config --global diff.markdown.textconv "ink --plain"
+
+# just lines 40 to 80 of the source
+$ ink --line-range 40:80 README.md
+
+# read a README straight from the web
+$ ink https://raw.githubusercontent.com/borghei/ink/main/README.md
-
-
Single binary
-
Built in Rust. No runtime dependencies. Fast startup.
+
+
+
+
+
+
And the rest
+
The details you'd expect, and some you wouldn't.
+
+
Inline images
Real pixels on Kitty, iTerm2, WezTerm, Ghostty and Sixel. Half-blocks everywhere else. SVG too.
+
Select and copy
Keyboard or mouse selection that knows where a code block ends. Works over SSH and tmux.
+
Admonitions
GitHub [!NOTE] blocks with icons, custom titles and Obsidian callouts.
+
Tabs and a file browser
Open several files at once, or run ink . and pick from a filterable list.
+
Watch mode
Re-renders within 100 ms of a save and keeps your scroll position.
+
Slides
ink --slides deck.md splits on ---. Arrow keys to move.
+
Frontmatter and wikilinks
YAML and TOML hidden or shown as a box. [[page]] links for Obsidian vaults.
+
Your keys
Vim-flavored by default, an emacs preset, and per-action overrides with chords.
+
Safe by default
Escape sequences are stripped and remote images stay off, so an untrusted file can't phone home.
+
+
+
+
jk scroll
+
Space page
+
/ search
+
t contents
+
f links
+
T themes
+
? every key
+
q quit
+
+
+
+
+
+
+
Compared
+
How ink stacks up.
+
+
+
Feature comparison of ink, glow, mdcat and frogmouth
+
+
+
+
diff --git a/docs/install.md b/docs/install.md
new file mode 100644
index 0000000..c85fc77
--- /dev/null
+++ b/docs/install.md
@@ -0,0 +1,144 @@
+# Installing ink
+
+ink is a single binary with no runtime dependencies. Pick whichever route you already use.
+
+- [Install script (macOS, Linux)](#install-script-macos-linux)
+- [Install script (Windows)](#install-script-windows)
+- [Homebrew](#homebrew)
+- [Cargo](#cargo)
+- [Scoop](#scoop)
+- [Conda and Pixi](#conda-and-pixi)
+- [mise](#mise)
+- [.deb and .rpm packages](#deb-and-rpm-packages)
+- [Prebuilt binaries](#prebuilt-binaries)
+- [From source](#from-source)
+- [After installing](#after-installing)
+
+## Install script (macOS, Linux)
+
+```bash
+curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh
+```
+
+The script picks the right binary for your OS, CPU and libc. Alpine, Raspberry Pi and systems with an older glibc get the static musl build. It checks the download against `SHA256SUMS` and installs to `/usr/local/bin`, using `sudo` only when it has to.
+
+Two environment variables change what it does:
+
+| Variable | Effect |
+|---|---|
+| `INK_VERSION` | Install a specific release, e.g. `v0.11.1`. Default: latest. |
+| `INK_INSTALL_DIR` | Install somewhere else, e.g. `$HOME/.local/bin`. |
+
+```bash
+curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | INK_VERSION=v0.11.1 INK_INSTALL_DIR="$HOME/.local/bin" sh
+```
+
+## Install script (Windows)
+
+```powershell
+irm https://raw.githubusercontent.com/borghei/ink/main/install.ps1 | iex
+```
+
+This installs `ink.exe` (x64 or ARM64) to `%LOCALAPPDATA%\Programs\ink` and adds it to your user `PATH`. Set `$env:INK_VERSION = "v0.11.1"` first to pin a version.
+
+## Homebrew
+
+macOS and Linux:
+
+```bash
+brew tap borghei/tap
+brew trust borghei/tap # recent Homebrew wants third-party taps trusted
+brew install ink
+```
+
+## Cargo
+
+```bash
+cargo install ink-md # build from source
+cargo binstall ink-md # or download the prebuilt binary (needs cargo-binstall)
+```
+
+The crate is called `ink-md`. The binary it installs is `ink`.
+
+## Scoop
+
+```powershell
+scoop bucket add borghei https://github.com/borghei/scoop-bucket
+scoop install ink
+```
+
+## Conda and Pixi
+
+The [conda-forge package](https://anaconda.org/conda-forge/ink-md) is maintained by the community.
+
+```bash
+conda install -c conda-forge ink-md
+pixi global install ink-md
+```
+
+## mise
+
+```bash
+mise use -g cargo:ink-md # through crates.io
+mise use -g ubi:borghei/ink # straight from GitHub releases
+```
+
+## .deb and .rpm packages
+
+Download the package from the [releases page](https://github.com/borghei/ink/releases), then:
+
+```bash
+sudo apt install ./ink-md_*_amd64.deb # Debian, Ubuntu
+sudo dnf install ./ink-md-*.x86_64.rpm # Fedora, openSUSE
+```
+
+The packages install the man page and shell completions too.
+
+## Prebuilt binaries
+
+Every release on the [releases page](https://github.com/borghei/ink/releases) has these:
+
+| Platform | Asset |
+|---|---|
+| Linux x86_64, arm64 (glibc 2.35+: Ubuntu 22.04, Debian 12 and newer) | `ink-linux-amd64`, `ink-linux-arm64` |
+| Linux x86_64, arm64, armv7, static (any distro: Alpine, Debian 11, Ubuntu 20.04, RHEL 8, NixOS, containers, Raspberry Pi) | `ink-linux-amd64-musl`, `ink-linux-arm64-musl`, `ink-linux-armv7-musl` |
+| macOS Intel, Apple Silicon | `ink-macos-amd64`, `ink-macos-arm64` |
+| Windows x64, ARM64 | `ink-windows-amd64.exe`, `ink-windows-arm64.exe` |
+
+On Linux, the glibc builds need glibc 2.35 or newer. Anything older, or musl-based, should use the static builds. The install script makes that choice for you.
+
+The Windows builds link the C runtime statically, so you don't need the Visual C++ redistributable.
+
+Each binary also ships as an archive (`ink---.tar.gz`, or `.zip` on Windows) with the man page and bash, zsh and fish completions inside.
+
+### Verifying a download
+
+`SHA256SUMS` is published with every release. Each asset also carries a signed build provenance attestation, which the GitHub CLI can check:
+
+```bash
+gh attestation verify ink-linux-amd64 --repo borghei/ink
+```
+
+The static musl builds and the Windows ARM64 binary started with v0.9.0. Older releases only have the glibc, macOS and Windows x64 builds.
+
+## From source
+
+You need a recent stable Rust toolchain.
+
+```bash
+git clone https://github.com/borghei/ink.git
+cd ink
+cargo build --release
+./target/release/ink --version
+```
+
+## After installing
+
+```bash
+ink --version
+ink config init # write a commented starter config
+ink completions zsh > ~/.zfunc/_ink # bash, zsh, fish, powershell, elvish
+ink man > /usr/local/share/man/man1/ink.1 # man page
+```
+
+Next: [Features](features.md) or [Configuration](configuration.md).
diff --git a/docs/llms-full.txt b/docs/llms-full.txt
index f0c2e0b..846cea0 100644
--- a/docs/llms-full.txt
+++ b/docs/llms-full.txt
@@ -164,6 +164,6 @@ preset = "emacs" # default | vim | emacs
- Website: https://borghei.github.io/ink/
- Author: Amin Borghei
- Crates.io: https://crates.io/crates/ink-md (install with `cargo install ink-md`, Rust 1.90+)
-- Install script (macOS/Linux): `curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh` (picks the glibc or static musl build; pin with INK_VERSION=v0.8.0, target dir INK_INSTALL_DIR)
+- Install script (macOS/Linux): `curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh` (picks the glibc or static musl build; pin with INK_VERSION=v0.11.1, target dir INK_INSTALL_DIR)
- Install script (Windows): `irm https://raw.githubusercontent.com/borghei/ink/main/install.ps1 | iex` (x64/ARM64, installs to %LOCALAPPDATA%\Programs\ink)
- Prebuilt binaries: Linux amd64/arm64 (glibc 2.35+), static musl Linux amd64/arm64/armv7 (Alpine, older glibc, Raspberry Pi), macOS amd64/arm64, Windows amd64/arm64; .deb/.rpm and tar.gz/zip archives with man page and completions
diff --git a/docs/llms.txt b/docs/llms.txt
index 3c5d864..2d57c7b 100644
--- a/docs/llms.txt
+++ b/docs/llms.txt
@@ -39,7 +39,7 @@ ink is a command-line tool that renders markdown files in the terminal with rich
curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh # macOS / Linux (picks glibc or static musl build)
irm https://raw.githubusercontent.com/borghei/ink/main/install.ps1 | iex # Windows PowerShell (x64 / ARM64)
cargo install ink-md # from source (Rust 1.90+)
-INK_VERSION=v0.11.0 sh install.sh # pin a version
+INK_VERSION=v0.11.1 sh install.sh # pin a version
Prebuilt: Linux amd64/arm64 (glibc 2.35+), static musl Linux amd64/arm64/armv7 (any distro), macOS amd64/arm64, Windows amd64/arm64; .deb/.rpm and tar.gz/zip archives include the man page and completions. Verify with SHA256SUMS or `gh attestation verify --repo borghei/ink`.
@@ -58,6 +58,16 @@ ink diff a.md b.md # compare two files (Myers diff)
ink completions zsh # shell completions
ink man # man page
+## Docs
+
+- Install: https://github.com/borghei/ink/blob/main/docs/install.md
+- Features: https://github.com/borghei/ink/blob/main/docs/features.md
+- Themes and color: https://github.com/borghei/ink/blob/main/docs/themes.md
+- Configuration and keybindings: https://github.com/borghei/ink/blob/main/docs/configuration.md
+- Command line: https://github.com/borghei/ink/blob/main/docs/cli.md
+- Troubleshooting: https://github.com/borghei/ink/blob/main/docs/troubleshooting.md
+- Full feature dump for LLMs: https://borghei.github.io/ink/llms-full.txt
+
## Links
- Source: https://github.com/borghei/ink
diff --git a/docs/themes.md b/docs/themes.md
new file mode 100644
index 0000000..0c2716e
--- /dev/null
+++ b/docs/themes.md
@@ -0,0 +1,145 @@
+# Themes and color
+
+- [Built-in themes](#built-in-themes)
+- [The terminal theme](#the-terminal-theme)
+- [Automatic light or dark](#automatic-light-or-dark)
+- [Color depth and NO_COLOR](#color-depth-and-no_color)
+- [ASCII mode](#ascii-mode)
+- [Custom themes](#custom-themes)
+
+## Built-in themes
+
+| Theme | Notes |
+|---|---|
+| `dark` | Default on dark terminals |
+| `light` | Default on light terminals |
+| `dracula` | |
+| `catppuccin` | |
+| `nord` | |
+| `tokyo-night` | |
+| `gruvbox` | |
+| `solarized` | |
+| `terminal` | Uses your terminal's own colors. See below. |
+
+Press `T` in the reader to open the theme picker. Themes preview live as you move, and the one you pick is saved to your config.
+
+```bash
+ink --theme nord README.md # one session
+ink --list-themes # built-ins plus your custom themes
+```
+
+## The terminal theme
+
+`terminal` doesn't bring colors of its own. It draws with the 16 colors of your terminal's palette and its default foreground, sets no background, and highlights code with the same palette, like `bat --theme=ansi`.
+
+So ink matches whatever scheme your terminal runs and looks right on light and dark backgrounds without switching themes. If you change your terminal scheme, ink follows.
+
+```toml
+theme = "terminal"
+```
+
+One catch: muted text (borders, link URLs, comments) uses "bright black". A few schemes, Solarized Dark among them, set bright black to the background color, which hides that text. Pick another theme there, or copy `terminal` into a [custom theme](#custom-themes) and change those keys.
+
+## Automatic light or dark
+
+With no theme set, ink asks the terminal for its background color through an OSC 11 query. Nearly every modern terminal answers, and tmux passes it through. ink picks `light` or `dark` to match. When the terminal doesn't answer it tries `COLORFGBG`, then falls back to `dark`.
+
+An explicit `--theme` or `theme =` in the config always wins and skips the query.
+
+`ink doctor` shows which theme was picked and why.
+
+## Color depth and NO_COLOR
+
+ink matches what your terminal can show:
+
+| Terminal | Colors |
+|---|---|
+| Advertises truecolor (`COLORTERM`, Windows Terminal, VS Code, Ghostty, WezTerm, iTerm2) | 24-bit |
+| `*-256color` | The 256-color palette |
+| Linux console and other 16-color terminals (`TERM=linux`, `xterm`, `vt100`, `screen`) | The 16 ANSI colors, from your own palette |
+
+With `--color=never` or `NO_COLOR` set, the reader draws without any color. Headings, links, search hits and selections use bold, underline and reverse video instead.
+
+Plain output has its own rules. See [Color in plain output](cli.md#color-in-plain-output).
+
+## ASCII mode
+
+The Linux console, non-UTF-8 locales, legacy console fonts and screen readers turn box-drawing characters into junk. `--ascii`, or `ascii = true` under `[behavior]`, draws every border, bullet, task box, quote bar, rule and status-bar marker in 7-bit ASCII (`+--+`, `|`, `*`, `[x]`, `#`). It also turns off smart quotes and emoji shortcodes, so an ASCII document prints as pure ASCII.
+
+It switches on by itself for `TERM=linux` and non-UTF-8 locales. `ascii = false` keeps Unicode regardless.
+
+## Custom themes
+
+Put a `.toml` file in the `themes/` folder next to your config file and use it by name. `ink config path` shows where the config lives. The theme folder is beside it, e.g. `~/.config/ink/themes/mytheme.toml`.
+
+```bash
+ink --theme mytheme README.md
+```
+
+### Color values
+
+Every color is one of:
+
+| Value | Meaning |
+|---|---|
+| `"#7aa2f7"` | A fixed 24-bit color, downgraded on terminals with fewer colors |
+| `"ansi:blue"`, `"ansi:bright-black"` | One of the terminal's 16 palette colors. Names: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, each with a `bright-` form. |
+| `"ansi:0"` to `"ansi:15"` | The same palette colors by number |
+| `"default"` | The terminal's own foreground or background |
+
+`code_theme` picks the syntax-highlighting theme for code blocks. Use `"ansi"` for the terminal palette, or any [syntect default theme](https://docs.rs/syntect/latest/syntect/highlighting/struct.ThemeSet.html#method.load_defaults) such as `"base16-ocean.dark"`, `"InspiredGitHub"` or `"Solarized (light)"`.
+
+### Template
+
+Every key below is required, except `bg`, `selection_bg` and `selection_fg`. Leave `bg` out to keep the terminal background.
+
+```toml
+name = "mytheme"
+code_theme = "base16-ocean.dark"
+
+[colors]
+bg = "#1a1b26"
+fg = "#c0caf5"
+heading1 = "#7aa2f7"
+heading2 = "#7dcfff"
+heading3 = "#bb9af7"
+heading4 = "#9ece6a"
+heading5 = "#e0af68"
+heading6 = "#f7768e"
+bold = "#e6e8f0"
+italic = "#c0caf5"
+strikethrough = "#565f89"
+code_fg = "#a9b1d6"
+code_bg = "#24283b"
+code_block_bg = "#24283b"
+link = "#7aa2f7"
+link_url = "#565f89"
+blockquote_bar = "#565f89"
+blockquote_text = "#a9b1d6"
+list_bullet = "#7aa2f7"
+list_number = "#7aa2f7"
+table_border = "#3b4261"
+table_header = "#7dcfff"
+hr = "#3b4261"
+task_done = "#9ece6a"
+task_pending = "#565f89"
+search_match = "#e0af68"
+search_current = "#ff9e64"
+selection_bg = "#33467c"
+selection_fg = "#c0caf5"
+status_bar_bg = "#16161e"
+status_bar_fg = "#a9b1d6"
+toc_active = "#7aa2f7"
+toc_inactive = "#565f89"
+admonition_note = "#7aa2f7"
+admonition_warning = "#e0af68"
+admonition_tip = "#9ece6a"
+admonition_important = "#bb9af7"
+admonition_caution = "#f7768e"
+```
+
+`search_match` and `search_current` color the text of matches, so they need good contrast against your background. Without `selection_bg`, selections fall back to `search_match`.
+
+The built-in themes in [`src/theme/builtin.rs`](../src/theme/builtin.rs) are good starting points. `terminal()` there shows a theme made only of palette colors.
+
+A theme file that fails to load prints a warning and falls back to `dark`.
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
new file mode 100644
index 0000000..7320ffa
--- /dev/null
+++ b/docs/troubleshooting.md
@@ -0,0 +1,84 @@
+# Troubleshooting
+
+- [Start with ink doctor](#start-with-ink-doctor)
+- [Images](#images)
+- [Colors look wrong](#colors-look-wrong)
+- [Boxes and symbols show as junk](#boxes-and-symbols-show-as-junk)
+- [Copying doesn't reach the clipboard](#copying-doesnt-reach-the-clipboard)
+- [Image paths on Windows](#image-paths-on-windows)
+- [Security model](#security-model)
+- [Reporting a bug](#reporting-a-bug)
+
+## Start with ink doctor
+
+```bash
+ink doctor
+ink doctor --save ink-doctor.txt
+```
+
+Run it in the terminal that misbehaves. It reports:
+
+- your platform and terminal
+- the color depth and theme ink picked, and the signal that decided each
+- the clipboard helper and OSC 52 wrapping it would use
+- mouse capture
+- config problems
+- what the graphics negotiation chose
+- decoder self-tests
+
+It leaves out anything that identifies you: no hostnames, user names, IPs or session IDs, and your home folder shows as `~`. It's safe to paste into an issue.
+
+## Images
+
+Terminal graphics support varies a lot. If an image is blank, garbled or missing:
+
+1. **Try the renderer that works everywhere:** `ink --image-protocol halfblocks file.md`. If the image shows up as coarse colored blocks, decoding is fine and the problem is your terminal's pixel protocol.
+2. **Try a specific protocol:** `--image-protocol iterm2` (iTerm2, WezTerm, VS Code, Warp) or `--image-protocol sixel`. Some terminals advertise protocols they only half support. Auto-detection already works around the known cases, like iTerm2 claiming Kitty support, but new terminal versions bring new quirks.
+3. **Check remote images:** `http` and `https` images only load with `--remote-images`.
+4. **Report it:** open an [image rendering issue](https://github.com/borghei/ink/issues/new?template=image-rendering.yml) with the `ink doctor` output attached. It usually pins the problem down right away.
+
+## Colors look wrong
+
+- **Wrong light or dark theme:** your terminal may not answer the background query. Set the theme yourself with `--theme` or `theme =` in the config. `ink doctor` shows what was detected.
+- **Washed-out or odd colors:** your terminal may not advertise truecolor, so ink uses the 256- or 16-color palette. Set `COLORTERM=truecolor` if your terminal supports it, or use the `terminal` theme, which only uses your palette.
+- **No color at all:** check for `NO_COLOR` in your environment, or `--color=never`.
+- **Escape codes in a pipe:** that's `--color=always`. Leave it at `auto` for files and scripts.
+
+More in [Themes and color](themes.md).
+
+## Boxes and symbols show as junk
+
+The Linux console, non-UTF-8 locales and legacy fonts can't draw box characters. Use `--ascii`, or set `ascii = true` under `[behavior]`. It switches on by itself for `TERM=linux` and non-UTF-8 locales.
+
+## Copying doesn't reach the clipboard
+
+ink sends copies through OSC 52 and a native helper at once.
+
+- **Over SSH or in tmux:** OSC 52 has to be allowed. In tmux, add `set -s set-clipboard on` to `.tmux.conf`. Some terminals ask before letting a program write the clipboard.
+- **Locally on Linux:** install `wl-copy` (Wayland) or `xclip` or `xsel` (X11).
+- **Nothing at all:** check that `clipboard` in your config isn't `off`.
+
+`ink doctor` shows which route ink would use.
+
+## Image paths on Windows
+
+Markdown treats `\` as an escape character, so `C:\pics\.cache\x.png` loses its separators in any CommonMark renderer. Write image paths with forward slashes, `C:/pics/.cache/x.png`. They work everywhere, Windows included.
+
+## Security model
+
+ink treats every document as untrusted.
+
+- Control bytes and escape sequences are stripped before anything reaches the terminal.
+- Links only open with `http`, `https` or `mailto`.
+- Remote images are off unless you pass `--remote-images`. Private, loopback and cloud-metadata addresses stay blocked even then.
+- Local images, absolute paths included, are only ever shown as pixels. The bytes must decode as an image and are never printed as text, so a hostile document can't use an image tag to put a file's contents on screen.
+
+Found a security problem? Please don't open a public issue. Reach [@borghei](https://github.com/borghei) privately first.
+
+## Reporting a bug
+
+Open an [issue](https://github.com/borghei/ink/issues/new/choose) with:
+
+- the `ink doctor` output
+- the smallest markdown that shows the problem
+- what you expected and what you got (a screenshot helps)
diff --git a/install.ps1 b/install.ps1
index dd70ac8..4c4c3de 100644
--- a/install.ps1
+++ b/install.ps1
@@ -4,7 +4,7 @@
# irm https://raw.githubusercontent.com/borghei/ink/main/install.ps1 | iex
#
# Environment:
-# $env:INK_VERSION = "v0.11.0" install a specific release (default: latest)
+# $env:INK_VERSION = "v0.11.1" install a specific release (default: latest)
# $env:INK_INSTALL_DIR = "C:\tools" install somewhere else
# (default: %LOCALAPPDATA%\Programs\ink)
#
diff --git a/install.sh b/install.sh
index 80f34ee..26bfed6 100755
--- a/install.sh
+++ b/install.sh
@@ -5,7 +5,7 @@
# curl -fsSL https://raw.githubusercontent.com/borghei/ink/main/install.sh | sh
#
# Environment:
-# INK_VERSION=v0.11.0 install a specific release (default: latest)
+# INK_VERSION=v0.11.1 install a specific release (default: latest)
# INK_INSTALL_DIR="$HOME/.local/bin" install somewhere else (default: /usr/local/bin)
#
# Options:
diff --git a/src/config.rs b/src/config.rs
index 2f10da0..59a657f 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -4,7 +4,6 @@ use std::ffi::OsStr;
use std::path::{Path, PathBuf};
#[derive(Debug, Deserialize)]
-#[allow(dead_code)]
pub struct Config {
pub theme: Option,
pub width: Option,
@@ -16,7 +15,6 @@ pub struct Config {
}
#[derive(Debug, Deserialize)]
-#[allow(dead_code)]
pub struct BehaviorConfig {
/// When true, closing a file via q/Esc returns to the browser instead of exiting.
pub browser_loop: Option,
@@ -32,7 +30,6 @@ pub struct BehaviorConfig {
}
#[derive(Debug, Deserialize)]
-#[allow(dead_code)]
pub struct KeybindingsConfig {
/// Built-in preset name: "default" | "vim" | "emacs".
pub preset: Option,
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 4f35212..f6be41a 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -38,7 +38,6 @@ impl StyledLine {
self.spans.push(span);
}
- #[allow(dead_code)]
pub fn plain(text: &str) -> Self {
Self {
spans: vec![StyledSpan {
@@ -52,7 +51,6 @@ impl StyledLine {
Self { spans: Vec::new() }
}
- #[allow(dead_code)]
pub fn width(&self) -> usize {
self.spans.iter().map(|s| s.text.width()).sum()
}
diff --git a/src/layout/table.rs b/src/layout/table.rs
index 0e6beb5..e2a3345 100644
--- a/src/layout/table.rs
+++ b/src/layout/table.rs
@@ -558,11 +558,9 @@ fn collect_cell_text<'a>(node: &'a AstNode<'a>) -> String {
crate::glyphs::current().ascii,
)),
NodeValue::Text(t) => buf.push_str(t),
- NodeValue::Code(c) => {
- buf.push('`');
- buf.push_str(&c.literal);
- buf.push('`');
- }
+ // Cells are plain text (bold and italic lose their markers too), so
+ // inline code shows its content, not the markdown backticks.
+ NodeValue::Code(c) => buf.push_str(&c.literal),
NodeValue::SoftBreak => buf.push(' '),
// A hard break makes the cell multi-line (`wrap_text` splits on it).
NodeValue::LineBreak => buf.push('\n'),
@@ -602,6 +600,12 @@ mod tests {
extract_table_data(table).1
}
+ #[test]
+ fn inline_code_in_a_cell_drops_its_backticks() {
+ let cells = body_cells("| a | b |\n|---|---|\n| `GET /sync` | x `y` z |\n");
+ assert_eq!(cells[0], vec!["GET /sync".to_string(), "x y z".to_string()]);
+ }
+
#[test]
fn breaks_at_a_cell_edge_or_doubled_add_no_empty_lines() {
let head = "| a | b |\n|---|---|\n";
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index a06aaa4..97c2749 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -17,14 +17,12 @@ pub fn parse(source: &str) -> ParsedDocument {
}
/// Parsed markdown document with extracted metadata.
-#[allow(dead_code)]
pub struct ParsedDocument {
pub source: String,
pub headings: Vec,
}
#[derive(Debug, Clone)]
-#[allow(dead_code)]
pub struct Heading {
pub level: u8,
pub text: String,
diff --git a/src/theme/mod.rs b/src/theme/mod.rs
index de6f3c6..4a365f8 100644
--- a/src/theme/mod.rs
+++ b/src/theme/mod.rs
@@ -46,7 +46,6 @@ pub fn available_themes() -> Vec {
}
#[derive(Debug, Clone, Deserialize)]
-#[allow(dead_code)]
pub struct Theme {
pub name: String,
pub colors: ThemeColors,
@@ -65,7 +64,6 @@ pub struct ThemeColors {
pub heading5: String,
pub heading6: String,
pub bold: String,
- #[allow(dead_code)]
pub italic: String,
pub strikethrough: String,
pub code_fg: String,
diff --git a/src/toc.rs b/src/toc.rs
index c7d2e9e..56236ed 100644
--- a/src/toc.rs
+++ b/src/toc.rs
@@ -87,7 +87,6 @@ pub fn filter_matches(text: &str, query: &str) -> bool {
}
impl TocState {
- #[allow(dead_code)]
pub fn new(headings: &[Heading], line_mapping: &[(usize, usize)]) -> Self {
let entries = headings
.iter()