Mu4e: further improve org-msg

- stylistic tweaks
- make accent colour easily user-settable
- scale LaTeX fragments appropriately
- make it easy to toggle org-msg-mode for one-off messages
This commit is contained in:
TEC 2020-10-01 01:52:58 +08:00
parent aecdbb17b2
commit a974db04c4
No known key found for this signature in database
GPG key ID: 779591AFDB81F06C
3 changed files with 147 additions and 27 deletions

View file

@ -18,6 +18,7 @@
- [[#offlineimap][offlineimap]] - [[#offlineimap][offlineimap]]
- [[#mbsync][mbsync]] - [[#mbsync][mbsync]]
- [[#mu-and-mu4e][mu and mu4e]] - [[#mu-and-mu4e][mu and mu4e]]
- [[#orgmsg][OrgMsg]]
- [[#troubleshooting][Troubleshooting]] - [[#troubleshooting][Troubleshooting]]
- [[#no-such-file-or-directory-mu4e][=No such file or directory, mu4e=]] - [[#no-such-file-or-directory-mu4e][=No such file or directory, mu4e=]]
- [[#void-function-org-time-add-error-on-gentoo][~(void-function org-time-add)~ error on Gentoo]] - [[#void-function-org-time-add-error-on-gentoo][~(void-function org-time-add)~ error on Gentoo]]
@ -168,6 +169,15 @@ Then configure Emacs to use your email address:
(mu4e-compose-signature . "---\nHenrik Lissner")) (mu4e-compose-signature . "---\nHenrik Lissner"))
t) t)
#+END_SRC #+END_SRC
** OrgMsg
By default, ~org-msg-mode~ is enabled before composing the first message.
To disable ~org-msg-mode~ by default, simply
#+BEGIN_SRC emacs-lisp :tangle no
(setq mu4e-compose--org-msg-toggle-next nil)
#+END_SRC
To toggle org-msg for a single message, just apply the universal argument to the
compose or reply command (=SPC u= with ~evil~, =C-u= otherwise).
* Troubleshooting * Troubleshooting
** =No such file or directory, mu4e= ** =No such file or directory, mu4e=

View file

@ -189,18 +189,18 @@ is tomorrow. With two prefixes, select the deadline."
;;;###autoload ;;;###autoload
(defun my-mu4e-set-account () (defun my-mu4e-set-account ()
"Set the account for composing a message. If a 'To' header is present, "Set the account for composing a message. If a 'To' header is present,
and correspands to an email account, this account will be selected. and correspands to an email account, this account will be selected.
Otherwise, the user is prompted for the account they wish to use." Otherwise, the user is prompted for the account they wish to use."
(unless (and mu4e-compose-parent-message (unless (and mu4e-compose-parent-message
(let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to))))
(from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from)))))
(if (member to (plist-get mu4e~server-props :personal-addresses)) (if (member to (plist-get mu4e~server-props :personal-addresses))
(setq user-mail-address to) (setq user-mail-address to)
(if (member from (plist-get mu4e~server-props :personal-addresses)) (if (member from (plist-get mu4e~server-props :personal-addresses))
(setq user-mail-address from) (setq user-mail-address from)
nil)))) nil))))
(ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate)))))
;;;###autoload ;;;###autoload
(defun mu4e~main-action-prettier-str (str &optional func-or-shortcut) (defun mu4e~main-action-prettier-str (str &optional func-or-shortcut)
@ -245,3 +245,91 @@ clicked."
(+mu4e--old-wconf (+mu4e--old-wconf
(set-window-configuration +mu4e--old-wconf) (set-window-configuration +mu4e--old-wconf)
(setq +mu4e--old-wconf nil)))) (setq +mu4e--old-wconf nil))))
;; org-msg hooks
;;;###autoload
(defun +org-msg-img-scale-css (img-uri)
"For a given IMG-URI, use imagemagik to find its width."
(if org-msg-currently-exporting
(list :width
(format "%.1fpx"
(/ (string-to-number
(shell-command-to-string
(format "identify -format %%w %s"
(substring img-uri 7)))) ; 7=(length "file://")
(plist-get org-format-latex-options :scale))))
(list :style (format "transform: scale(%.3f)"
(/ 1.0 (plist-get org-format-latex-options :scale))))))
(defun org-html-latex-fragment-scaled (latex-fragment _contents info)
"Transcode a LATEX-FRAGMENT object from Org to HTML.
CONTENTS is nil. INFO is a plist holding contextual information.
This differs from `org-html-latex-fragment' in that it uses the LaTeX fragment
as a meaningful alt value, applies a class to indicate what sort of fragment it is
(latex-fragment-inline or latex-fragment-block), and (on Linux) scales the image to
account for the value of :scale in `org-format-latex-options'."
(let ((latex-frag (org-element-property :value latex-fragment))
(processing-type (plist-get info :with-latex)))
(cond
((memq processing-type '(t mathjax))
(org-html-format-latex latex-frag 'mathjax info))
((memq processing-type '(t html))
(org-html-format-latex latex-frag 'html info))
((assq processing-type org-preview-latex-process-alist)
(let ((formula-link
(org-html-format-latex latex-frag processing-type info)))
(when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
(let ((source (org-export-file-uri (match-string 1 formula-link)))
(attributes (list :alt latex-frag
:class (concat "latex-fragment-"
(if (equal "\\(" (substring latex-frag 0 2))
"inline" "block")))))
(when (and (memq processing-type '(dvipng convert)) IS-LINUX)
(apply #'plist-put attributes (+org-msg-img-scale-css source)))
(org-html--format-image source attributes info)))))
(t latex-frag))))
(defun org-html-latex-environment-scaled (latex-environment _contents info)
"Transcode a LATEX-ENVIRONMENT element from Org to HTML.
CONTENTS is nil. INFO is a plist holding contextual information.
This differs from `org-html-latex-environment' in that (on Linux) it
scales the image to account for the value of :scale in `org-format-latex-options'."
(let ((processing-type (plist-get info :with-latex))
(latex-frag (org-remove-indentation
(org-element-property :value latex-environment)))
(attributes (org-export-read-attribute :attr_html latex-environment))
(label (and (org-element-property :name latex-environment)
(org-export-get-reference latex-environment info)))
(caption (and (org-html--latex-environment-numbered-p latex-environment)
(number-to-string
(org-export-get-ordinal
latex-environment info nil
(lambda (l _)
(and (org-html--math-environment-p l)
(org-html--latex-environment-numbered-p l))))))))
(plist-put attributes :class "latex-environment")
(cond
((memq processing-type '(t mathjax))
(org-html-format-latex
(if (org-string-nw-p label)
(replace-regexp-in-string "\\`.*"
(format "\\&\n\\\\label{%s}" label)
latex-frag)
latex-frag)
'mathjax info))
((assq processing-type org-preview-latex-process-alist)
(let ((formula-link
(org-html-format-latex
(org-html--unlabel-latex-environment latex-frag)
processing-type info)))
(when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
(let ((source (org-export-file-uri (match-string 1 formula-link))))
(when (and (memq processing-type '(dvipng convert)) IS-LINUX)
(apply #'plist-put attributes (+org-msg-img-scale-css source)))
(org-html--wrap-latex-environment
(org-html--format-image source attributes info)
info caption label)))))
(t (org-html--wrap-latex-environment latex-frag info caption label)))))

View file

@ -172,7 +172,7 @@
(when (featurep! :lang org) (when (featurep! :lang org)
(use-package! org-msg (use-package! org-msg
:hook (org-load . org-msg-mode) :after (mu4e org)
:config :config
(setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng"
org-msg-startup "hidestars indent inlineimages" org-msg-startup "hidestars indent inlineimages"
@ -190,6 +190,27 @@ Usefull for affecting HTML export config.")
:after #'org-msg-org-to-xml :after #'org-msg-org-to-xml
(setq org-msg-currently-exporting nil)) (setq org-msg-currently-exporting nil))
(advice-add #'org-html-latex-fragment :override #'org-html-latex-fragment-scaled)
(advice-add #'org-html-latex-environment :override #'org-html-latex-environment-scaled)
(defvar mu4e-compose--org-msg-toggle-next t ; t to initialise org-msg
"Whether to toggle ")
(defun mu4e-compose-org-msg-handle-toggle (toggle-p)
(when (xor toggle-p mu4e-compose--org-msg-toggle-next)
(org-msg-mode (if org-msg-mode -1 1))
(setq mu4e-compose--org-msg-toggle-next
(not mu4e-compose--org-msg-toggle-next))))
(defadvice! mu4e-maybe-toggle-org-msg (orig-fn toggle-p)
:around #'mu4e-compose-new
:around #'mu4e-compose-reply
(interactive "p")
(mu4e-compose-org-msg-handle-toggle (/= 1 toggle-p))
(funcall orig-fn))
(defvar +org-msg-accent-color "#c01c28"
"Accent color to use in org-msg's generated CSS.
Must be set before org-msg is loaded to take effect.")
(setq org-msg-enforce-css (setq org-msg-enforce-css
(let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\ (let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\
\"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";")) \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";"))
@ -197,12 +218,13 @@ Usefull for affecting HTML export config.")
(font-size '(font-size . "11pt")) (font-size '(font-size . "11pt"))
(font `(,font-family ,font-size)) (font `(,font-family ,font-size))
(line-height '(line-height . "1.2")) (line-height '(line-height . "1.2"))
(theme-color "#8a0400") (theme-color +org-msg-accent-color)
(bold '(font-weight . "bold")) (bold '(font-weight . "bold"))
(color `(color . ,theme-color)) (color `(color . ,theme-color))
(table `((margin-top . "6px") (margin-bottom . "6px") (table `((margin-top . "6px") (margin-bottom . "6px")
(border-left . "none") (border-right . "none") (border-left . "none") (border-right . "none")
(border-top . "2px solid #222222") (border-bottom . "2px solid #222222") (border-top . "2px solid #222222")
(border-bottom . "2px solid #222222")
)) ))
(ftl-number `(,color ,bold (text-align . "left"))) (ftl-number `(,color ,bold (text-align . "left")))
(inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp (inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp
@ -234,10 +256,12 @@ Usefull for affecting HTML export config.")
(margin-top . "0px") (margin-left . "30px") (margin-top . "0px") (margin-left . "30px")
(padding-top . "0px") (padding-left . "5px"))) (padding-top . "0px") (padding-left . "5px")))
(nil signature (,@font (margin-bottom . "20px"))) (nil signature (,@font (margin-bottom . "20px")))
(blockquote nil ((padding . "0px 10px") (margin-left . "10px") (blockquote nil ((padding . "2px 12px") (margin-left . "10px")
(margin-top . "20px") (margin-bottom . "0") (margin-top . "10px") (margin-bottom . "0")
(border-left . "3px solid #ccc") (font-style . "italic") (border-left . "3px solid #ccc")
(font-style . "italic")
(background . "#f9f9f9"))) (background . "#f9f9f9")))
(p blockquote ((margin . "0") (padding . "4px 0")))
(code nil (,font-size ,monospace-font (background . "#f9f9f9"))) (code nil (,font-size ,monospace-font (background . "#f9f9f9")))
,@code-src ,@code-src
(nil linenr ((padding-right . "1em") (nil linenr ((padding-right . "1em")
@ -266,10 +290,7 @@ Usefull for affecting HTML export config.")
(nil org-src-name ,ftl-number) (nil org-src-name ,ftl-number)
(img nil ((vertical-align . "middle") (img nil ((vertical-align . "middle")
(max-width . "100%"))) (max-width . "100%")))
(img latex-fragment-inline ((transform . ,(format "translateY(-1px) scale(%.3f)" (img latex-fragment-inline ((margin . "0 0.1em")))
(/ 1.0 (if (boundp 'preview-scale)
preview-scale 1.4))))
(margin . "0 -0.35em")))
(table nil (,@table ,line-height (border-collapse . "collapse"))) (table nil (,@table ,line-height (border-collapse . "collapse")))
(th nil ((border . "none") (border-bottom . "1px solid #222222") (th nil ((border . "none") (border-bottom . "1px solid #222222")
(background-color . "#EDEDED") (font-weight . "500") (background-color . "#EDEDED") (font-weight . "500")
@ -280,8 +301,9 @@ Usefull for affecting HTML export config.")
(td org-right ((text-align . "right"))) (td org-right ((text-align . "right")))
(td org-center ((text-align . "center"))) (td org-center ((text-align . "center")))
(kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px") (kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px")
(box-shadow . "inset 0 -1px 0 #d1d5da") (background-color . "#fafbfc") (box-shadow . "inset 0 -1px 0 #d1d5da")
(color . "#444d56") (padding . "3px 5px") (display . "inline-block"))) (background-color . "#fafbfc") (color . "#444d56")
(padding . "3px 5px") (display . "inline-block")))
(div outline-text-4 ((margin-left . "15px"))) (div outline-text-4 ((margin-left . "15px")))
(div outline-4 ((margin-left . "10px"))) (div outline-4 ((margin-left . "10px")))
(h4 nil ((margin-bottom . "0px") (font-size . "11pt"))) (h4 nil ((margin-bottom . "0px") (font-size . "11pt")))
@ -289,11 +311,11 @@ Usefull for affecting HTML export config.")
,color (font-size . "14pt"))) ,color (font-size . "14pt")))
(h2 nil ((margin-top . "20px") (margin-bottom . "20px") (h2 nil ((margin-top . "20px") (margin-bottom . "20px")
,color (font-size . "18pt"))) ,color (font-size . "18pt")))
(h1 nil ((margin-top . "20px") (h1 nil ((margin-top . "20px") (margin-bottom . "0px")
(margin-bottom . "0px") ,color (font-size . "24pt"))) ,color (font-size . "24pt")))
(p nil ((text-decoration . "none") (margin-bottom . "0px") (p nil ((text-decoration . "none") (line-height . "11pt")
(margin-top . "10px") (line-height . "11pt") ,font-size (margin-top . "10px") (margin-bottom . "0px")
(max-width . "100ch"))) ,font-size (max-width . "100ch")))
(b nil ((font-weight . "500") (color . ,theme-color))) (b nil ((font-weight . "500") (color . ,theme-color)))
(div nil (,@font (line-height . "12pt")))))))) (div nil (,@font (line-height . "12pt"))))))))