This is the fourth part in the series on Reading Mail in the Terminal.
For displaying email (neo)mutt uses the built-in pager (unless you configure an external pager through the pager setting) which is actually quite good, because it allows you to quickly access the attachments directly, or on the spot reply to the email.
There is a status line for the pager which can be reconfigured to display only the relevant information, like the sender, subject, and number of attachments. I’ll demonstrate two variants: one with and one without the use of nerd fonts:
# ~/.config/neomutt/neomuttrc # sender, subject, right align, number of attachments, if any set pager_format = " %n - %s %> %?X?@ %X?& " # and again, this time with nerd fonts set pager_format = " %n %s %> %?X? %X ?"
It’s probably time to address the elephant in the room: yes, I’m not using the normal colour scheme, but solarized light. Setting that up in the console is easy enough, but where do the colors for the attachment information and the header come from?
Painting the Mail Red
(neo)mutt can be assigned colours to various parts of the UI by means of the color directive:
# ~/.config/neomutt/neomuttrc color message color0 color15 color hdrdefault color14 color7 color signature color0 color15 color attachment color2 color15
Colours are set by object, foreground, background. In this example an attachment will have the foreground colour 2 (green) and background colour 15 (white). Only the header uses the darker variant of white (color 7).
But this is not where it stops. You can use regular expressions to colour parts of messages differently. For example you could highlight URLs and email addresses 1:
# ~/.config/neomutt/neomuttrc color body color4 color15 "<?(http|ftp)s?://[^ \n\t\r\)]+>?" color body color4 color15 "<?[a-zA-Z+\-_0-9\.]+@[a-zA-Z0-9_\.\-]+\.[a-zA-Z0-9]+>?"
Furthermore you can decide to give certain headers a different colour, again using regular expressions:
# ~/.config/neomutt/neomuttrc color header color0 color7 "^(Subject:)" color header color0 color7 "^(From:)"
And of course you can apply that newly found power for colouring everywhere else in (neo)mutt, too: in the index, in the attachments, etc.
Handling HTML Email
The pager only knows how to display plain text emails. Unfortunately, thanks to bad decisions on the end of software developers, many people send HTML-only emails. To still be able to read these more or less conveniently, I convert them to markdown.
In order to tell (neo)mutt how to convert HTML emails to markdown, you have to set up a so-called mailcap file. In this file you tell (neo)mutt how to open certain file types:
# ~/.config/neomutt/mailcap text/html; ~/bin/html2text.py; copiousoutput; text/plain; cat; copiousoutput;
copiousoutput tells (neo)mutt to copy the output of that program directly into the pager.
And here is the python script (that‘s really just a wrapper around html2text):
#!/usr/bin/env python3 # ~/bin/html2text.py import sys import html2text raw = sys.stdin.buffer.read() parser = html2text.HTML2Text() parser.unicode_snob = True parser.re_unescape = True parser.skip_internal_links = True parser.protect_links = True parser.re_space = True parser.use_automatic_links = False parser.inline_links = False html = None for encoding in ['utf_8', 'iso8859_15', 'utf16', 'cp1252', 'cp858', 'utf_32']: try: html = str(raw, encoding) except Exception as exc: continue else: break if html is None: print('Failed to decode binary blob: could not find any sane encoding') else: print(parser.handle(html))
Together with some reflowing options to make it easier to read emails with too long lines, it results in these configuration options:
# ~/.config/neomutt/neomuttrc set pager_stop = yes set wrap = 85 set reflow_text = yes set pager_format = " %n %s %> %?X? %X ?" set mailcap_path = "~/.config/neomutt/mailcap" auto_view text/html alternative_order text/plain text/markdown text/enriched text/html
pager_stop is quite useful unless you like to scroll to the next email when you pass the last line of the one you are currently reading.
You still have to set auto_view to
text/html if you want the
html2text.py script to kick into action.
The regex for email addresses is not working great yet, but as things go, it’s good enough for now.