HTML Terminal Snapshots
April 9, 2016
In preparation for my future posts, I needed to devise a way to export the output of terminal commands to formatted HTML (including colors). While I’m sure some terminal emulators out there already provide such a feature, I wanted my own portable solution that anyone could use.
First attempt
⌘+C, ⌘+V
My research first led me to an OS X only version. The clipboard management of OS X has support for rich text copy and paste, through the RTF format. I could just run a command in the Terminal application, copy and paste the output to TextEdit, and save as an HTML file.
Although this solution worked, it had major caveats:
- It is a tedious process and can’t be automated
- The generated HTML output is not really helpful for this blog:
- All colors and properties defined in generated styles in
<head>
- Automatically generated style names makes it impossible to paste multiple snapshots in a single post
- Not in a
<pre>
tag, spaces are wrapped in styled spans
- All colors and properties defined in generated styles in
- Not really portable!
An answer from the experts
Thankfully after reading some posts on StackOverflow, I discovered a very nifty tool called ansifilter1, which translates ANSI escape codes (we’re gonna see a lot more of these in future posts :)2 to either formats such as HTML, RTF and even LaTeX.
What’s more, ansifilter
generates clean HTML, uses <pre>
and can produce either a standalone HTML file or only the contents of the <pre>
tag. I can now present to you, anytime I want, glorious terminal snapshots:
0 1 2 3 4 5 6 7 8 |
$ cowsay -e '>o' 'Howdy, readers!' | lolcat -F 0.4
_________________
< Howdy, readers! >
-----------------
\ ^__^
\ (>o)\_______
(__)\ )\/\
||----w |
|| ||
|
All I had to do now was to create some useful aliases:
1 2 | alias html="ansifilter -H -f"
alias copyhtml="html | pbcopy"
|
Running any command and piping its output to copyhtml
would now place a nicely colored HTML output in my clipboard, ready to paste anywhere. Piping to html
would output the formated HTML to stdout
enabling you to further pipe into other commands.
The last step to make this process even quicker with Hugo, my blog builder, was to create a template to avoid having to manually wrap my pasted snippet with opening and closing tags for the formatting:
0 1 2 3 4 5 6 7 |
$ pless layouts/shortcodes/term.html
<table class="highlighttable">
<tr>
<td>
<pre>{{ .Inner }}</pre>
</td>
</tr>
</table>
|
(pless
is a custom command that has a less
behavior while highlighting code syntax with pygments
, more on that in later posts!)
Thanks to that template, I now have a really nice work flow for writing my Markdown posts:
- Run the command I want to demo, pipe it to
copyhtml
- Go to my Markdown article, open a
{{< term >}}
tag - Paste
- ???
- Profit!
Clever pipes
In actuality, I had to cheat to produce the above example (sorry). Some programs like ls
or lolcat will detect if their stdout
is connected to a tty or not, stripping all ANSI escape codes in the latter case.
Enter the unbuffer
command from the expect
3 software suite:
unbuffer disables the output buffering that occurs when program output is redirected from non-interactive programs.
The commands I really ran were:
1 2 3 | cowsay -e '>o' 'Howdy, readers!' > tmp
unbuffer lolcat -F 0.4 tmp | copyhtml
rm tmp
|
But, for most cases, command | copyhtml
is enough :)
ansifilter
is available onbrew
if you’re on a Mac [return]- http://www.xkcd.com/541/ [return]
- Also available on
brew
[return]