2

I know I can do something like this:

(setq org-format-latex-options (plist-put org-format-latex-options :scale 1.5)

But what If I want to change another property, say :foreground, how do I do it? I don't want to repeat the whole thing again, there's gotta be a better way, right?

1

If I were you, I would use

(setq org-format-latex-options
      (cdr '(_ :foreground auto         ; default
               :background default
               :scale 1.5               ; 1.0
               :html-foreground "Black"
               :html-background "Transparent"
               :html-scale 1.0
               :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))))

or

(setq org-format-latex-options (plist-put org-format-latex-options :scale 1.5))
(setq org-format-latex-options (plist-put org-format-latex-options :foreground 'auto))

because I like simple and obvious solutions. As for you question, you can use

(setq org-format-latex-options
      (plist-put (plist-put org-format-latex-options
                            :scale 1.5)
                 :foreground 'auto))

To save more typing, you can define your own plist-put, for example,

(defmacro your-plist-put (plist &rest args)
  (let ((list nil))
    (while args
      (push `(setq ,plist (plist-put ,plist ,(pop args) ,(pop args))) list))
    (cons 'progn (nreverse list))))

then you can use it in this way,

(your-plist-put org-format-latex-options :scale 1.5 :foreground 'auto)

↦

(progn
  (setq org-format-latex-options
        (plist-put org-format-latex-options :scale 1.5))
  (setq org-format-latex-options
        (plist-put org-format-latex-options :foreground 'auto)))
  • What is the benefit of (cdr '(_ ...)) over the more common, and IMO clear, (list ...) or even just '(...)? – Basil Mar 17 '18 at 21:33
  • Note also you can use (macroexp-progn ...) in place of (cons 'progn ...) to forgo the redundant progn in case of a single assignment. – Basil Mar 17 '18 at 21:55
  • @Basil because Emacs doesn't indent plist correctly, that's a work-around. – xuchunyang Mar 18 '18 at 3:44
1

See xuchunyang's for the more canonical and complete answer; the following is merely a somewhat handy trick specific to property lists, for completeness.

Given:

  1. the underlying structure of lists in Elisp;
  2. a non-empty plist variable; and
  3. the destructive nature of plist-put on non-empty lists,

you can modify a plist variable via plist-put directly, without having to reassign its value:

(setq my-plist (list :a 1)) ; my-plist ⇒ (:a 1)
(plist-put my-plist :b 2)   ; my-plist ⇒ (:a 1 :b 2)
(plist-put my-plist :a 3)   ; my-plist ⇒ (:a 3 :b 2)

Contrast this with an empty plist variable:

(setq my-plist ())        ; my-plist ⇒ ()
(plist-put my-plist :b 2) ; my-plist ⇒ ()
(plist-put my-plist :a 3) ; my-plist ⇒ ()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.