Question

I have the following Emacs macro, which evaluates the AucTex command TeX-insert-macro on selected text:

(eval-after-load "latex"
  '(progn
     (define-key LaTeX-mode-map (kbd "C-c (")
       (lambda ()
     (interactive)
     (TeX-insert-macro "command")))))

However, how would I perform a regexp on the selected text and pass that to TeX-insert-macro?

See this question for more details.

For example: Suppose I have the following text:

…as shown in figure (24).

Now, suppose I select "(24)." Then, I want a command to convert it to:

…as shown in figure \command{eq:24}.

Viz., how would I define a new Emacs command that I could place in ~/.emacs that would run C-C RET command RET on a regexp'ed version of the selected text?

Why doesn't the following with regexp work?

(eval-after-load "latex"
  '(progn
     (define-key LaTeX-mode-map (kbd "C-c )")
       (lambda ()
     (interactive)
     (query-replace-regexp "\(([0-9]+)\)" "\1")
     (TeX-insert-macro "eq")
))))

Minor improvement:

This works well if I select, e.g., "(45)" from the left to the right and then run the code by typing C-c )

(eval-after-load "latex"
  '(progn
     (define-key LaTeX-mode-map (kbd "C-c )")
       (lambda ()
     (interactive)
     (exchange-point-and-mark)
     (replace-regexp "[\(\)]" "")
     (TeX-insert-macro "eq")
))))

However, if I select "(45)" from the right to the left, it doesn't work because the point and mark are flipped. Is there a way to make sure the point and mark aren't flipped, such as by running exchange-point-and-mark when they are flipped?

Also, there are other issue with the regexp, e.g., if there are other parentheses nearby it gets greedy.

thanks

Was it helpful?

Solution

I don't have the requisite libraries installed, or know how the TeX functions work, but something like this might do the trick.

(eval-after-load "latex"
  '(progn
     (defun my-insert-latex-command-macro (beginning end)
       (interactive "r")
       (goto-char beginning)
       (when (not (looking-at "(\\(.+?\\))"))
         (error "Region does not match expected pattern."))
       (push-mark)
       (replace-match "eq:\\1")
       (exchange-point-and-mark)
       (TeX-insert-macro "command")
       (goto-char (mark))
       (pop-mark))
     (define-key LaTeX-mode-map (kbd "C-c (") 'my-insert-latex-command-macro)))

Using the "r" argument for interactive conveniently gives you the region boundaries in ascending order, regardless of which direction you marked it in.

To avoid greedy matching in a regexp, use the non-greedy operators (*?, +?, ??).

Note that you do not have sufficient backslash escapes in your regexps. In order to get a backslash into a regexp string in the first place, you first need to account for string escaping. Basically, double the backslashes. e.g.: This:

(query-replace-regexp "\(([0-9]+)\)" "\1")

needs to be this:

(query-replace-regexp "\\(([0-9]+)\\)" "\\1")
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top