Teaching Emacs how to open mail attachments
Mailcap
On Windows Emacs is a bit handicapped, because it does not know how to operate on many file types. One solution is to write your own .mailcap
file, which Emacs will happily parse.
# plays AIFF files audio/x-aiff; sfplay %s # plays AIFC files audio/x-aifc; sfplay %s # open PDFs application/pdf; xpdf %s
Unfortunately, this only allows you to specify external programs, not actions within Emacs, and it is yet another configuration file to handle.
A different solution is to directly configure Emacs' MIME environment. You need to configure two variables
mailcap-mime-data
is a tree of associations from MIME types and subtypes, to viewers and flags. This is where.mailcap
information lands.mailcap-mime-extensions
is an association list between file name extensions and MIME types. Unfortunately, Emacs does not always respect the MIME types in attachments and sometimes exclusively guesses the type from the name.
My solution
Because of the clash between functions that focus on the file name extension and others that look for MIME types, it has taken me an inordinate amount of time to find the right way to configure these options. I believe I have found a simple path to keep everything configured from within Emacs, but I am still looking for an option that teaches Emacs to delegate to Windows' routines for opening all documents.
The code below contains some example configurations that I use in my system, and which are likely to grow. Note that I use doc-view. See my other posts to learn how to configure DocView for Emacs on Windows. Even with those changes, we still need to tweak doc-view to make it work with MIME buffers, because they have no filename and doc-view has no way to identify the document type—hence the use of the odf-doc-view-mode
wrapper.
(use-package mailcap :custom (mailcap-user-mime-data nil) :config (defvar jjgr-mailcap-additional-application-types '((("vnd.oasis.opendocument.presentation") odf-doc-view-mode ".odp") (("vnd.oasis.opendocument.presentation") "start \"%s\"" ".odp") (("vnd.openxmlformats-officedocument.wordprocessingml.document") "\"C:/Program Files (x86)/Microsoft Office/root/Office16/WINWORD.EXE\" \"%s\"" ".docx") (("vnd.openxmlformats-officedocument.presentationml.presentation") "\"C:/Program Files (x86)/Microsoft Office/root/Office16/POWERPNT.EXE\" \"%s\"" ".pptx") (("vnd.ms-excel" "vnd.openxmlformats-officedocument.spreadsheetml.sheet") "\"C:/Program Files (x86)/Microsoft Office/root/Office16/EXCEL.EXE\" \"%s\"" ".xlsx"))) (defun odf-doc-view-mode () (require 'doc-view) (let ((doc-view-saved-settings (cons '(doc-view-doc-type . odf) doc-view-saved-settings))) (doc-view-mode) (print doc-view-doc-type))) (defun jjgr-add-simple-mailcap-entry (subtypes viewer &rest extensions) (when subtypes (dolist (subtype subtypes) (let ((regexp (replace-regexp-in-string "\\." "\\\\." subtype)) (type (concat "application/" subtype))) (mailcap-add-mailcap-entry "application" regexp `((viewer . ,viewer) (type . ,type))))) (dolist (extension extensions) (add-to-list 'mailcap-mime-extensions (cons extension (concat "application/" (car subtypes))))))) (dolist (i jjgr-mailcap-additional-application-types) (apply 'jjgr-add-simple-mailcap-entry i)))
Important bonus
On top of this, you will want to make sure that Emacs' MIME parser stores the attachments with the right encoding, free of strange characters, on a temporary location that is compatible with Windows' expectations
(use-package mm-decode :config ;; Clean up file names, removing accents and spaces, so that the operating ;; system does not get confused. (add-to-list 'mm-file-name-rewrite-functions 'xah-asciify-string) (add-to-list 'mm-file-name-rewrite-functions 'mm-file-name-replace-whitespace) )