-
Notifications
You must be signed in to change notification settings - Fork 163
HTML mails
As of version 0.9, alot has rudimentary features to add, edit and remove HTML alternatives to plaintext message contents. This is done using txt2html
and html2txt
commands in envelope mode.
Envelopes store both html and plaintext alternatives until you send a mail. If at that time, a html body text is present, alot will create a text/multipart
message that contains both these texts. Most MUAs on the receiving end will display only the html part.
No HTML part is initially present for envelopes, and if there is one, you can remove it using the (envelope mode) command removehtml
. To change which part alot shows in envelope mode you can use the display
command:
display html
switches to HTML and display plaintext
switches to displaying the envelope's plaintext.
To add a HTML part, use the txt2html
command. It will pipe your plaintext message body through a pre-defined shell script and add the resulting text as HTML part to the envelope.
The defaultshell command to use is read from the config setting envelope_txt2html
, but you can also just give it as a parameter to the txt2html
command directly (see bottom of this page for an example).
The command html2txt
works analogously, but translates the HTML text back into a plaintext alternative and overwrites the current one in the envelope.
You can directly edit the HTML part by passing a parameter to the edit
command:
edit --part=plaintext
.
I write emails in pandoc's Markdown and generate HTML from it like so:
envelope_txt2html = "pandoc -f markdown -t html -s --self-contained"
envelope_html2txt = "pandoc -t markdown -f html"
Pandoc allows to adjust the template HTML to use and I've found this pretty awesome one for myself.
To use it, download the template file and store it as ~.pandoc/templates/email.html5
.
Then adjust alot's txt2html command as follows.
envelope_txt2html = "pandoc -f markdown -t html -s --self-contained --template=email.html5"
I actually keep several templates around and have bindings for txt2html
with different templates.
For example, I use a template called email-official.html5
that includes a fancy signature.
I use and external browser to preview the generated HTML parts before sending emails.
This is not part of mailine alot but uses a hook. My code is below.
import alot
import tempfile
import webbrowser
from alot.helper import string_sanitize
from alot.helper import string_decode
# Helper method to extract the raw html part of a message. Note that it
# only extracts the first text/html part found.
def _get_raw_html(msg):
mail = msg.get_email()
for part in mail.walk():
ctype = part.get_content_type()
if ctype != "text/html":
continue
cd = part.get('Content-Disposition', '')
if cd.startswith('attachment'):
continue
enc = part.get_content_charset() or 'utf-8'
raw = string_decode(part.get_payload(decode=True), enc)
return string_sanitize(raw)
return None
# Opens HTML emails in an external browser.
# Related issue:
# - https://github.com/pazz/alot/issues/1153
def open_in_browser(ui=None):
ui.notify("Opening message in browser...")
cb = ui.current_buffer
htmlstr = None
if isinstance(cb, alot.buffers.EnvelopeBuffer):
htmlstr = cb.envelope.body_html
elif isinstance(cb, alot.buffers.ThreadBuffer):
msg = ui.current_buffer.get_selected_message()
htmlstr = _get_raw_html(msg)
if htmlstr == None:
ui.notify("no html part found")
return
temp = tempfile.NamedTemporaryFile(prefix="alot-",suffix=".html",
delete=False)
temp.write(htmlstr.encode("utf-8"))
temp.flush()
temp.close()
webbrowser.open(temp.name)
envelope_txt2html = "pandoc -f markdown -t html -s --self-contained --template=email.html5"
envelope_html2txt = "pandoc -t markdown -f html"
[bindings]
[[envelope]]
enter = "edit --part=plaintext; txt2html; display html"
', b' = "call hooks.open_in_browser(ui)"
'_' = "txt2html pandoc -f markdown -t html -s --self-contained --template=email-official.html5; display html"