I'm writing a lot of LaTeX-files and to improve the process I'm trying to give each environment a background tinge. So I wrote a list of tuples of environment types and faces, daselt-latex-colored-env-list, and I wrote a function font-lock should use to match an environment:
(defun daselt-latex-match-environment (env end)
"This function matches the first LaTeX environment of type env between beg and end."
(let ((match (re-search-forward (format "\\\\begin{%s}\\(\n[ ]*\\\\label{.*}\n\\)?" env) end t))
(env0 (match-end 0)))
(if env0 (progn (condition-case noend (LaTeX-find-matching-end)
(error nil))
(beginning-of-line)
(backward-char)
(set-match-data (list env0 (point)))
match))))
Now I'd like to automatically add this function with its matching face to font-lock-keywords using font-lock-add-keywords and wrote a function that should do that:
(defun daselt-latex-font-lock-add-env-colors ()
"This function adds the environment-color pairs in daselt-latex-colored-env-list to font-lock-keywords."
(interactive)
(mapcar (lambda (envtuple)
(font-lock-add-keywords 'LaTeX-mode
(list (cons
(lambda (end)
(daselt-latex-match-environment (car envtuple) end))
(list '2 (nth 1 envtuple) t t)))))
daselt-latex-colored-env-list))
The trouble is, when I try this out, the function doesn't add, daselt-latex-match-environmentwith first argument fixed to one value, like "align", but it adds ((daselt-latex-match-environment (car envtuple) end)), so that I get an error because envtuple is undefined.
Since this wasn't working I went back to the manual and read that the MATCHER in an entry of font-lock-keywords should be the name of a function, not a function itself. Since I never got that far I'm not sure whether this would have been a problem, but I tried to write a function that automatically generates all functions I need as named functions:
(mapcar (lambda (envtuple)
(let (env (car envtuple))
(defun (intern (format "daselt-latex-font-lock-match-%s" env)) (beg end)
(format "Function to match environments of type %n for font-lock." env)
(lambda (beg end) (daselt-latex-match-environment env beg end)))))
daselt-latex-colored-env-list)
But this doesn't work either because it doesn't evaluate (intern (format "daselt-latex-font-lock-match-%s" env)), so I get an error message because defun wants a symbol as its first argument. Though those two approaches are different, the core problem is roughly the same which is that macros don't expand their arguments, so how do I use them to create new functions by fixing an argument of a base function?