mirror of https://github.com/djcb/mu.git
Merge pull request #986 from stig/format-flowed-alt
POC: Respect format=flowed and delsp=yes for viewing plain-text messages
This commit is contained in:
commit
ad1a372b5f
|
@ -422,11 +422,31 @@ append_sexp_thread_info (GString *gstr, const MuMsgIterThreadInfo *ti)
|
||||||
" :has-child t" : "");
|
" :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
|
static void
|
||||||
append_message_file_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
|
append_message_file_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
GError *err;
|
GError *err;
|
||||||
|
const GSList *params;
|
||||||
|
|
||||||
err = NULL;
|
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")))
|
if (str || (str = mu_msg_get_header (msg, "X-Mailer")))
|
||||||
append_sexp_attr (gstr, "user-agent", str);
|
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",
|
append_sexp_body_attr (gstr, "body-txt",
|
||||||
mu_msg_get_body_text(msg, opts));
|
mu_msg_get_body_text(msg, opts));
|
||||||
append_sexp_body_attr (gstr, "body-html",
|
append_sexp_body_attr (gstr, "body-html",
|
||||||
|
|
70
lib/mu-msg.c
70
lib/mu-msg.c
|
@ -520,6 +520,76 @@ get_body (MuMsg *self, MuMsgOptions opts, gboolean want_html)
|
||||||
return g_string_free (bdata.gstr, FALSE);
|
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*
|
const char*
|
||||||
mu_msg_get_body_html (MuMsg *self, MuMsgOptions opts)
|
mu_msg_get_body_html (MuMsg *self, MuMsgOptions opts)
|
||||||
{
|
{
|
||||||
|
|
13
lib/mu-msg.h
13
lib/mu-msg.h
|
@ -166,6 +166,19 @@ void mu_msg_cache_values (MuMsg *self);
|
||||||
const char* mu_msg_get_body_text (MuMsg *msg, MuMsgOptions opts);
|
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
|
* get the html body of this message
|
||||||
*
|
*
|
||||||
|
|
|
@ -184,6 +184,7 @@ static void
|
||||||
test_mu_msg_03 (void)
|
test_mu_msg_03 (void)
|
||||||
{
|
{
|
||||||
MuMsg *msg;
|
MuMsg *msg;
|
||||||
|
GSList *params;
|
||||||
|
|
||||||
msg = get_msg (MU_TESTMAILDIR4 "/1283599333.1840_11.cthulhu!2,");
|
msg = get_msg (MU_TESTMAILDIR4 "/1283599333.1840_11.cthulhu!2,");
|
||||||
g_assert_cmpstr (mu_msg_get_to(msg),
|
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),
|
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");
|
"\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),
|
g_assert_cmpuint (mu_msg_get_flags(msg),
|
||||||
==, MU_FLAG_UNREAD); /* not seen => unread */
|
==, MU_FLAG_UNREAD); /* not seen => unread */
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
(require 'cl)
|
(require 'cl)
|
||||||
(require 'html2text)
|
(require 'html2text)
|
||||||
|
(require 'flow-fill)
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-html2text-command
|
(defcustom mu4e-html2text-command
|
||||||
|
@ -189,6 +190,12 @@ representation."
|
||||||
;; otherwise, use text
|
;; otherwise, use text
|
||||||
(t nil))))
|
(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)
|
(defun mu4e-message-body-text (msg &optional prefer-html)
|
||||||
"Get the body in text form for this message.
|
"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)))
|
(mu4e~html2text-wrapper mu4e-html2text-command msg)))
|
||||||
(t (mu4e-error "Invalid `mu4e-html2text-command'")))
|
(t (mu4e-error "Invalid `mu4e-html2text-command'")))
|
||||||
;; use a text body
|
;; 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)
|
(dolist (func mu4e-message-body-rewrite-functions)
|
||||||
(setq body (funcall func msg body)))
|
(setq body (funcall func msg body)))
|
||||||
body))
|
body))
|
||||||
|
|
Loading…
Reference in New Issue