From 68fd3b71d365407fc89f7990907cb09b150fe7f0 Mon Sep 17 00:00:00 2001 From: djcb Date: Sun, 27 Nov 2016 14:34:50 +0200 Subject: [PATCH] mu4e: fix toggling between html/text --- mu4e/mu4e-message.el | 92 +++++++++++++++++++++++--------------------- mu4e/mu4e-view.el | 17 ++++++-- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/mu4e/mu4e-message.el b/mu4e/mu4e-message.el index e91ef403..94a02bc5 100644 --- a/mu4e/mu4e-message.el +++ b/mu4e/mu4e-message.el @@ -161,60 +161,66 @@ This is equivalent to: (defvar mu4e~message-body-html nil "Whether the body text uses HTML.") + +(defun mu4e~message-use-html-p (msg prefer-html) + "Determine whether we want to use html or text; this is based +on PREFER-HTML and whether the message supports the given +representation." + (let* ((txt (mu4e-message-field msg :body-txt)) + (html (mu4e-message-field msg :body-html)) + (txt-len (length txt)) + (html-len (length html)) + (txt-limit (* mu4e-view-html-plaintext-ratio-heuristic txt-len)) + (txt-limit (if (>= txt-limit 0) txt-limit most-positive-fixnum))) + (cond + ; user prefers html --> use html if there is + (prefer-html (> html-len 0)) + ;; otherwise (user prefers text) still use html if there is not enough + ;; text + ((< txt-limit html-len) t) + ;; otherwise, use text + (t nil)))) + + (defun mu4e-message-body-text (msg &optional prefer-html) "Get the body in text form for this message. This is either :body-txt, or if not available, :body-html converted to text, using `mu4e-html2text-command' is non-nil, it will use that. Normally, this function prefers the text part, unless PREFER-HTML is non-nil." - (setq mu4e~message-body-html nil) ;; default - (let* ((txt (mu4e-message-field msg :body-txt)) - (html (mu4e-message-field msg :body-html)) - (txtlen (length txt)) - (txtlimit (* mu4e-view-html-plaintext-ratio-heuristic txtlen)) - (txtlimit (if (>= txtlimit 0) txtlimit most-positive-fixnum)) ;; overflow - (body - (cond - ;; does it look like some text? ie., if the text part is more than - ;; mu4e-view-html-plaintext-ratio-heuristic times shorter than the - ;; html part, it should't be used - ;; This is an heuristic to guard against 'This messages requires - ;; html' text bodies. - ((and (> txtlen 0) - (or (> txtlimit (length html)) (not prefer-html))) - txt) - ;; otherwise, it there some html? - (html - (with-temp-buffer - (insert html) - (cond - ((stringp mu4e-html2text-command) - (let* ((tmp-file (mu4e-make-temp-file "html"))) - (write-region (point-min) (point-max) tmp-file) - (erase-buffer) - (call-process-shell-command mu4e-html2text-command tmp-file t t) - (delete-file tmp-file))) - ((functionp mu4e-html2text-command) - (funcall mu4e-html2text-command)) - (t (mu4e-error "Invalid `mu4e-html2text-command'"))) - (setq mu4e~message-body-html t) - (buffer-string)) - ) - (t ;; otherwise, an empty body - "")))) + (setq mu4e~message-body-html (mu4e~message-use-html-p msg prefer-html)) + (let ((body + (if mu4e~message-body-html + ;; use an HTML body + (with-temp-buffer + (insert (mu4e-message-field msg :body-html)) + (cond + ((stringp mu4e-html2text-command) + (let* ((tmp-file (mu4e-make-temp-file "html"))) + (write-region (point-min) (point-max) tmp-file) + (erase-buffer) + (call-process-shell-command mu4e-html2text-command tmp-file t t) + (delete-file tmp-file))) + ((functionp mu4e-html2text-command) + (funcall mu4e-html2text-command)) + (t (mu4e-error "Invalid `mu4e-html2text-command'"))) + (setq mu4e~message-body-html t) + (buffer-string)) + ;; use a text body + (or (mu4e-message-field msg :body-txt) "")))) ;; and finally, remove some crap from the remaining string; it seems ;; esp. outlook lies about its encoding (ie., it says 'iso-8859-1' but ;; really it's 'windows-1252'), thus giving us these funky chars. here, we ;; either remove them, or replace with 'what-was-meant' (heuristically) (with-temp-buffer - (insert body) - (goto-char (point-min)) - (while (re-search-forward "[  ’]" nil t) - (replace-match - (cond - ((string= (match-string 0) "’") "'") - (t "")))) - (buffer-string)))) + (insert body) + (goto-char (point-min)) + (while (re-search-forward "[  ’]" nil t) + (replace-match + (cond + ((string= (match-string 0) "’") "'") + (t "")))) + (buffer-string)))) (defun mu4e-message-contact-field-matches (msg cfield rx) "Checks whether any of the of the contacts in field diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index 01832088..a6e2f815 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -254,7 +254,13 @@ found." (mu4e~view-custom-field msg field)))))) mu4e-view-fields "") "\n" - (let ((body (mu4e-message-body-text msg mu4e-view-prefer-html))) + (let* ((prefer-html + (cond + ((eq mu4e~view-html-text 'html) t) + ((eq mu4e~view-html-text 'text) nil) + (t mu4e-view-prefer-html))) + (body (mu4e-message-body-text msg prefer-html))) + (setq mu4e~view-html-text nil) (when (fboundp 'add-face-text-property) (add-face-text-property 0 (length body) 'mu4e-view-body-face t body)) body))) @@ -969,11 +975,16 @@ the new docid. Otherwise, return nil." (mu4e-view-refresh) (mu4e~view-hide-cited))) +(defvar mu4e~view-html-text nil + "Should we prefer html or text just this once? A symbol `text' +or `html' or nil.") + (defun mu4e-view-toggle-html () "Toggle html-display of the message body (if any)." (interactive) - (let ((mu4e-view-prefer-html (not mu4e~message-body-html))) - (mu4e-view-refresh))) + (setq mu4e~view-html-text + (if mu4e~message-body-html 'text 'html)) + (mu4e-view-refresh)) (defun mu4e-view-refresh () "Redisplay the current message."