Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs-lisp: prettify-symbols-mode for LaTeX

I was trying to port over the "pretty entities" behaviour from org-mode to latex-mode using the Emacs builtin prettify-symbols-mode. This mode uses font-lock-mode to display character sequences in a buffer as a single (unicode) character. By default for instance emacs-lisp code

(lambda () t)

becomes

(λ () t)

It does however seem to require the character sequences to be separated by some characters, e.g. white-spaces. For instance in my setup, the replacement

\alpha \beta -> α β`

will work, but it will fail when the strings are not separated, e.g.

\alpha\beta -> \alphaβ

This is an issue specifically, because I wanted to use this prettification to make quantum mechanical equations more readable, where I e.g. the replacement like

|\psi\rangle -> |ψ⟩

Is it possible to avoid this delimiter-issue using prettify-symbols-mode? And if it is not, is it possible by using font-lock-mode on a lower level?

like image 992
kdb Avatar asked Apr 08 '14 12:04

kdb


People also ask

What is prettify symbols in Emacs?

Prettify Symbols ships with Emacs as of 24.4 and adds support for custom Unicode replacement of symbols. Any combination of these tools may be chosen; Fira Code is not required to utilize prettify-symbols or pretty-mode.

What are pretty-mode and prettify symbols?

Pretty-mode provides Greeks, subscripts, and more symbols. Prettify Symbols ships with Emacs as of 24.4 and adds support for custom Unicode replacement of symbols. Any combination of these tools may be chosen; Fira Code is not required to utilize prettify-symbols or pretty-mode.

How do I add additional symbols to a text file?

Additional symbols can be added through prettify-symbols-alist. Some changes are aggressive, mix and match codes to your taste. The command insert-char, C-x 8 RET prompts for Unicode characters by name and inserts at point. There is also describe-char, M-m h d c which gives information on the character at point.

Why doesn't prettify-symbols work with Subsub/superscripts?

Sub/superscripts, greek letters, and the sigma summation must be manually activated. The :logic group overlaps/interferes with prettify-symbols and is disabled. The :sets group interferes with the int symbol replacement for unknown reasons. We redefine its symbols in prettify-symbols-mode later.


2 Answers

Here's the code that should do what you want:

(defvar pretty-alist
  (cl-pairlis '("alpha" "beta" "gamma" "delta" "epsilon" "zeta" "eta"
                "theta" "iota" "kappa" "lambda" "mu" "nu" "xi"
                "omicron" "pi" "rho" "sigma_final" "sigma" "tau"
                "upsilon" "phi" "chi" "psi" "omega")
              (mapcar
               (lambda (x) (make-char 'greek-iso8859-7 x))
               (number-sequence 97 121))))
(add-to-list 'pretty-alist '("rangle" . ?\⟩))
(defun pretty-things ()
  (mapc
   (lambda (x)
     (let ((word (car x))
           (char (cdr x)))
       (font-lock-add-keywords
        nil
        `((,(concat "\\(^\\|[^a-zA-Z0-9]\\)\\(" word "\\)[a-zA-Z]")
            (0 (progn
                 (decompose-region (match-beginning 2) (match-end 2))
                 nil)))))
       (font-lock-add-keywords
        nil
        `((,(concat "\\(^\\|[^a-zA-Z0-9]\\)\\(" word "\\)[^a-zA-Z]")
            (0 (progn
                 (compose-region (1- (match-beginning 2)) (match-end 2)
                  ,char)
                 nil)))))))
   pretty-alist))

As you can see above, pretty-alist starts out with greek chars. Then I add \rangle just to demonstrate how to add new things. To enable it automatically, add it to the hook:

(add-hook 'LaTeX-mode-hook 'pretty-things)

I used the code from here as a starting point, you can look there for a reference.

like image 61
abo-abo Avatar answered Oct 20 '22 02:10

abo-abo


The code of prettify-symbols-mode derives from code developped for languages like Haskell and a few others, which don't use something like TeX's \. So you may indeed be in trouble. I suggest you M-x report-emacs-bug requesting prettify-symbol-mode be improved to support TeX-style syntax.

In the mean time, you'll have to "do it by hand" along the lines of what abo-abo suggests.

One note, tho: back in the days of Emacs-21, I ported X-Symbol to work on Emacs, specifically because I wanted to see such pretty things in LaTeX. Yet, I discovered that it was mostly useless to me. And I think it's even more the case now. Here's why:

  • You can just use an actual ψ character in your LaTeX code instead of \psi nowadays. So you don't need display tricks for it to look "right".
  • Rather than repeating |\psi\rangle I much prefer defining macros and then use \Qr{\Vangle} (where \Vangle turns into \psi ("V" stands for "metaVariable"), and \Qr wraps it in a braket) so I can easily tweak those macros and know that the document will stay consistent. At that point, pretty-display of \psi and \rangle is of no importance.
like image 31
Stefan Avatar answered Oct 20 '22 04:10

Stefan