Send Stylish MIME in Emacs
15 Jan 2015Last Updated: 18 Jan 2015
This is the first technical article in this blog, however the main purpose is not to analyse the problem and provide the solutions, but to tell a story of an ordinary person trying to pursuit his vision in a multi-languages environment (Emacs and HTML) that he only knows the basis. Hope you find it is interesting to read and for those who care the solution more than problem-solving approach, please see the last section.
Table of Contents
The Problem
The first time I thought I need an fancy Email is when I sent an quick model update to my colleague; I have a table like this
Conditioning Variable | Dependent Variable | Probability |
---|---|---|
k >= 50 | t >= 50 | 0.154 |
k >= 50 | t >= 100 | 0.111 |
k >= 50 | t >= 200 | 0.078 |
It was written in org-mode in which I can do the formatting quickly and nicely. But once copied over to Outlook, it looks messy, and the columns does not lineup.
| Conditioning Variable | Dependent Variable | Probability |
|---------------------------------------------------–—|
| k >= 50 | t >= 50 | 0.154 |
| k >= 50 | t >= 100 | 0.111 |
| k >= 50 | t >= 200 | 0.078 |
The correct way is to insert a table in Outlook. First, I have to export the table to a CSV file, than open it in Excel, and finally copy it over to Outlook which will recognised it as a table.
HTML Attachment Solution
I guess the purpose of that email is to give my colleague few numbers, in a way that he can compare and gain a feeling of the model. So the format is really necessary, but the workaround is really tedious.
I have another colleague who is an HTML expert and produced an company CSS style-sheet. He was kindly customised it to match the org-export class, i.e. org-ur, org-table, org-list.
So what I did was to export to org-file as a HTML and attached it in the email so that my colleague can simply click and open it in a browser, which will gives him a nicely formatted table. But people have hundreds email per day and seems to dislike attachments.
Paradise of MIME
I noticed Bernt Hansen pointed out in his famous Org Mode - Organize Your Life In Plain Text! that he use org-mime to sent HTML Email. MIME, standards for Multi-Purpose Internet Mail Extensions, is an extension to plain email and enable user to exchange rich data includes image, table, video etc.
The org-mime can parse the org file into an HTML code, in a way that the email server like Office365 or Gmail can recognise and render it with pre-defined styles.
The default style looks awful: the font, the colour, size, basically nothing is right. Recently I sent about 3-5 emails using this style, I doubt the reader will spent less time in reading and comprehend it, therefore the message is not conveyed.
But the workflow is fascinating: I call org-mime-subtree
function, then I just type few email address, no need to switch to system or Outlook, everything is done in Emacs and at the exact point where the main content is generated.
So I was thinking, what if the email is look as good as the attachment? What if I can apply the style to the email, that would be looks fanatic!
I did my research, the org-mime indeed provides feature to let user to change the HTML style, two example are showed on worg. The package first generate the HTML file, and than search-and-replace a certain chunk, for example,
1
2
3
<p>
this is a paragraph
</p>
will becomes something like this, depends on users specification,
1
2
3
<p style="blue">
this is a paragraph
</p>
The search-replace mechanics works fine, for a small email. It takes a pair value (element, style), where element can be paragraph, table, list and style can be colour, font, size etc. The problem is this pair is not quick match the standard CSS file,
1
2
3
4
5
6
7
body {
font-family: "Helvetica Neue", "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif !important;
font-size: 14px;
}
body #content {
padding-top: 70px;
}
One can processing the CSS file, and feed the package a long list of pairs. But this approach seems not safe. I quickly skim the CSS file and found something I couldn't understand, for example the body #content block above.
Hack org-mime
I think the most problem-free approach is to follow org-export-html and ensure the generated Email has same style as exported HTML and org-MIME package will eventually implement this, but I don't to wait and decide to hack.
The script is formatted in a nice way, and looks like a textbook C program: it first declares variable and functions, with concise documentation so one can visualise the structure after reading 5-10 minutes. But the implementation is way beyond my knowldge on Emacs-Lisp language. I almost looked up each function that be used, take this snippet for example,
1
2
3
4
5
6
(with-temp-buffer
(insert html)
(goto-char (point-min))
(run-hooks 'org-mime-html-hook)
(buffer-string))
I have no idea of what does it means. You know the feeling when you try to learn an foreign language but took the wrong book that way above your level, and you find there no single word you could understand, and you was like What The Hell? That was my feeling.
The strategy I came up was to build up my Emacs-Lisp vocabulary: try to understand the functions/processes and translate it into a plain English, for example,
- with-temp-buffer
- create a temporary buffer
- insert
- insert the string, in this case, called html, at point.
- goto-char
- move the cursor, which is called point in emacs, to somewhere
- point-min
- means the begining of a buffer/file
- run-hook
- run functions that links to org-mime-html-hooks
- buffer-string
- return a buffer as a string
Now that I understand each words, I need to comprehense it and combine than together to understand the mean of this snippet. I tried to write in a plain English and the first attempt is like this
create temporary buffer, insert the generated html file, than move the cursor to the very start, and than apply other functions that links to org-mime-htmize
I continue this word-sentence-paragraph process and I understand few functions. But it can goes on and on, and the more I learn about Emacs lisp, the future away I digress from my original goal: apply the style sheet to HTML email. I guess this is a common dilemma in working with multi-languages. Usually I follow my interests but this time I choose to focus on achieving the goal.
MIME Solution
It turned out it is a right decision. The concept of "inline-CSS" is mentioned int the script, I googled and found out the solution within 10 minutes. I realised that what I need to do is add a block in beginning of the HTML mail!! BINGO!
1
2
3
4
5
6
<head>
<style>
...
</style>
</head>
;; html email content starts here
Emacs Configuration
Here's the settings:
1
2
3
4
5
6
7
8
9
10
11
12
(require 'org-mime)
(add-hook 'org-mime-html-hook
(lambda ()
(insert
"
<head>
<style>
;; content of the .css file
</style>
</head>"
))
t)