Simple composition of HTML emails in Emacs using Markdown
Suppose you'd like to compose HTML emails1 in Emacs' message-mode
.2 An HTML email is really just a MIME
message with two parts: a text/plain
part and its text/html
alternative. Creating a
MIME message [by hand] is boring and non-trivial.
Therefore, [Emacs includes a] library called
You can read the gory mml
[…] that parses a language called
MML and generates
MIME messages.mml
details in (emacs-mime)
Composing. For now, though, consider this sample document:
<#multipart type=alternative>
hello, world
<#part type=text/html>
<html>
<head>
<title>HTML version of email</title>
</head>
<body>
<p>hello, world</p>
</body>
</html>
<#/multipart>
OK, this looks doable, but for one big, glaring problem: you have to write, by hand, both the text and HTML versions of the email. Holy redundant redundancy, Batman!
Enter Markdown.
It's a
text-to-HTML conversion tool [that] allows you to write using an
easy-to-read, easy-to-write plain text format[.]
Check it
(emphasis mine):
The overriding design goal for Markdown’s formatting syntax is to make it as readable as possible. The idea is that a Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions. While Markdown’s syntax has been influenced by several existing text-to-HTML filters, the single biggest source of inspiration for Markdown’s syntax is the format of plain text email.
If you're used to composing plain text emails, your existing writing habits are probably pretty close to Markdown, so it shouldn't be too hard to learn. So what we'd like to do is to simply use Markdown syntax for the text part, and then use a Markdown→HTML processor to generate the HTML section for us.
The first thing I did was to quickly hack up a command-line
tool, mimedown, which takes Markdown-formatted text on
stdin, and spits out mml
containing
both the text and HTML versions on stdout.
I used the Python markdown library, which you can download
from SourceForge.
#!/usr/bin/env python
# mimedown - generate multipart text and HTML MIME message from Markdown input.
import markdown
def mimedown(input, output):
text = input.read()
html = markdown.Markdown(text, safe_mode=False).toString()
html = "<htm><head><title></title><body>%s</body></html>" % html
print >> output, '''<#multipart type=alternative>
%s
<#part type=text/html>
%s
<#/multipart>
''' % (text, html)
if __name__ == '__main__':
import sys
mimedown(sys.stdin, sys.stdout)
The next step is to hook this into message-mode
somehow. Here's a mimedown
command which runs the message
body through mimedown
:
(defun mimedown ()
(interactive)
(save-excursion
(message-goto-body)
(shell-command-on-region (point) (point-max) "mimedown" nil t)))
There you have it. You can now compose HTML emails in Emacs with Markdown. Share and Enjoy!
Notes
- Before you get angry, know that generally, I'm against the use of HTML email. ↩
-
Emacs ships with two mail composition modes,
mail-mode
andmessage-mode
. I read mail with Gnus, which usesmessage-mode
by default. Also,message-mode
's support for MIME composition is much, much better than that ofmail-mode
. ↩