2

I'm trying to make a font lock hook to replace strings of text for a mathmatical notation plugin.

So I'm thinking " / " (note the spaces) will turn into " ÷ ", but "/" won't. (It's a package mainly for R statistical language.)

I'm playing with the examples from the manual and I can't even get that to work. I was trying to get the word FIXIT to change font color.

(add-hook 'emacs-lisp-mode-hook
        (lambda ()
        (font-lock-add-keywords nil
            '(("\\<\\(FIXIT\\):" 1
            font-lock-warning-face t)))))

I don't even fully understand the syntax since I'm just getting used to Lisp. Does it use a RegEx to identify strings? and if so, what RegEx engine?

I was hoping it would change the font color, but it didn't... but again, that was just me playing with it trying to understand it, not the end goal. The end result would be the first thing I mentioned: to change math symbols (" / " into " ÷ ").

4
  • 2
    You might want to take a look at prettify-symbols-mode.
    – user12563
    Feb 17, 2019 at 22:04
  • Re: "if so, what RegEx engine", see gnu.org/software/emacs/manual/html_node/elisp/… . Emacs regexp syntax is similar to BRE syntax, along with various custom features.
    – phils
    Feb 17, 2019 at 22:28
  • emacswiki.org/emacs/CategoryRegexp and emacs.stackexchange.com/q/5568 might be useful.
    – phils
    Feb 17, 2019 at 22:33
  • @DoMiNeLa10 , yes, I'm primarily using prettify-symbols-mode for this but for certain items I need something more powerful, as prettify-symbols-mode only allows one symbol. So if I need to replace a string of symbols, p-s mode only allows one (as far as i know.) I also would like to italicize variables as is generally done in mathematical notation (ie: x )
    – Chris
    Feb 18, 2019 at 16:41

1 Answer 1

4

Here's a code snippet that will make all occurrences of " / " appear as " ÷ " in the current buffer:

(add-to-list 'font-lock-extra-managed-props 'display)
(font-lock-add-keywords nil
 '((" \\(/\\) " 1 '(face nil display "÷"))))

The first line makes font-lock manage the display property of text, so that it removes the property when a piece of text no longer matches the keyword.

Let's break down what (" \\(/\\) " 1 '(face nil display "÷")) means:

  • " \\(/\\) " is an emacs regex that matches only the sequence  /  (space-slash-space), and captures the / -- that's what the escaped parentheses (\\( and \\)) are for.

  • 1 says that we want to modify the properties of text captured in the first group. In our case, we want to change the display property of only the / character, not the surrounding spaces. That's why we capture it in the regex. If we wanted to change the properties of the entire matched text, we would put 0 in place of 1.

  • '(face nil display "÷") specifies the properties that we want applied to the / character. We only want to set the display property, not the face property, but the function requires us to specify face, so we specify it as nil. The effect is that font-lock won't change the face property of matching text. We then set the display property to "÷", so the / character will be displayed as ÷.

More about font-lock keywords: https://www.gnu.org/software/emacs/manual/html_node/elisp/Search_002dbased-Fontification.html

More about the display property: https://www.gnu.org/software/emacs/manual/html_node/elisp/Display-Property.html#Display-Property (the code above uses a replacing spec)

4
  • Oh I'm sorry, the " wasn't part of the String... I just put that there because StackExcange collapses the whitespace around the symbols when they're in code brackets. See: ` / ` (i just typed that with 10 white space characters surrounding) Anyway the string is " / " -> " ÷ " all spaces as is. What's the emacs regex for that? But besides that this answer is exactly what I needed. Thanks!
    – Chris
    Feb 19, 2019 at 0:12
  • The regex " \\(/\\) " matches the sequence space-slash-space. The escaped parentheses (\\( and \\)) are used to capture the / character, as this is the only character in the regex that we want to change the display of.
    – jpi
    Feb 19, 2019 at 7:28
  • So the code you posted would find " / " or "" / "" (ignore the first set of parentheses in both cases.)
    – Chris
    Feb 19, 2019 at 18:23
  • It will find " / ".
    – jpi
    Feb 19, 2019 at 18:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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