12

I'm using spacemacs with AUCTeX for LaTeX editing and would like to make rainbow-delimiters and/or rainbow-blocks highlight LaTeX math equations. Unfortunately this only works partly, i.e., some equations get highlighted and some don't:

Example: rainbow-delimiters

In the example screenshot, in-line math enclosed in $ does not get highlighted while the rest - including in-line math enclosed in \(...\) - does.

With rainbow-blocks it gets worse, as it will sometimes work in one place of the document and sometimes won't work regardless of scope.

Example: rainbow-blocks

Q: Does anyone know why this happens or how to get rainbow-blocks working for in-line math in LaTeX? Are there any working alternatives?

itsjeyd
  • 14,586
  • 3
  • 58
  • 87
nemesit
  • 291
  • 1
  • 5
  • latex-mode in auctex seems to define "$" to have special syntax in the syntax-table, so perhaps font-lock's syntactic fontification is overriding any keyword-based fontification. – Kirill Dec 11 '14 at 05:05
  • `highlight-parentheses` uses overlays instead of font lock, and it would be a very simple thing to use a temporary syntax-table for the duration of the overlay function. https://github.com/nschum/highlight-parentheses.el The function that would need to be altered in that library is `hl-paren-highlight`: `(let ((my-syntax-table (make-syntax-table))) (with-syntax-table my-syntax-table . . .` Unfortunately, that is another library than the one you have specified -- I do not know how to fix `rainbow-delimiters` -- perhaps you could open up an issue on Github with the maintainer. – lawlist Jan 13 '15 at 10:27
  • Using `(with-silent-modifications (remove-text-properties (region-beginning) (region-end) '(face nil font-lock-face nil)) (add-text-properties (region-beginning) (region-end) '(face rainbow-delimiters-depth-1-face)))` it is possible to replace the fontification within an embedded formula. But this does not work in an around advice of `rainbow-delimiters-propertize-delimiter`. This indicates that the fontification of `latex-mode` takes place after the fontification through `rainbow-delimiters-mode`. – Tobias May 24 '15 at 00:03
  • rainbow-delimiters uses jit-lock directly. Maybe, syntactic fontification does not use jit-lock and we get a timing problem because of that? – Tobias May 24 '15 at 00:11

1 Answers1

2

The following is more like a comment since

  1. it solves only to a small part of the problem (rainbow-delimiters-mode)
  2. it is not thoroughly tested (just with one latex-file)
  3. I do not completely understand why it works (font-lock-mode is really quite a complicated machinery)

At first the solution for rainbow-delimiters-mode:

We replace the text property font-lock-face by face in rainbow-delimiters-propertize-delimiter and rainbow-delimiters-unpropertize-delimiter. Since defsubst is used in the package instead of defun we cannot employ defalias but must modify the functions themselves (as far as I understand it -- please comment if I am wrong in this regard).

The modified functions are:

(defsubst rainbow-delimiters-propertize-delimiter (loc depth)
  "Highlight a single delimiter at LOC according to DEPTH.

LOC is the location of the character to add text properties to.
DEPTH is the nested depth at LOC, which determines the face to use.

Sets text properties:
`font-lock-face' to the appropriate delimiter face.
`rear-nonsticky' to prevent color from bleeding into subsequent characters typed by the user."
  (with-silent-modifications
    (let ((delim-face (if (<= depth 0)
                          'rainbow-delimiters-unmatched-face
                        (rainbow-delimiters-depth-face depth))))
      ;; (when (eq depth -1) (message "Unmatched delimiter at char %s." loc))
      (add-text-properties loc (1+ loc)
               ;; 2015-05-24: Changed font-lock-face to face to enable rainbow after syntax fontification in latex-mode
               ;; (see http://emacs.stackexchange.com/questions/4260/how-to-get-rainbow-delimiters-rainbow-blocks-to-highlight-in-line-math-in-latex)
                           `(face ,delim-face
                             rear-nonsticky t)))))


(defsubst rainbow-delimiters-unpropertize-delimiter (loc)
  "Remove text properties set by rainbow-delimiters mode from char at LOC."
  (with-silent-modifications
    (remove-text-properties loc (1+ loc)
                ;; 2015-05-24: See corresponding line in `rainbow-delimiters-propertize-delimiter'.
                            '(face nil
                              rear-nonsticky nil))))

Now the reasoning:

The embedded formulas between the $-delimiters are syntax fontified by font-lock-mode (as already Kirill pointed out). The registration of this fontification looks normal (see variable font-lock-syntactic-face-function and function font-latex-syntactic-face-function). But describe-char at the characters of an embedded formula shows that syntactic fontification uses the face-property instead of the font-lock-face-property.

The following is hypothetical since I do not completely understand the font-lock machinery which is quite complex.

It seems that face is stronger than font-lock-face. Rainbow-delimiters uses font-lock-face which is dominated by face of syntactic fontification. Nevertheless, we have the advantage that syntactic fontification comes first before search (keyword) based fontification which in turn uses jit-lock (see info-pages of font-lock-mode).

That leads me to the conclusion that the problem is solved if we use face in rainbow-delimiters instead of font-lock-face. And here I do not know the full consequences. But, since rainbow-delimiters also uses jit-lock directly (and not through font-lock-mode) we are standing on a shaky floor anyway.

Note, that I had already some contact with rainbow-delimiters (see https://stackoverflow.com/questions/19800243/highlight-first-mismatching-paren/20022030#20022030) but not with rainbow-blocks. Because I have only a limited frame of time I chose to concentrate on rainbow-delimiters. Maybe, you can solve the rainbow-blocks-problem in a similar way.

Tobias
  • 32,569
  • 1
  • 34
  • 75