Respect format=flowed and delsp=yes for viewing plain-text messages

This commit is contained in:
Stig Brautaset 2016-12-18 16:16:02 +00:00
parent 05faceeb49
commit cdc2fa1bd8
5 changed files with 137 additions and 1 deletions

View File

@ -422,11 +422,31 @@ append_sexp_thread_info (GString *gstr, const MuMsgIterThreadInfo *ti)
" :has-child t" : "");
}
static void
append_sexp_param (GString *gstr, GSList *param)
{
for (;param; param = g_slist_next (param)) {
char *key, *value;
key = param->data;
key = key ? mu_str_escape_c_literal (key, FALSE) : "";
param = g_slist_next (param);
value = param->data;
value = value ? mu_str_escape_c_literal (value, FALSE) : "";
g_string_append_printf (gstr, "(\"%s\" . \"%s\")", key, value);
if (param->next)
g_string_append_c (gstr, ' ');
}
}
static void
append_message_file_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
{
const char *str;
GError *err;
const GSList *params;
err = NULL;
@ -445,6 +465,13 @@ append_message_file_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
if (str || (str = mu_msg_get_header (msg, "X-Mailer")))
append_sexp_attr (gstr, "user-agent", str);
params = mu_msg_get_body_text_content_type_parameters (msg, opts);
if (params) {
g_string_append_printf (gstr, "\t:body-txt-params (");
append_sexp_param (gstr, params);
g_string_append_printf (gstr, ")\n");
}
append_sexp_body_attr (gstr, "body-txt",
mu_msg_get_body_text(msg, opts));
append_sexp_body_attr (gstr, "body-html",

View File

@ -520,6 +520,76 @@ get_body (MuMsg *self, MuMsgOptions opts, gboolean want_html)
return g_string_free (bdata.gstr, FALSE);
}
struct _ContentTypeData {
const GMimeContentType *ctype;
gboolean want_html;
};
typedef struct _ContentTypeData ContentTypeData;
static void
find_content_type (MuMsg *msg, MuMsgPart *mpart, ContentTypeData *cdata)
{
if (!GMIME_IS_PART(mpart->data))
return;
/* text-like attachments are included when in text-mode */
GMimePart *wanted = NULL;
if (!cdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN))
wanted = mpart->data;
else if (!(mpart->part_type & MU_MSG_PART_TYPE_ATTACHMENT) &&
cdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_HTML))
wanted = mpart->data;
if (wanted)
cdata->ctype = g_mime_object_get_content_type (wanted);
}
static const GSList*
get_content_type_parameters (MuMsg *self, MuMsgOptions opts, gboolean want_html)
{
ContentTypeData cdata;
cdata.want_html = want_html;
cdata.ctype = NULL;
mu_msg_part_foreach (self, opts,
(MuMsgPartForeachFunc)find_content_type,
&cdata);
if (cdata.ctype) {
const GSList *paramlist;
const GMimeParam *param;
paramlist = NULL;
param = g_mime_content_type_get_params (cdata.ctype);
for (; param; param = param->next) {
paramlist = g_slist_prepend (paramlist,
g_strdup (param->name));
paramlist = g_slist_prepend (paramlist,
g_strdup (param->value));
}
return free_later_lst(self, g_slist_reverse (paramlist));
}
return NULL;
}
const GSList*
mu_msg_get_body_text_content_type_parameters (MuMsg *self, MuMsgOptions opts)
{
g_return_val_if_fail (self, NULL);
return get_content_type_parameters(self, opts, FALSE);
}
const char*
mu_msg_get_body_html (MuMsg *self, MuMsgOptions opts)
{

View File

@ -166,6 +166,19 @@ void mu_msg_cache_values (MuMsg *self);
const char* mu_msg_get_body_text (MuMsg *msg, MuMsgOptions opts);
/**
* get the content type parameters for the text body part
*
* @param msg a valid MuMsg* instance
* @param opts options for getting the body
*
* @return the value of the requested body part content type parameter, or
* NULL in case of error or if there is no such body. the returned string
* should *not* be modified or freed. The returned data is in UTF8 or NULL.
*/
const GSList* mu_msg_get_body_text_content_type_parameters (MuMsg *self, MuMsgOptions opts);
/**
* get the html body of this message
*

View File

@ -184,6 +184,7 @@ static void
test_mu_msg_03 (void)
{
MuMsg *msg;
GSList *params;
msg = get_msg (MU_TESTMAILDIR4 "/1283599333.1840_11.cthulhu!2,");
g_assert_cmpstr (mu_msg_get_to(msg),
@ -199,6 +200,14 @@ test_mu_msg_03 (void)
g_assert_cmpstr (mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE),
==,
"\nLet's write some fünkÿ text\nusing umlauts.\n\nFoo.\n");
params = mu_msg_get_body_text_content_type_parameters(msg, MU_MSG_OPTION_NONE);
g_assert_cmpuint (g_slist_length ((GSList*)params), ==, 2);
g_assert_cmpstr ((char*)params->data,==, "charset");
params = g_slist_next(params);
g_assert_cmpstr ((char*)params->data,==,"UTF-8");
g_assert_cmpuint (mu_msg_get_flags(msg),
==, MU_FLAG_UNREAD); /* not seen => unread */

View File

@ -32,6 +32,7 @@
(require 'cl)
(require 'html2text)
(require 'flow-fill)
(defcustom mu4e-html2text-command
@ -189,6 +190,12 @@ representation."
;; otherwise, use text
(t nil))))
(defun mu4e~message-body-has-content-type-param (msg param)
(cdr
(assoc param (mu4e-message-field msg :body-txt-params))))
(defun mu4e~safe-iequal (a b)
(and b (equal (downcase b) a)))
(defun mu4e-message-body-text (msg &optional prefer-html)
"Get the body in text form for this message.
@ -210,7 +217,17 @@ unless PREFER-HTML is non-nil."
(mu4e~html2text-wrapper mu4e-html2text-command msg)))
(t (mu4e-error "Invalid `mu4e-html2text-command'")))
;; use a text body
(or (mu4e-message-field msg :body-txt) ""))))
(or (with-temp-buffer
(insert (mu4e-message-field msg :body-txt))
(if (mu4e~safe-iequal "flowed"
(mu4e~message-body-has-content-type-param
msg "format"))
(fill-flowed nil (mu4e~safe-iequal
"yes"
(mu4e~message-body-has-content-type-param
msg "delsp"))))
(buffer-string))
""))))
(dolist (func mu4e-message-body-rewrite-functions)
(setq body (funcall func msg body)))
body))