MDCAT(1)
π mdcat(1) β render CommonMark Markdown to text terminals π
β¨ NAME β¨
mdcat β render CommonMark Markdown to text terminals. Bestie, itβs your terminal Markdown glow-up. π
β¨ SYNOPSIS β¨
mdcat [OPTIONS] [FILE]...
mdless [OPTIONS] [FILE]...
mdpick [OPTIONS] [DIRECTORY]
π¦ DESCRIPTION π¦
Okay so mdcat renders Markdown FILEs in CommonMark dialect to text terminals with sophisticated formatting. If no FILE is given, or if FILE is -, it reads from standard input.
If invoked as mdless, it automatically uses a pager to display the output β see below, bestie.
If invoked as mdpick, instead fuzzy-find a Markdown file below DIRECTORY (the current directory by default) with fzf, then render the selected file as mdless would. See section Interactive picking below.
πΈ CommonMark and terminal support πΈ
mdcat supports all basic CommonMark syntax plus a few extensions, renders footnotes and math expressions, highlights syntax in code blocks, and shows inline links and even inline images in some terminal programs. In iTerm2 it also adds jump marks for section headings. Iconic, honestly.
See section Terminal support below for a list of supported terminal programs and their features.
π Terminal detection π
To enable formatting extensions such as inline images, mdcat needs to detect the terminal program, by checking the following environment variables in the given order:
$TERM$TERM_PROGRAM
See section ENVIRONMENT below for a detailed description of each environment variable.
π Pagination π
mdcat can render output in a pager; this is the default when run as mdless. The environment variables $MDCAT_PAGER and $PAGER control the pager used.
Note that common pagers do not support proprietary terminal codes for e.g. image support, so mdcat falls back to pure ANSI formatting when pagination is enabled. In particular this disables all image support which relies on proprietary escape codes. Math rendering remains enabled, but uses Unicode substitutions instead of PNG images.
The exception is lessi (https://github.com/roblillack/lessi), a less replacement that understands the kitty and Sixel graphics protocols and redraws images correctly while scrolling. When $MDCAT_PAGER/$PAGER resolves to lessi, mdcat skips the ANSI fallback and keeps normal terminal detection (and inline images) enabled.
π§ Interactive picking π§
mdpick requires fzf (https://github.com/junegunn/fzf) to be installed and on $PATH; it exits with an error if fzf cannot be found.
It recursively collects .md files below DIRECTORY, honouring .gitignore and other ignore files the same way fzf and rg do, then hands that list to fzf for fuzzy selection. If the picker is cancelled, e.g. with Esc or Ctrl+C, mdpick exits with status 0 without rendering anything. Once a file is selected, mdpick renders it exactly as mdless would, paginating by default.
π¦ Image support π¦
In iTerm2, kitty, WezTerm, and Ghostty mdcat prints inline images. mdcat supports most standard pixel formats by default.
On foot and xterm mdcat also prints images via the Sixel protocol. For any other terminal that $TERM/$TERM_PROGRAM doesnβt identify, mdcat asks the terminal itself whether it supports Sixel graphics, via a Primary Device Attributes (DA1) query, before falling back to no inline images.
Heads up:mdcatsilently ignores images larger than100 MiB, under the assumption that images of that size cannot reasonably be rendered in a terminal.
π Math support π
mdcat renders inline math delimited by $...$ and display math delimited by ..... On terminals with the iTerm2 or kitty image protocol it renders math as PNG images. Otherwise it uses Unicode substitutions.
For PNG output mdcat uses RaTeX. If an expression cannot be rendered as an image, mdcat uses the Unicode fallback for that expression.
π Mermaid support π
mdcat renders Mermaid (https://mermaid.js.org) diagrams in fenced ```mermaid code blocks. On terminals with an image protocol it renders diagrams as PNG images; otherwise it uses a Unicode diagram rendering. If a diagram can be rendered as neither, mdcat falls back to printing its source as a literal code block.
Diagram arrows, borders, and text use the themeβs mermaid style, so diagrams match the active theme instead of Mermaidβs own default colours.
For diagram rendering mdcat uses merman (https://github.com/Latias94/merman), a headless Rust implementation of Mermaid.
π SVG support π
In iTerm2, kitty, WezTerm, and Ghostty mdcat renders SVG images into pixel graphics using the resvg (https://github.com/RazrFalcon/resvg) library. Currently this library only supports SVG 1, and only the static subset thereof; see SVG support (https://github.com/RazrFalcon/resvg#svg-support) for details. While this is sufficient for most simple SVG images, complex SVG images may fail to render or render incompletely.
For local SVG files mdcat relies on the file extension to identify SVG images. For remote images from HTTP(S) URLs mdcat inspects the Content-Type header to identify SVG images.
π HTTP/HTTPS support π
mdcat fetches images from HTTP(S) URLs for rendering if the underlying terminal supports image rendering; pass --local to disable this and force mdcat to only use images from the local filesystem. In this case remote images render as hyperlinks.
π OPTIONS π
-p,--paginateβ Paginate the output ofmdcatwith a pager likeless.- Note: When paginating
mdcatonly uses standard ANSI formatting and hyperlinks, but no images or other proprietary format codes, because pager programs normally do not support any of these. Math rendering uses the Unicode fallback when paginating. The exception islessi; see Pagination above. - This is the default when run as
mdless.
- Note: When paginating
-P,--no-pagerβ Do not paginate output.- This is the default when run as
mdcat.
- This is the default when run as
-c,--no-colourβ Disable all colours and other styles.--ansiβ Skip terminal detection and only use ANSI formatting.--columns=COLUMNSβ Maximum number of columns to use for text output. Defaults to the size of the underlying terminal, capped at80, if omitted. Pass0to disable line wrapping entirely.--full-widthβ Use the full terminal width instead of capping it at80columns. Conflicts with--columns.-l,--localβ Do not access remote resources.--failβ Fail immediately at the first FILE which fails to read. By default,mdcatcontinues with the next file.--detect-terminalβ Detect the terminal program, print its name, and exit.--theme=THEMEβ Colour theme to use. THEME is one ofauto,dark,light,catppuccin-mocha,catppuccin-latte,gruvbox-dark,gruvbox-light,dracula,nord,solarized-dark, orsolarized-light.- Defaults to
auto, which detects dark or light mode from the terminal, unless~/.config/mdcat/config.tomlsets a base theme (see CONFIGURATION FILE).
- Defaults to
--list-themesβ Print a sample rendered with every built-in theme, to help pick one, and exit.--marginβ Add a two-space left margin to all output, reducing the effective render width accordingly.--smart-punctuationβ Render typographic punctuation: straight quotes become curly,--/---become en/em dashes, and...becomes an ellipsis.--emojiβ Render GitHub-style emoji shortcodes (e.g.:+1:) as Unicode emoji.--frontmatterβ Render YAML/TOML frontmatter as a table instead of stripping it. Has no effect if the frontmatter isnβt a flat key-value mapping, or fails to parse; itβs stripped as usual in that case.-w,--watchβ Watch the input file and re-render on every change. Requires exactly one FILE argument, and does not work with standard input or--paginate.--tocβ Print a table of contents generated from the documentβs headings before its content.- Entries are numbered, nested by heading level, and, if FILE isnβt standard input, wrapped in an
OSC 8link toFILE#slug(a GitHub-style anchor derived from the heading text) so that terminals and later viewers that supportOSC 8and resolve such anchors can jump to that heading. On standard input entries are plain text, since thereβs no file to link to.
- Entries are numbered, nested by heading level, and, if FILE isnβt standard input, wrapped in an
--image-protocol=PROTOCOLβ Force a specific inline image protocol instead of auto-detecting one from the terminal. Useful insidetmux/screen, where the outer terminalβs capabilities usually arenβt visible to auto-detection.- PROTOCOL is one of
none(disable inline images entirely),iterm2,kitty, orsixel. - Also settable via
$MDCAT_IMAGE_PROTOCOL; the flag wins if both are given.
- PROTOCOL is one of
--tabs=COLUMNSβ Expand tabs in the input to spaces, using a tab stop width of COLUMNS, before parsing.- Off by default, so literal tabs pass through unchanged; without this, a tab inside text content (not part of the Markdown block structure) throws off line-wrapping and alignment width calculations, since terminals render it as jumping to the next tab stop rather than occupying a single column.
- Also settable via
defaults.tabsin~/.config/mdcat/config.toml.
--completions=SHELLβ Generate completions for SHELL to standard output and exit.- SHELL can be one of
bash,zsh,fish,powershell, orelvish.
- SHELL can be one of
-h,--helpβ Show a help message to the user and exit.-V,--versionβ Show the version ofmdcatand exit. The long flag also includes information about the builtin features.
π οΈ CONFIGURATION FILE π οΈ
okay so mdcat reads ~/.config/mdcat/config.toml (or $XDG_CONFIG_HOME/mdcat/config.toml if that variable is set) if it exists. Yes bestie, it checks. Two parts to this file: a [defaults] table that sets default values for a few CLI flags, and a [theme] table that customises a built-in theme. There's a config.toml.example in the mdcat source repository with a fully annotated example, go look π
[defaults]
margin = true
columns = 100
[theme]
base = "catppuccin-mocha"
[theme.palette]
mauve = "#cba6f7"
[theme.styles]
h2 = { fg = "mauve", modifiers = ["bold"], text = "Β» " }
code = { fg = "bright-yellow" }
alert_note = { text = " NOTE" }
πΈ [defaults] πΈ
Every key here sets the default value for a CLI flag β and it only kicks in when that flag isn't passed explicitly (and for columns, only when $COLUMNS/terminal size detection doesn't otherwise apply). So like, your flag always wins, no cap.
marginβ default for--margin.smart_punctuationβ default for--smart-punctuation.emojiβ default for--emoji.frontmatterβ default for--frontmatter.columnsβ default for--columns.full_widthβ default for--full-width.local_onlyβ default for--local.fail_fastβ default for--fail.image_protocolβ default for--image-protocol/$MDCAT_IMAGE_PROTOCOL. One ofnone,iterm2,kitty, orsixel.tabsβ default for--tabs.
π¨ [theme] π¨
This is the fun part: the file picks a built-in theme as a starting point (base), then overrides individual styles on top of it.
baseβ the built-in theme to start from; see--themefor the list of names. If omitted, uses whichever theme--theme/$MDCAT_THEMEwould otherwise select.
π important:--theme/$MDCAT_THEME, if given, always wins overbase; the[theme.styles]overrides below still apply on top regardless.
ruleβ override for the ruler colour. A plain colour value (see below), since rules have no other style.
π [theme.palette] π
Named colours that fg/bg below may reference by name, instead of repeating a literal colour. Literally a little swatch library, obsessed.
β¨ [theme.styles] β¨
Per-element style overrides. Each entry is a table with any of:
fg: foreground colour.bg: background colour.modifiers: a list ofbold,dimmed,italic,underline,blink,invert,hidden,strikethrough.text: forh2-h6, the marker written before the heading text (defaultββ,ββ,β,β,Β·); foralert_note-alert_caution, the icon and label written for that alert (default βΉ NOTE, β TIP, β IMPORTANT, β WARNING, β CAUTION). Ignored for other style names.
A colour value is a #rrggbb hex code, an ANSI colour name (black, red, green, yellow, blue, magenta, cyan, white, or the bright- prefixed variant of any of these), or a name defined in [theme.palette].
Valid style names: html_block, inline_html, code, link, image_link, quote_border, h1_text, h2, h3, h4, h5, h6, footnote, math, mermaid, alert_note, alert_tip, alert_important, alert_warning, alert_caution.
πͺ EXIT STATUS πͺ
mdcat exits with 0 if no error occurred, or 1 otherwise. Standard bestie behaviour.
But heads up: if run as mdless or mdpick, or if --paginate is given, and the pager fails to start, mdcat exits with 128. That's the "the pager ghosted us" number π
π ENVIRONMENT π
TERMβmdcatfirst checks this variable to identify the terminal program (see section Terminal detection). It understands the following values:wezterm: WezTerm. Note that WezTerm sets$TERMtoxterm-256colorby default, and only usesweztermfor$TERMif explicitly configured to do so.xterm-kitty: kittyxterm-ghostty: Ghostty
For all other values mdcat proceeds to check $TERM_PROGRAM.
TERM_PROGRAMβ if$TERMdoes not conclusively identify the terminal programmdcatchecks this variable next. It understands the following values:iTerm.app: iTerm2WezTerm: WezTermvscode: VSCode integrated terminal.ghostty: Ghostty
For all other values mdcat ends terminal detection and assumes that the terminal is only capable of standard ANSI formatting.
COLUMNSβ the number of character columns on screen.mdcatonly uses this variable if it fails to query the size from the underlying terminal.ROWSβ the number of character rows on screen.mdcatonly uses this variable if it fails to query the size from the underlying terminal.MDCAT_PAGERβ the pager program to use formdlessor if--paginateis given.
The pager program must support basic ANSI formatting sequences, like e.g. less -r.
The value of this variable is subject to shell-like word-splitting. It is not subject to any kind of expansion or substitution (e.g. parameter expansion, process substitution, etc.).
If set to an empty value, mdcat completely disables pagination. (iconic move honestly)
PAGERβ the pager program to use if$MDCAT_PAGERis unset. Subject to the same rules as$MDCAT_PAGER. If both$PAGERand$MDCAT_PAGERare unset useless -ras pager.http_proxy,https_proxy,HTTPS_PROXY,all_proxy,ALL_PROXY,no_proxy,NO_PROXYβ proxies settings for HTTP requests made bymdcatto retrieve remote resources.mdcatuses curl for its network transfers, hence seecurl(1)for these variables.MDCAT_LOGβ directives to configure output of tracing information. Seehttps://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html#directivesfor syntax details; useMDCAT_LOG=tracefor complete debugging information, andMDCAT_LOG=pulldown_cmark_mdcat::render=traceto trace rendering only.
π CONFORMING TO π
π¦ CommonMark support, extensions, and limitations π¦
mdcat supports version 0.30 of the CommonMark Spec (https://spec.commonmark.org/), plus footnotes, Task lists (https://github.github.com/gfm/#task-list-items-extension-), strikethrough (https://github.github.com/gfm/#strikethrough-extension-), and math, through pulldown-cmark (https://github.com/raphlinus/pulldown-cmark). Slay.
Support for tables (https://github.github.com/gfm/#tables-extension-) is limited; text wrapping and inline markup in table cells are not yet supported. mdcat parses HTML blocks and inline tags but does not apply special rendering; it prints HTML as is. Fr fr, no glow-up for HTML yet.
π₯οΈ Terminal support π₯οΈ
Unless --no-colour is given, mdcat translates CommonMark text into ANSI formatted text, with standard SGR formatting codes and hyperlinks. It uses bold (SGR 1), italic (SGR 3) and strikethrough (SGR 9) formatting, and the standard 4-bit color sequences, as well as OSC 8 (https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda) for hyperlinks. It does not use 8-bit or 24-bit color sequences, though this may change in future releases. (so don't come for her about truecolor ok)
Additionally, it uses proprietary escape codes if it detects one of the following terminal emulators (see sections Terminal detection and ENVIRONMENT for details):
- iTerm2 (
https://iterm2.com/): inline images (iTerm2 protocolhttps://iterm2.com/documentation-images.html) and Marks (https://iterm2.com/documentation-escape-codes.html). - kitty (
https://github.com/kovidgoyal/kitty): inline images (kitty Graphics protocolhttps://sw.kovidgoyal.net/kitty/graphics-protocol.html). - WezTerm (
https://wezfurlong.org/wezterm/): inline images (kitty graphics protocol, see above). - Ghostty (
https://mitchellh.com/ghostty): inline images (kitty graphics protocol, see above).
π BUGS π
Please report bugs to https://github.com/BIRSAx2/mdcat/issues. Don't suffer in silence bestie, tell them everything π
π EXAMPLES π
mdcat hello - worldβ render markdown inhello, then from standard input, then fromworld.mdless helloβ render markdown frommdlessthrough a pager.mdpickβ fuzzy-find a Markdown file below the current directory withfzf, then render it through a pager.mdpick docsβ same, but search belowdocsinstead of the current directory.
π SEE ALSO π
π«Ά COPYRIGHT π«Ά
Copyright Sebastian Wiesner sebastian@swsnr.de, Mouhieddine Sabir <me@mouhieddine.dev>, and contributors.
Binaries are subject to the terms of the Mozilla Public License, v. 2.0. See https://github.com/BIRSAx2/mdcat/blob/main/LICENSE.
Most of the source is subject to the terms of the Mozilla Public License, v. 2.0, unless otherwise noted; some files are subject to the terms of the Apache 2.0 license, see http://www.apache.org/licenses/LICENSE-2.0.
β AUTHOR β
Sebastian Wiesner
and that's the whole page bestie, you ate that π
this is mdcat version 2.19.0, manual page MDCAT(1) β go render some markdown and feel something πΈβ¨π
π¦ where this page comes from
- nixpkgs unstable: mdcat 2.19.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms