Termsnap turns terminal output into vector graphics. It uses an in-memory instance of Alacritty under the hood to be compatible with many terminal control sequences.
See $ termsnap --help
for CLI usage documentation. For example, to run the
ls
command and store the output in an SVG file, run:
$ termsnap -- ls -l > ./out.svg
These examples are generated by ./scripts/examples.sh. Note some of these examples send automated input to an interactive bash session.
$ termsnap -l 9 -c 28 -- cowsay Hello, world
$ termsnap -l 12 -c 60 -- nvim --clean ./scripts/example.py <<EOF
:set number
:syntax enable
:q
EOF
$ (
# `sleep` gives bash time to be ready for the command, if this is omitted
# the appearance of prompts can get messed up.
sleep 0.05
echo -ne "for x in {16..231}; do printf \"\\\e[48;5;\${x}m%03d\\\e[0m \" \$x; done\r"
sleep 0.05
) | termsnap -l 16 -c 72 -- bash --noprofile --rcfile "$PWD/scripts/inputrc"
$ (
sleep 0.05
printf "echo \$-\r"
sleep 0.05
printf "tty\r"
sleep 0.05
) | termsnap -l 12 -c 60 -- bash --noprofile --rcfile "$PWD/scripts/inputrc"
$ termsnap -l 22 -c 80 -- tokei
Install using Cargo:
$ cargo install termsnap
# Run ls
$ termsnap --columns 80 --lines 36 -- ls --color=always -l
# Run an interactive bash session
$ termsnap --interactive --out ./interactive-bash.svg -- bash
Run using Nix flakes:
# Run ls
$ nix run github:tomcur/termsnap -- --columns 80 --lines 36 -- ls --color=always -l
# Run an interactive bash session
$ nix run github:tomcur/termsnap -- --interactive --out ./interactive-bash.svg -- bash
The SVG generated by Termsnap assumes the font used is monospace with a glyph width/height ratio of 0.60 and a font ascent of 0.75. The font is not embedded and the text not converted to paths. If the client rendering the SVG can't find the specified font, the SVG may render incorrectly, especially if the used font's dimensions do not match Termsnap's assumptions. You can use, e.g., Inkscape to convert the text to paths---the downside is the text may lose crispness when rendering at low resolutions. You can also convert the SVG to a raster image.
# Text to path
$ inkscape --export-text-to-path --export-plain-svg --export-filename=./out.svg ./in.svg
# Render to raster image
$ inkscape --export-width=800 --export-filename=./out.png ./in.svg