Hi, everyone!
I have been trying to add some custom keywords to the search-based
fontification of org-mode, to add some colors to latex fragments, and
I am running into an issue I cannot seem to resolve. I was hoping that
someone might be able to offer some guidance, any insight or suggestion
is greatly appreciated!
SHORT DESCRIPTION
The Goal. I have a custom set of keywords for applying faces to
certain tokens in org latex fragments, and I wish to enforce different
faces according as the fragments are within or outside certain blocks
which I consider “mathematical”.
The Current Problem. So in the matcher of the keyword I have added a check
using org-in-block-p
, which then doesn’t seem to work on the startup of
an org buffer. Some characteristics of this issue:
- As soon as I remove the wrapper around
org-in-block-p
,
the rest of the matcher and in fact the entire fontification
works as intended (apart from the distinct context provided
by the block); in fact, having removed theorg-in-block-p
and
added the keywords to latex-mode, the effect is also as intended. - The predicate
org-in-block-p
and my wrappers around it also work
when I invoke them interactively in isolation; - With the
org-in-block-p
predicate added, however, on startup,
whether my org file is folded or expanded, there is no fontification
at all for any latex fragments, regardless of whether they are inside
one of my list of blocks or outside; - Any subsequent edits after startup are fontified as intended. In particular,
when I modify any text on the same line or in the same block with an existing
fragment even trivially (say by inserting a white space), all the fragments on
the line or in the block get updated fontification, as desired.
These points combined suggest to me that somehow, the interaction between
the predicate org-in-block-p
and the font-lock engine is messed up
precisely on the startup of a file.
DETAILS
The Value of the Keywords
In case this is relevant, the list of keywords I wish to add are stored
in a variable called org-latex-fragment-inblock-kws
, which after evaluation
in IELM prints:
(((lambda
(limit)
(when
(org-inside-math-block-p)
(if
(save-excursion
(and
(re-search-forward "\\\\(" limit t)
(re-search-forward "\\\\)" limit t)))
(progn
(re-search-forward "\\\\)" limit t)
(re-search-backward "\\\\(" nil t)
(re-search-forward "\\\\(" nil t))
nil)))
(0 'latex-math-delim-face prepend)
("\\(\\\\\\)\\([[:alpha:]]+\\)"
(save-excursion
(re-search-forward "\\\\)")
(re-search-backward "\\\\)")
(point))
(progn
(re-search-backward "\\\\(")
(re-search-forward "\\\\("))
(2 'latex-math-cmd-face prepend))
...
... ;; And some more of these anchored highlighters.
... ;; Then finally at the end the highlighter for
... ;; the closing delimiter.
...
("\\\\)"
(save-excursion
(re-search-forward "\\\\)")
(point))
nil
(0 'latex-math-delim-face prepend))))
Here, the whole lambda
chunk is the matcher constructed, and within it
the function org-inside-math-block-p
is just a simple wrapper around
org-in-block-p
which is defined as follows:
(defun org-inside-math-block-p ()
(org-in-block-p org-math-block-list))
Where org-math-block-list
is just a list of strings.
Some Rudimentary Debugging, Hopefully Helpful
I have tried to add a few messages around org-inside-math-block-p
for
some minor debugging, including what-line
, which informs me that at
startup of an org file, the line the point has been at is always 1.
With the same rudimentary messaging behavior wrapped up interactively
around org-inside-math-block-p
, the line number and the detected org
block seem to be correct after startup.
My Own Naive Speculation
Is this related to how org blocks behave at buffer startup, or how
initial fontification is carried out?
Even if the particular behavior of having latex fragments inside
and outside certain blocks fontified differently (and correctly
at startup) cannot be achieved, I should really like to know why,
and possibly learn one thing or two about the font-lock engine
or the internals of org.