Index: includes/mail.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/mail.inc,v
retrieving revision 1.25
diff -u -p -r1.25 mail.inc
--- includes/mail.inc	1 Sep 2009 17:40:27 -0000	1.25
+++ includes/mail.inc	2 Oct 2009 11:45:55 -0000
@@ -93,12 +93,15 @@ function drupal_mail($module, $key, $to,
   // Bundle up the variables into a structured array for altering.
   $message = array(
     'id'       => $module . '_' . $key,
+    'module'   => $module,
+    'key'      => $key,
     'to'       => $to,
     'from'     => isset($from) ? $from : $default_from,
     'language' => $language,
     'params'   => $params,
     'subject'  => '',
-    'body'     => array()
+    'body'     => array(),
+    'html'     => FALSE,
   );
 
   // Build the default headers
@@ -119,6 +122,13 @@ function drupal_mail($module, $key, $to,
   }
   $message['headers'] = $headers;
 
+  // Invoke hook_mail_prepare() to allow all modules to prepare the e-mail; in
+  // particular, to possibly alter $message['html'].
+  foreach (module_implements('mail_prepare') as $module) {
+    $function = $module . '_mail_prepare';
+    $function($message);
+  }
+
   // Build the e-mail (get subject and body, allow additional headers) by
   // invoking hook_mail() on this module. We cannot use module_invoke() as
   // we need to have $message by reference in hook_mail().
Index: modules/system/system.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v
retrieving revision 1.80
diff -u -p -r1.80 system.api.php
--- modules/system/system.api.php	1 Oct 2009 13:16:17 -0000	1.80
+++ modules/system/system.api.php	2 Oct 2009 12:08:03 -0000
@@ -669,6 +669,32 @@ function hook_image_toolkits() {
 }
 
 /**
+ * Prepare an e-mail message created with the drupal_mail() function.
+ *
+ * hook_mail_prepare() allows to prepare and modify the basic e-mail message
+ * data before the message content is created by an implementation of
+ * hook_mail().
+ *
+ * For example, a module allowing e-mail messages to contain HTML may alter
+ * $message['html'] to TRUE to inform the hook_mail() implementation that any
+ * HTML in the message text should not be converted to plain-text.
+ *
+ * @param &$message
+ *   An array containing the message data, as described in hook_mail_alter().
+ *
+ * @see hook_mail()
+ * @see hook_mail_alter()
+ * @see drupal_mail()
+ */
+function hook_mail_prepare(&$message) {
+  // Our example module allows to enter HTML for the configurable "Send e-mail"
+  // action.
+  if ($message['module'] == 'system' && $message['key'] == 'action_send_email') {
+    $message['html'] = TRUE;
+  }
+}
+
+/**
  * Alter an email message created with the drupal_mail() function.
  *
  * hook_mail_alter() allows modification of email messages created and sent
@@ -699,6 +725,10 @@ function hook_image_toolkits() {
  *     An array of strings containing the message text. The message body is
  *     created by concatenating the individual array strings into a single text
  *     string using "\n\n" as a separator.
+ *  - 'html':
+ *     A boolean value indicating whether implementations of hook_mail() shall
+ *     convert potential HTML in the e-mail body to plain-text. Defaults to
+ *     FALSE.
  *  - 'headers':
  *     Associative array containing mail headers, such as From, Sender,
  *     MIME-Version, Content-Type, etc.
@@ -709,6 +739,8 @@ function hook_image_toolkits() {
  *     The language object used to build the message before hook_mail_alter()
  *     is invoked.
  *
+ * @see hook_mail()
+ * @see hook_mail_prepare()
  * @see drupal_mail()
  */
 function hook_mail_alter(&$message) {
@@ -1061,6 +1093,10 @@ function hook_watchdog(array $log_entry)
  *     An array of lines containing the message to be sent. Drupal will format
  *     the correct line endings for you. drupal_mail() sets this to an empty
  *     array when the hook is invoked.
+ *  - 'html':
+ *     A boolean value indicating whether potential HTML in the e-mail body
+ *     should be converted to plain-text using drupal_html_to_text(). Defaults
+ *     to FALSE.
  *  - 'from':
  *     The address the message will be marked as being from, which is
  *     set by drupal_mail() to either a custom address or the site-wide
@@ -1071,6 +1107,10 @@ function hook_watchdog(array $log_entry)
  *     several headers in this array.
  * @param $params
  *   An array of parameters supplied by the caller of drupal_mail().
+ *
+ * @see drupal_mail()
+ * @see hook_mail_prepare()
+ * @see hook_mail_alter()
  */
 function hook_mail($key, &$message, $params) {
   $account = $params['account'];
@@ -1107,7 +1147,9 @@ function hook_mail($key, &$message, $par
   $subject = strtr($context['subject'], $variables);
   $body = strtr($context['message'], $variables);
   $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
-  $message['body'][] = drupal_html_to_text($body);
+  // By default, any HTML in the message body should be converted to text,
+  // unless another module instructed us to keep it.
+  $message['body'][] = ($message['html'] ? $body : drupal_html_to_text($body));
 }
 
 /**
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.800
diff -u -p -r1.800 system.module
--- modules/system/system.module	30 Sep 2009 18:36:02 -0000	1.800
+++ modules/system/system.module	2 Oct 2009 11:29:54 -0000
@@ -2566,7 +2566,9 @@ function system_mail($key, &$message, $p
   $body = token_replace($context['message'], $context);
 
   $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
-  $message['body'][] = drupal_html_to_text($body);
+  // A configurable action may contain tokens that generate HTML. By default,
+  // we convert any HTML to text, unless a module instructed us to keep it.
+  $message['body'][] = ($message['html'] ? $body : drupal_html_to_text($body));
 }
 
 function system_message_action_form($context) {
