# Smarter and more efficient way to add font lock keywords to org-mode?

I really hate looking at raw markup in org-mode documents, so I am trying to replace as much of it with symbols as possible.

So #=begin_ becomes {, src becomes some-glyph etc.

My current approach is to just list a bunch of regexes for each case:

(font-lock-add-keywords
'org-mode (("^\s*\\#\\+BEGIN_\$$QUOTE\$$ "
(1 (progn (compose-region (match-beginning 1) (match-end 1) "")
nil)))
("^\s*\\#\\+END\$$QUOTE\$$ "
(1 (progn (compose-region (match-beginning 1) (match-end 1) "")
nil)))
("^\s*\$$\\#\\+BEGIN_\$$[:alpha:]"
(1 (progn (compose-region (match-beginning 1) (match-end 1) "{")
nil)))
("^\s*\$$\\#\\+END_\$$[:alpha:]"
(1 (progn (compose-region (match-beginning 1) (match-end 1) "}")
nil)))


I wish I knew elisp better to refactor this but I don't. With this approach, you're searching for related syntax elements separately. It seems like it would be much more efficient to first look for an occurrences of #+begin_, replace them with {, then search forward for words like src, quote, comment etc.

I am not sure yet what the performance implications of this are for longer documents (perhaps someone will enlighten me), but I'd like to get off too a good start. Some interesting stuff on font-locking here by @lunaryorn, but it's totally over my head at the moment, and it seems to be about writing new major modes, instead of augmenting the font-locking in org-mode.

• org-mode is too complicated for anyone to try and add font-lock keywords except as to portions of the buffer that are never touched by org-mode rules and so forth. If any portion of the buffer that is touched by org-mode needs modification, then it is almost certainly better to find the location of code within org-mode and modify it directly. In other words, the premise of using font-lock-add-keywords to answer this question is not a good approach unless one is certain that org-mode never touches that area of the buffer. org-mode touches areas of the buffer in a specific order ... – lawlist Jul 15 '17 at 7:10
• oh god, i hope it's not that bad. what's org-font-lock-hook all about? – user27636 Jul 15 '17 at 23:04
• You've already launched the bounty, so go ahead and let it fly its course -- perhaps someone will come with a unique universal approach and I can "eat my hat". When the bounty ends, consider launching a new question that seeks a specific result without restricting the answer to a general approach using things like font-lock-add-keywords. That will enable someone to dig into the applicable code, and suggest a precise solution. org-mode is under constant development, and people use old versions, current versions, etc. -- so be sure to state the particular version you are using. – lawlist Jul 16 '17 at 0:15

It looks like you want to only specify the regexp and the string,
so just write a little function to add all the rest.

(defun myfun (regexp str)
(,regexp (1 (progn (compose-region
(match-beginning 1) (match-end 1) ,str) nil))))


Then you can use it in your expression:

(font-lock-add-keywords
'org-mode (,(myfun "^\s*\\#\\+BEGIN_\$$QUOTE\$$ "     "")
,(myfun "^\s*\\#\\+END\$$QUOTE\$$ "        "")
,(myfun "^\s*\$$\\#\\+BEGIN_\$$[:alpha:]"  "{")
,(myfun "^\s*\$$\\#\\+END_\$$[:alpha:]"    "}") ))


Still pretty ugly... what you really want to do is

(MY-simple-font-lock-add-keywords
'org-mode '(("^\s*\\#\\+BEGIN_\$$QUOTE\$$ "     "")
("^\s*\\#\\+END\$$QUOTE\$$ "        "")
("^\s*\$$\\#\\+BEGIN_\$$[:alpha:]"  "{")
("^\s*\$$\\#\\+END_\$$[:alpha:]"    "}")))


The parentheses on each line might seem annoying, and you could get rid of them (change this code below) but they keep things straight.

(defun MY-simple-font-lock-add-keywords (mode list-regexp-str)
`