Skip to content

Rendering Markdown In Terminal

Brett Terpstra edited this page Mar 22, 2026 · 3 revisions

Rendering Markdown in the Terminal

Apex can render Markdown to ANSI-colored output suitable for TTYs, terminal emulators, and terminal-based file manager previews (e.g. lf, yazi). This page describes the output formats, CLI flags, and configuration options.

Output formats: -t / --to

Use -t or --to to choose the output format. For terminal rendering, use one of:

Format Aliases Description
terminal cli 8/16-color ANSI output (standard and bright colors). Best compatibility with basic terminals.
terminal256 256-color ANSI output (xterm-256 palette). Richer colors when your terminal supports it.

Examples:

# 16-color terminal output (default theme)
apex doc.md -t terminal

# Same as above (cli is an alias for terminal)
apex doc.md -t cli

# 256-color terminal output
apex doc.md -t terminal256

# Pipe from stdin
cat doc.md | apex -t terminal

Output is written to stdout. Redirect or pipe as needed:

apex doc.md -t terminal | less -R
apex doc.md -t terminal256 -o -

Options

--theme NAME

Load a terminal theme from:

  • ~/.config/apex/terminal/themes/NAME.theme (when NAME is given)
  • ~/.config/apex/terminal/themes/default.theme (when no theme is specified and a default file exists)

Themes are YAML files that map element types to colors and optional bold. See Theme file format below.

Examples:

apex doc.md -t terminal --theme brett
apex doc.md -t terminal256 --theme dark

--width N

Hard-wrap terminal (and terminal256) output at N visible columns. ANSI escape sequences are not counted toward the width, so colors and formatting are preserved while lines are wrapped. Useful when:

  • Viewing in a narrow terminal or file manager preview pane
  • Apex cannot detect the pane width (e.g. in lf or yazi preview)

N must be a positive integer. If omitted or set to 0, Apex does not add wrapping; the terminal controls line breaks.

Examples:

apex doc.md -t terminal --width 80
apex doc.md -t terminal256 --width 72

--code-highlight-theme THEME

When using an external syntax highlighter (via --code-highlight), you can control the highlighting theme with --code-highlight-theme. The same theme name is applied consistently to HTML and terminal output:

  • Pygments: maps to style=THEME for both HTML and terminal/terminal256 ANSI output
  • Skylighting: maps to --style THEME for both HTML and ANSI output
  • Shiki: maps to --theme THEME for both HTML and ANSI output

For -t terminal / -t terminal256, Apex uses the highlighter's ANSI output when available, so your code blocks in the terminal use the selected theme's colors.

apex doc.md -t terminal --code-highlight pygments --code-highlight-theme monokai
apex doc.md -t terminal256 --code-highlight shiki --code-highlight-theme github-dark

--list-themes

List available syntax highlighting themes for Pygments, Skylighting, and Shiki. The output is arranged in multiple columns that adapt to the current terminal width (up to four columns on wide screens).

apex --list-themes

Use this together with --code-highlight-theme to discover theme names that look good in your terminal.

-p, --paginate

When using -t terminal, -t cli, or -t terminal256, -p / --paginate sends the rendered terminal output through a pager instead of writing directly to stdout.

Pager selection order:

  • If $APEX_PAGER is set and non-empty, Apex uses its value as the pager
  • Otherwise, if $PAGER is set and non-empty, Apex uses that
  • Otherwise, Apex falls back to less -R

Pagination is ignored when the output format is not a terminal format or when -o/--output is used to write to a file.

apex doc.md -t terminal --paginate
APEX_PAGER="less -RFX" apex doc.md -t terminal256 -p

Inline images (terminal graphics)

When stdout is a TTY and inline images are enabled, Apex can render ![alt](url) images as actual graphics in the terminal instead of text.

Viewer selection (first executable found on PATH, in order):

  1. imgcat (iTerm2-style; -W width)
  2. chafa (-s size)
  3. viu (-w width)
  4. catimg (-w width)

Width: Use --terminal-image-width N to set the maximum width in character cells (default 50). This is separate from --width, which wraps prose.

Remote HTTP(S) images: If curl is on PATH, Apex downloads the image to a temporary file under TMPDIR or /tmp, displays it, then deletes the temp file. Downloads use a 60 second timeout and reject files larger than 10 MiB. If curl is missing or the download fails, Apex falls back to link-style output (see below).

When images are not drawn inline: Apex emits link-style output (styled alt text and the URL in parentheses), matching how normal links look in terminal output—not ![...](...) markdown. That happens when:

  • Output is not a TTY (e.g. piped to a file or another command)
  • --no-terminal-images is set
  • No supported viewer is installed, or the viewer exits with an error
  • A local path does not resolve to a readable file
  • A remote URL cannot be fetched within the limits above

Captions: After an inline image, a caption line may show the file basename, optional image title, and alt text (subject to title_captions_only / --title-captions-only behavior for links).

--no-terminal-images

Disables inline terminal rendering of images. Images always use the link-style fallback.

apex doc.md -t terminal --no-terminal-images

--terminal-image-width N

Sets the maximum width in character cells for the terminal image tools (default 50).

apex doc.md -t terminal256 --terminal-image-width 72

Configuration and metadata

Terminal behavior can be set via document metadata or a config file (e.g. --meta-file), so you don’t have to pass flags every time.

Precedence: CLI flags override metadata/config. For width: CLI --width > metadata/config terminal.width. For terminal inline images: --no-terminal-images forces images to link-style output; --terminal-image-width overrides terminal.image_width when given.

Metadata keys

Use a terminal: mapping in YAML front matter (or flattened keys in your metadata):

Key Example Description
terminal.theme or terminal_theme brett Default terminal theme name for -t terminal / -t terminal256.
terminal.width or terminal_width 80 Default wrap width (positive integer).
terminal.inline_images or terminal_inline_images true Enable (true) or disable (false) inline terminal image rendering when a viewer is available (default: enabled in the API; use metadata to turn off per document).
terminal.image_width or terminal_image_width 50 Default max width in character cells for imgcat / chafa / viu / catimg (see Inline images above).
code-highlight or code_highlight pygments Default external syntax highlighter for code blocks (Pygments, Skylighting, Shiki, or abbreviations).
code-highlight-theme or code_highlight_theme monokai Default syntax highlighting theme for both HTML and terminal output.
paginate / terminal.paginate / terminal_paginate true Enable pagination by default for terminal/cli/terminal256 output.

Example in document front matter:

---
title: My Doc
terminal:
  theme: brett
  width: 80
paginate: true
code-highlight: pygments
code-highlight-theme: monokai
---

Example in a shared config file (e.g. config.yml passed with --meta-file):

terminal:
  theme: dark
  width: 72

If you set --theme or --width on the command line, those values override the metadata/config.

Theme file format

Theme files live under ~/.config/apex/terminal/themes/ and use the .theme extension. They are plain YAML.

Location and naming

  • Path: ~/.config/apex/terminal/themes/<NAME>.theme
  • default.theme is used when no theme name is provided (and no --theme is given).

Element keys

Common top-level keys:

  • h1h6 – Heading levels (each can have color and optional bold: true).
  • link – Link text and optional link.url for the URL style.
  • code_span – Inline code.
  • code_block – Fenced code blocks.
  • blockquote – Blockquote marker and text color (blockquote.character, blockquote.color).
  • table – Table border/style (table.border, optional table.bold).
  • list_marker – Style for bullet and numbered list markers (e.g. *, 1., 2.). When unset, markers use bold bright red.

For any element that has a color field, you can add bold: true to make that element bold in addition to its color.

Example theme (excerpt)

h1:
  color: "bright_white"
  bold: true

h2:
  color: "bright_blue"
  bold: true

list_marker: "b intense_red"

code_span:
  color: "b white on_intense_black"

code_block:
  color: "white on_black"
  bold: true

Color values can use names like red, bright_blue, intense_red, and 256-color forms like 38;5;nnn. The b prefix (or bold: true in structured keys) enables bold. See existing themes in the repo or in ~/.config/apex/terminal/themes/ for more examples.

Typical use cases

  • Interactive reading: apex doc.md -t terminal | less -R
  • File manager preview (lf, yazi, etc.): Use -t terminal or -t terminal256 and --width set to your preview pane width (e.g. --width 80), or set terminal.width in metadata/config.
  • Consistent look: Create a .theme file and reference it with --theme or terminal.theme in metadata so all your terminal renders use the same colors and emphasis.

Replacing mdless and similar tools

If you are used to tools like mdless, you can use Apex as a drop-in replacement and keep all of your preferred colors, width, and pagination settings in one place.

One simple approach is to create a shell alias that always renders with terminal colors, pagination, wrapping, and syntax highlighting:

alias mdless='apex -t terminal256 --paginate --code-highlight pygments --code-highlight-theme monokai --width 60 --theme mdless'

You can then run:

mdless README.md

Most of these options can also be moved into config or metadata so the alias stays short:

terminal:
  theme: brett
  width: 60
paginate: true
code-highlight: pygments
code-highlight-theme: monokai

With this configuration, the alias can be as simple as:

alias mdless='apex -t terminal256'

See also

Quick Links

Clone this wiki locally