{"id":602,"date":"2019-10-19T22:28:42","date_gmt":"2019-10-19T22:28:42","guid":{"rendered":"http:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/?p=602"},"modified":"2019-10-19T22:28:42","modified_gmt":"2019-10-19T22:28:42","slug":"emacs-and-org-mode-for-sending-mailshots","status":"publish","type":"post","link":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/?p=602","title":{"rendered":"Emacs and org-mode for sending mailshots"},"content":{"rendered":"<p>\nI use Emacs for reading and sending email, so I&#8217;ve been using emacs-lisp to send mailshots for years (but in a rather clunky way).\n<\/p>\n<p>\nThe big shortcoming is that it is not hugely convenient getting the data (e.g., student names, email addresses, marks, comments) into emacs-lisp data structures, or conveniently writing the emails.\n<\/p>\n<p>\n<code>org-mode<\/code> makes it all easier.\n<\/p>\n<p>\nI present an example here: how to send mails giving feedback on performance in a test.\n<\/p>\n<p><!--more--><\/p>\n<p>\nFirst we put the data in an org-mode table, giving it a name. <code>org-mode<\/code> tables are very ergonomic to enter data directly in. You could also cut and paste a CSV and convert it (insert, highlight, type &#8220;C-|&#8221;), but it&#8217;s likely better to use org-mode to enter the data in the first place.\n<\/p>\n<pre class=\"example\">\r\n#+NAME: assignment1\r\n|  1 | Sleepy |    5 |\r\n|  2 | Sneezy |   15 |\r\n|  3 | Doc    |   10 |\r\n<\/pre>\n<p>\nThen we write the email (exactly the content of a message-mode Emacs mail-buffer, before sending), but with &#8220;%s&#8221; marking locations where we insert variable information. This is input as an org-mode EXAMPLE, with a name.\n<\/p>\n<pre class=\"example\">\r\n#+NAME: boilerplate\r\n#+BEGIN_EXAMPLE \r\nTo: %s\r\nSubject: Assignment 1\r\nBCC: brendan.halpin@ul.ie\r\n--text follows this line--\r\nDear %s,\r\n\r\nHomework assignment 1\r\n\r\nYour mark on assignment 1 was %s\/20. In other words, you %s.\r\n\r\nRegards,\r\n\r\nSnow White\r\n-- \r\n#+END_EXAMPLE\r\n<\/pre>\n<p>\nThe boilerplate defines fields to fill as:\n<\/p>\n<ul class=\"org-ul\">\n<li>full email address<\/li>\n<li>name<\/li>\n<li>mark, and<\/li>\n<li>a verbal summary of the performance.<\/li>\n<\/ul>\n<p>\nNote that the boilerplate defines the complete contents of a mail message buffer (apart from the signature, which can be inserted afterwards, as below).\n<\/p>\n<p>\nThe next block explicitly refers to the student data and the boilerplate (&#8220;<code>:var boilerplate=boilerplate students=assignment1<\/code>&#8220;), and then defines a function, <code>make-message<\/code>, which works on each row of the student data table and\n<\/p>\n<ul>\n<li>creates a mail buffer, deleting its contents in order to replace them<br \/>\nwith our own<\/li>\n<li>inserts the boilerplate, populating the fields appropriately<\/li>\n<li>including creating the verbal summary based on the mark<\/li>\n<li>renames the buffer uniquely (and marks it unmodified, to make it easy<br \/>\nto delete if necessary)<\/li>\n<\/ul>\n<p>\nThe block then applies the defun to each element of the student-data list (using <code>mapcar<\/code>, which is like the <code>apply<\/code> family in R).\n<\/p>\n<div class=\"org-src-container\">\n<pre class=\"src src-emacs-lisp\">\r\n#+BEGIN_SRC emacs-lisp :results none :var boilerplate=boilerplate students=assignment1\r\n(<span style=\"color: #00ffff\">defun<\/span> <span style=\"color: #87cefa\">make-message<\/span> (student)\r\n  (compose-mail)\r\n  (delete-region (point-min) (point-max))\r\n  (insert (format boilerplate\r\n                  (format <span style=\"color: #ffa07a\">\"dwarf%s@forest.mine\"<\/span> (nth 0 student))\r\n                  (nth 1 student)\r\n                  (nth 2 student)\r\n                  (<span style=\"color: #00ffff\">cond<\/span> ((&lt; (nth 2 student) 10)\r\n                         <span style=\"color: #ffa07a\">\"fluffed it\"<\/span>)\r\n                        ((= (nth 2 student) 10)\r\n                         <span style=\"color: #ffa07a\">\"did okay\"<\/span>)\r\n                        ((&gt; (nth 2 student) 10)\r\n                         <span style=\"color: #ffa07a\">\"aced it\"<\/span>))))\r\n  (insert <span style=\"color: #ffa07a\">\"Snow White Housekeeping and Judgementals<\/span>\r\n<span style=\"color: #ffa07a\">The Dwarves' House<\/span>\r\n<span style=\"color: #ffa07a\">Enchanted Forest\"<\/span>)\r\n  (rename-uniquely)\r\n  (set-buffer-modified-p nil)) <span style=\"color: #ff7f24\">;; <\/span><span style=\"color: #ff7f24\">make easy to delete for debug<\/span>\r\n\r\n\r\n(mapcar (<span style=\"color: #00ffff\">lambda<\/span> (student) (make-message student))\r\n students)\r\n#+END_SRC\r\n<\/pre>\n<\/div>\n<p>\nThe end result is multiple mail buffers, one per student, each containing a mail message ready to send. You can then visit the buffers, and verify before sending. Insert the command <code>message-send-and-exit<\/code> at the end of the defun if you are truly reckless!\n<\/p>\n<p>\nAn example mail buffer:\n<\/p>\n<pre class=\"example\">\r\nTo: dwarf3@forest.mine\r\nSubject: Assignment 1\r\nBCC: brendan.halpin@ul.ie\r\n--text follows this line--\r\nDear Doc,\r\n\r\nHomework assignment 1\r\n\r\nYour mark on assignment 1 was 10\/20. In other words, you did okay.\r\n\r\nRegards,\r\n\r\nSnow White\r\n-- \r\nSnow White Housekeeping and Judgementals\r\nThe Dwarves' House\r\nEnchanted Forest\r\n<\/pre>\n<p>\nThis is nice because we can enter the data conveniently in an <code>org-mode<\/code> table, and similarly enter the email boilerplate in an <code>org-mode<\/code> <code>EXAMPLE<\/code> block without worrying too much about escaping quotation marks etc. However, what is really nice is that we can\n<\/p>\n<ol class=\"org-ol\">\n<li>do arbitrary things to the text using emacs-lisp (&#8220;you fluffed it&#8221;)<\/li>\n<li>process the data tables using, e.g,. <a href=\"https:\/\/twitter.com\/BrendanTHalpin\/status\/1185495264196550656?s=20\">R<\/a><\/li>\n<\/ol>\n<p>\nIt is also possible to generate arbitrarily complex HTML and multipart emails, but that&#8217;s a topic for another day.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I use Emacs for reading and sending email, so I&#8217;ve been using emacs-lisp to send mailshots for years (but in a rather clunky way). The big shortcoming is that it is not hugely convenient getting the data (e.g., student names, email addresses, marks, comments) into emacs-lisp data structures, or conveniently writing the emails. org-mode makes &hellip; <a href=\"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/?p=602\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Emacs and org-mode for sending mailshots<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/602"}],"collection":[{"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=602"}],"version-history":[{"count":11,"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/602\/revisions"}],"predecessor-version":[{"id":614,"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/602\/revisions\/614"}],"wp:attachment":[{"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=602"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=602"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/teaching.sociology.ul.ie\/bhalpin\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=602"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}