Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top