Go to the first, previous, next, last section, table of contents.


Reading MIME Messages

If the variable vm-display-using-mime is non-nil VM will display messages using Multipurpose Internet Mail Extensions (MIME). MIME is a set of extensions to the standard Internet message format that allows reliable transmission of arbitrary data including images, audio and video, as well as ordinary text. A non-nil value for this variable means that VM will recognize MIME encoded messages and display them as specified by the various MIME standards specifications. A nil value means VM will display MIME messages as plain text messages.

At its most basic MIME is a set of transfer encodings used to ensure error free transport, and a set of content types. VM understands the two standard MIME transport encodings, Quoted-Printable and BASE64, and will decode messages that use them as necessary. VM also will try to recognize and decode messages using the UNIX "uuencode" encoding system. While this is not an official MIME transfer encoding and never will be, enough old mailers still use it that it is worthwile to attempt to decode it. VM has Emacs-Lisp based Quoted-Printable and BASE64 encoders and decoders, but you can have VM use external programs to perform these tasks and the process will almost certainly be faster. The variables vm-mime-qp-decoder-program, vm-mime-qp-decoder-switches, vm-mime-qp-encoder-program, vm-mime-qp-encoder-switches, vm-mime-base64-decoder-switches, vm-mime-base64-encoder-switches, vm-mime-base64-decoder-program, vm-mime-base64-encoder-program, tell VM which programs to use and what command line switches to pass to them. There are C programs at VM's distribution sites on the Internet to handle BASE64 and Quoted-Printable. VM does not have a builtin "uuencode" decoder, so vm-mime-uuencode-decoder-program must be set non-nil for VM to decode uuencoded MIME objects.

By default VM will display as many content types as possible within Emacs. Images and audio are also supported if support for images and audio has been compiled in. Types that cannot be displayed internally within Emacs can be converted to a type that can, or be displayed using an external viewer.

The first step in displaying a MIME message is decoding it to determine what object types it contains. The variable vm-auto-decode-mime-messages controls when this happens. A value of t means VM should decode the message as soon as the message body is exposed, or during previewing if vm-mime-decode-for-preview is also set non-nil. A nil value means wait until decoding is explicitly requested. Type D (vm-decode-mime-message) to manually initiate MIME decoding.

After decoding you will see either the decoded MIME objects or button lines that must be activated to attempt display of the MIME object. The variable vm-auto-displayed-mime-content-types specifies the types that are displayed immediately. Its value should be a list of MIME content types that should be displayed immediately after decoding. Other types will be displayed as a button that you must activate to display the object. To activate a button, either click the middle mouse button over it, or move the cursor to the line and press RET. If you are running under a window system, you can use the right mouse button over a MIME button to display a menu of actions you can take on the MIME object. If you prefer using keyboard commands, you can save the MIME object with $ w, print it with $ p, or pipe it to a shell command with $ |. Use $ s to append an encapsulated message or USENET news article to a folder. If you want to display the object with its characters displayed using Emacs' default face, use $ RET. To display the object using an external viewer, type $ e.

Sometimes MIME objects are large and you may not want to save them along with the message that contains them. If so, use $ d (vm-delete-mime-object) while the cursor is on the MIME button. The object will be deleted and replaced with an object that indicates what the old object was and the fact that it is gone. This is not an undoable operation, so use this command with care. If you inadvertently delete an object, the only way to get it back is to quit visiting the current folder without saving and then revisit the folder. This works because the object isn't removed from the disk copy of the folder until you save the folder. By default VM will ask if you're sure about deleting an object before doing the deletion. You can make VM not ask this question by setting vm-mime-confirm-delete to nil.

A value of t for vm-auto-displayed-mime-content-types means that all types should be displayed immediately. A nil value means never display MIME objects immediately; only use buttons. If the value of vm-auto-displayed-mime-content-types is a list, it should be a list of strings, which should all be MIME types or type/subtype pairs. Example:

(setq vm-auto-displayed-mime-content-types '("text" "image/jpeg"))

If a top-level type is listed without a subtype, all subtypes of that type are assumed to be included. The example above specifies that all text types are displayed immediately, but only JPEG images are displayed this way.

The variable vm-auto-displayed-mime-content-type-exceptions should be a list of MIME content types that should not be displayed immediately after decoding. This variable acts as an exception list for vm-auto-displayed-mime-content-types; all types listed there will be auto-displayed except those in the exception list.

The value of vm-auto-displayed-mime-content-type-exceptions should be either nil or a list of strings. The strings should all be types or type/subtype pairs. Example:

(setq vm-auto-displayed-mime-content-type-exceptions '("text/html"))

Again, if a top-level type is listed without a subtype, all subtypes of that type are assumed to be included.

The variable vm-mime-internal-content-types specifies which types should be displayed internally within Emacs. Like vm-auto-displayed-mime-content-types its value should be a list of MIME content types. A value of t means that VM should always display an object internally if possible. VM knows which object types can be displayed internally, so you can specify the types you want without worrying about errors if Emacs can't handle them. A nil value means never display MIME objects internally, which means VM will have to run an external viewer to display all MIME objects.

If the value is a list, it should be a list of strings. Example:

(setq vm-mime-internal-content-types '("text" "image/jpeg"))

If a top-level type is listed without a subtype, all subtypes of that type are assumed to be included. Note that multipart types are always handled internally regardless of the setting of this variable.

The variable vm-mime-internal-content-type-exceptions serves as the exception list for vm-mime-internal-content-types. Its value should be a list of types that should not be displayed internally.

For types that you want displayed externally, set the value of vm-mime-external-content-types-alist to specify external viewers for the types. The value of this variable should be an associative list of MIME content types and the external programs used to display them. If VM cannot display a type internally or a type is not listed in vm-mime-internal-content-types VM will try to launch an external program to display that type.

The alist format is a list of lists, each sublist having the form

(TYPE PROGRAM ARG ARG ... )

or

(TYPE COMMAND-LINE)

TYPE is a string specifying a MIME type or type/subtype pair. For example "text" or "image/jpeg". If a top-level type is listed without a subtype, all subtypes of that type are assumed to be included.

In the first form, PROGRAM is a string naming a program to run to display an object. Any ARGs will be passed to the program as arguments. The octets that compose the object will be written into a temporary file and the name of the file can be inserted into an ARG string by writing `%f' in the ARG string. In earlier versions of VM the filename was always added as the last argument; as of VM 6.49 this is only done if `%f' does not appear in any of the ARG strings.

If the COMMAND-LINE form is used, the program and its arguments are specified as a single string and that string is passed to the shell ("sh -c" typically) for execution. Since the command line will be passed to the shell, you can use shell variables and input/output redirection if needed. As with the PROGRAM/ARGS form, the name of the temporary file that contains the MIME object will be appended to the command line if `%f' does not appear in the command line string.

In either the PROGRAM/ARG or COMMAND-LINE forms, all the program and argument strings will have any %-specifiers in them expanded as described in the documentation for the variable vm-mime-button-format-alist. The only difference is that `%f' refers to the temporary file VM creates to store the object to be displayed, not the filename that the sender may have associated with the attachment.

Example:

(setq vm-mime-external-content-types-alist
      '(
	 ("text/html" 	"netscape")
	 ("image/gif" 	"xv")
	 ("image/jpeg" 	"xv")
	 ("video/mpeg" 	"mpeg_play")
	 ("video" 	"xanim")
       )
)

The first matching list element will be used.

No multipart message will ever be sent to an external viewer.

External viewer processes are normally killed when you select a a new message in the current folder. If you want viewer processes to not be killed, set vm-mime-delete-viewer-processes to a nil value.

Any type that cannot be displayed internally or externally or converted to a type that can be displayed, will be displayed as a button that allows you to save the body to a file.

As with the internal type list, there is an exception list that you can use to specify types that you do not want displayed externally. When VM is considering whether it should automatically launch an external viewer, it will consult the variable vm-mime-external-content-type-exceptions. If the type to be displayed is listed, VM will not launch a viewer. This allows you to setup viewers for types that ordinarily you would not want VM to display or for types that you norally want to convert to some other type using vm-mime-type-converter-alist. You can still display such a type with anexternal viewer by using $ e.

When a MIME object is displayed using an external viewer VM must first write the object to a temporary file. The external viewer thne opens and displays that file. Some viewers will not open a file unless the filename ends with some extention that it recognizes such as `.html' or `.jpg'. You can use the variable vm-mime-attachment-auto-suffix-alist to map MIME types to extensions that your external viewers will recognize. The value of this variable should be a list of type and suffix pairs. The list format is:

((TYPE . SUFFIX) ...)

TYPE is a string specifying a MIME top-level type or a type/subtype pair. If a top-level type is listed without a subtype, all subtypes of that type are matched.

SUFFIX is a string specifying the suffix that shoul be used for the accompanying type.

Example:

(setq vm-mime-attachment-auto-suffix-alist
      '(
        ("image/jpeg"		.	".jpg")
        ("image/gif"		.	".gif")
        ("image/png"		.	".png")
        ("text"			.	".txt")
       )
)

VM will search the list for a matching type. The suffix associated with the first type that matches will be used for the temporary filename.

Types that cannot be displayed internally or externally are checked against an associative list of types that can be converted to other types. If an object can be converted to a type that VM can display, then the conversion is done and the new object is subject to the auto-display rules which determine whether the object is displayed immediately or a button is displayed in its place. The conversion list is stored in the variable vm-mime-type-converter-alist.

The alist format is

( (START-TYPE END-TYPE COMMAND-LINE ) ... )

START-TYPE is a string specifying a MIME type or type/subtype pair. Example `"text"' or `"image/jpeg"'. If a top-level type is listed without a subtype, all subtypes of that type are assumed to be included.

END-TYPE must be an exact type/subtype pair. This is the type to which START-TYPE will be converted.

COMMAND-LINE is a string giving a command line to be passed to the shell. The octets that compose the object will be written to the standard input of the shell command.

Example:

(setq vm-mime-type-converter-alist
       '(
	 ("image/jpeg"	"image/gif"	"jpeg2gif")
	 ("text/html"	"text/plain"	"striptags")
	)
)

The first matching list element will be used.

For text type messages, MIME also requires that a character set be specified, so that the recipient's mail reader knows what character glyphs to use to display each character code. To display a message properly VM needs to know how to choose a font for a given character set.

The variable vm-mime-default-face-charsets tells VM what character sets your default face can display. For most American and European users using X Windows, Emacs' default face displays the ISO-8859-1 and US-ASCII characters, US-ASCII being a subset of ISO-8859-1. The value of vm-mime-default-face-charsets must be a list of strings specifying the character sets that your default face can display. This variable is useful for making bogus, unregistered character sets that are slight variants of ISO-8859-1 visible. Example:

(add-to-list 'vm-mime-default-face-charsets "Windows-1251")
(add-to-list 'vm-mime-default-face-charsets "Windows-1252")
(add-to-list 'vm-mime-default-face-charsets "Windows-1257")

Messages sent using such character sets would normally be considered undisplayable by VM, and a button would be displayed that offers to save the message body to a file.

Sometimes a charset that VM cannot display can be converted to a one that VM can display. An example would be a message encoded using UTF-8 but in fact only contains Japanese characters. In that case the message text could probably be converted to iso-2022-jp which VM running on a MULE-enabled Emacs could display.

VM offers a way to do such conversions. The variable vm-mime-charset-converter-alist is an associative list of MIME charsets and programs that can convert between them. If VM cannot display a particular character set, it will scan this list to see if the charset can be converted into a charset that it can display.

The alist format is:

 ( ( START-CHARSET END-CHARSET COMMAND-LINE ) ... )

START-CHARSET is a string specifying a MIME charset. Example `"iso-8859-1"' or `"utf-8"'.

END-CHARSET is a string specifying the charset to which START-CHARSET will be converted.

COMMAND-LINE is a string giving a command line to be passed to the shell. The characters in START-CHARSET will be written to the standard input of the shell command and VM expects characters encoded in END-CHARSET to appear at the standard output of the COMMAND-LINE. COMMAND-LINE is passed to the shell, so you can use pipelines, shell variables and redirections.

Example:

(setq vm-mime-charset-converter-alist
      '(
	 ("utf-8" "iso-2022-jp" "iconv -f utf-8 -t iso-2022-jp")
       )
)

The first matching list element will be used.

The variable vm-mime-charset-font-alist tells VM what font to use to display a character set that cannot be displayed using the default face. The value of this variable should be an assoc list of character sets and fonts that can be used to display them. The format of the list is: ( (CHARSET . FONT) ...) CHARSET is a string naming a MIME registered character set such as `"iso-8859-5"'. FONT is a string naming a font that can be used to display CHARSET. An example setup might be:

(setq vm-mime-charset-font-alist
  '(
    ("iso-8859-5" . "-*-*-medium-r-normal-*-16-160-72-72-c-80-iso8859-5")
   )
)

This variable is only useful for character sets whose characters can all be encoded in single 8-bit bytes. Also multiple fonts can only be displayed if you're running under a window system e.g. X Windows. So this variable will have no effect if you're running Emacs on a tty.

Note that under FSF Emacs 19 any fonts you use must be the same height as your default font. XEmacs and Emacs 21 do not have this limitation. Under Emacs 20 and beyond, and under any XEmacs version compiled with MULE support, the value of vm-mime-charset-font-alist has no effect. This is because all characters are displayed using fonts discovered by MULE and VM has no control over them.

MIME allows a message to be sent with its content encoded in multiple formats, simultaneously, in the same message. Such messages have a content type of multipart/alternative. The idea is that the sender might have different MIME decoding or display capabilities than some of his recipients. For instance, the sender may be able to compose a message using fancy text formatting constructs like tables, italics and equations but some of the recipients may only be able to display plain text. The multipart/alternative type message is the solution to this dilemma. Such a message would contain at least two text subparts, one in plaintext and the other in the full featured text formatting language that the sender used.

To control how VM displays multipart/alternative messages, you must set the variable vm-mime-alternative-select-method. Its value must be a symbol. A value of best tells VM to display the message using the subpart closest in appearance to what the sender used to compose the message. In the example above this would mean displaying the fully featured text subpart, if VM knows how to display that type. VM will display the type either internally or externally. A value of best-internal tells VM to use the closest subpart that it can display internally. External viewers won't be used in this case.

Some mailers incorrectly use the generic `application/octet-stream' type when sending files that really have a specific MIME type. For example, a JPEG image might be sent using `application/octet-stream' type instead of `image/jpeg', which would be the correct type. In many cases the filename sent along with the mistyped file (e.g. `foo.jpg') suggests the correct type. If the variable vm-infer-mime-types is set non-nil, VM will attempt to use the filename sent with a MIME attachment to guess an attachment's type if the attachment is of type `application/octet-stream'.


Go to the first, previous, next, last section, table of contents.