mu4e: fix toggling between html/text

This commit is contained in:
djcb
2016-11-27 14:34:50 +02:00
parent b6d73b5da4
commit 68fd3b71d3
2 changed files with 63 additions and 46 deletions

View File

@ -161,60 +161,66 @@ This is equivalent to:
(defvar mu4e~message-body-html nil (defvar mu4e~message-body-html nil
"Whether the body text uses HTML.") "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) (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.
This is either :body-txt, or if not available, :body-html This is either :body-txt, or if not available, :body-html
converted to text, using `mu4e-html2text-command' is non-nil, it converted to text, using `mu4e-html2text-command' is non-nil, it
will use that. Normally, this function prefers the text part, will use that. Normally, this function prefers the text part,
unless PREFER-HTML is non-nil." unless PREFER-HTML is non-nil."
(setq mu4e~message-body-html nil) ;; default (setq mu4e~message-body-html (mu4e~message-use-html-p msg prefer-html))
(let* ((txt (mu4e-message-field msg :body-txt)) (let ((body
(html (mu4e-message-field msg :body-html)) (if mu4e~message-body-html
(txtlen (length txt)) ;; use an HTML body
(txtlimit (* mu4e-view-html-plaintext-ratio-heuristic txtlen)) (with-temp-buffer
(txtlimit (if (>= txtlimit 0) txtlimit most-positive-fixnum)) ;; overflow (insert (mu4e-message-field msg :body-html))
(body (cond
(cond ((stringp mu4e-html2text-command)
;; does it look like some text? ie., if the text part is more than (let* ((tmp-file (mu4e-make-temp-file "html")))
;; mu4e-view-html-plaintext-ratio-heuristic times shorter than the (write-region (point-min) (point-max) tmp-file)
;; html part, it should't be used (erase-buffer)
;; This is an heuristic to guard against 'This messages requires (call-process-shell-command mu4e-html2text-command tmp-file t t)
;; html' text bodies. (delete-file tmp-file)))
((and (> txtlen 0) ((functionp mu4e-html2text-command)
(or (> txtlimit (length html)) (not prefer-html))) (funcall mu4e-html2text-command))
txt) (t (mu4e-error "Invalid `mu4e-html2text-command'")))
;; otherwise, it there some html? (setq mu4e~message-body-html t)
(html (buffer-string))
(with-temp-buffer ;; use a text body
(insert html) (or (mu4e-message-field msg :body-txt) ""))))
(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
""))))
;; and finally, remove some crap from the remaining string; it seems ;; and finally, remove some crap from the remaining string; it seems
;; esp. outlook lies about its encoding (ie., it says 'iso-8859-1' but ;; 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 ;; really it's 'windows-1252'), thus giving us these funky chars. here, we
;; either remove them, or replace with 'what-was-meant' (heuristically) ;; either remove them, or replace with 'what-was-meant' (heuristically)
(with-temp-buffer (with-temp-buffer
(insert body) (insert body)
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "[ (while (re-search-forward "[
<EFBFBD><EFBFBD>]" nil t) <EFBFBD><EFBFBD>]" nil t)
(replace-match (replace-match
(cond (cond
((string= (match-string 0) "<EFBFBD>") "'") ((string= (match-string 0) "<EFBFBD>") "'")
(t "")))) (t ""))))
(buffer-string)))) (buffer-string))))
(defun mu4e-message-contact-field-matches (msg cfield rx) (defun mu4e-message-contact-field-matches (msg cfield rx)

View File

@ -254,7 +254,13 @@ found."
(mu4e~view-custom-field msg field)))))) (mu4e~view-custom-field msg field))))))
mu4e-view-fields "") mu4e-view-fields "")
"\n" "\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) (when (fboundp 'add-face-text-property)
(add-face-text-property 0 (length body) 'mu4e-view-body-face t body)) (add-face-text-property 0 (length body) 'mu4e-view-body-face t body))
body))) body)))
@ -969,11 +975,16 @@ the new docid. Otherwise, return nil."
(mu4e-view-refresh) (mu4e-view-refresh)
(mu4e~view-hide-cited))) (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 () (defun mu4e-view-toggle-html ()
"Toggle html-display of the message body (if any)." "Toggle html-display of the message body (if any)."
(interactive) (interactive)
(let ((mu4e-view-prefer-html (not mu4e~message-body-html))) (setq mu4e~view-html-text
(mu4e-view-refresh))) (if mu4e~message-body-html 'text 'html))
(mu4e-view-refresh))
(defun mu4e-view-refresh () (defun mu4e-view-refresh ()
"Redisplay the current message." "Redisplay the current message."