2013-11-07 3 views
2

Я хотел бы заменить все вхождения буквы «n», которые встречаются внутри любого уравнения LaTeX, с буквой «N». Можно предположить, что уравнения LaTeX в документе имеют форму $ ... $Emacs regex: замена строки внутри уравнения латекса

Примут также решения в perl или любом другом языке/инструменте/приложении, которые легко доступны на ubuntu или Windows.

ответ

4

В emacs мы можем использовать hightighting of auctex для замены строки в всех математических средах. (Я знаю, что это отклоняется от вопроса. Но, возможно, это еще более полезно.) После запуска кода ниже нажмите M-x latex-replace-in-math и введите исходное регулярное выражение, например \<n\>, а затем введите свою заменяющую строку, такую ​​как N. Если вы сохранили пробелы между именами переменных, то \<n\> лучше, чем просто n еще и \sin будет заменен на \siN, что, вероятно, не то, что вы хотите. Но это также не так много проблем с кодом ниже, поскольку он заменяет запрос, и вы можете пропускать ненужные замены, нажимая `n '.

Обратите внимание, что если вы хотите заменить чувствительный к регистру, вы должны деактивировать Функции → Игнорировать регистр для поиска.

Пользователь cgogolin дал мне новую идею с его ответом.

Мой новый предпочтительным решением является:

(fset 'latex-replace-in-math 
     `(lambda (regexp to-string &optional delimited start end backward) 
    "Like `query-replace-regexp' but only replaces in LaTeX-math environments." 
    ,(interactive-form 'query-replace-regexp) 
    (let ((replace-re-search-function (lambda (regexp bound noerror) 
         (catch :found 
          (while (let ((ret (re-search-forward regexp bound noerror))) 
          (when (save-match-data (texmathp)) (throw :found ret)) 
          ret)))))) 
     (query-replace-regexp regexp to-string delimited start end backward)))) 

Бывший более сложная версия была:

(defun latex-in-math (pos) 
    "Check whether pos is in math environment." 
    (let ((face (plist-get (text-properties-at pos) 'face))) 
    (or (eq face 'font-latex-math-face) 
    (and (listp face) 
     (memq 'font-latex-math-face face))))) 

(defun latex-next-math-change (&optional bound stay) 
    "Starting at point search for next beginning of math environment. 
Place point there if STAY is nil and return point. 
Else leave point where it was and return nil." 
    (let ((b (point)) 
    (inMathB (latex-in-math (point))) 
    inMath) 
    (catch :found 
     (while (setq b (next-single-property-change b 'face nil bound)) 
    (setq inMath (latex-in-math b)) 
    (when (or (and inMathB (null inMath)) 
      (and (null inMathB) inMath)) 
     (unless stay (goto-char b)) 
     (throw :found b)))))) 

(defun latex-replace-in-math (src tgt &optional bound) 
    "In all math-environments replace SRC with TGT." 
    (interactive (list (read-regexp "Source regular expression:") 
      (read-string "Target string:"))) 
    (save-excursion 
    (font-lock-fontify-region (point) (point-max))) 
    (catch 'quit 
    (let (b e repl) 
     (when (latex-in-math (point)) 
    (error "point-min should not be in math environment")) 
     (while (setq b (latex-next-math-change bound)) 
    (goto-char b) 
    (while (search-forward-regexp src (latex-next-math-change bound t) 'noErr) 
     (unless (eq repl 'all) 
     (let ((ol (make-overlay (match-beginning 0) (match-end 0)))) 
      (overlay-put ol 'face 'query-replace) 
      (while (null 
       (eval (cdr (assq (read-char "y: replace, n: don't, q: quit, !: replace all" '(?y ?n ?q ?!)) 
         '((?y . (setq repl t)) 
        (?n . (setq repl 'no)) 
        (?q . (setq repl 'quit)) 
        (?! . (setq repl 'all)))))))) 
      (delete-overlay ol)) 
     (when (eq repl 'quit) 
      (throw 'quit nil))) 
     (unless (eq repl 'no) 
     (replace-match tgt))))))) 
+0

Спасибо. Я дал вам предварительный голос, но я не буду отмечать ваш ответ как «Ответ», поскольку для меня это слишком сложно понять (из-за моей собственной незнакомости с Lisp). Я думаю, что буду придерживаться подхода грубой силы и выполнить ручную поиск и замену. –

+0

На самом деле ничего не понять. Просто скопируйте материал в файл конфигурации (скорее всего, '.emacs' в вашем домашнем каталоге). Затем материал запускается при запуске emacs. После этого вы получите новую команду «latex-replace-in-math». Вы можете вызвать эту команду нажатием клавиши M-x, затем введите в минибайер 'latex-replace-in-math'. Затем emacs просит вас заменить регулярное выражение и строку подстановки. Некоторые из его преимуществ: поиск всех математических сред. Замечания не затрагиваются (возможно, у вас есть комментарий '% was $ n $'. Вы не захотите его заменять. – Tobias

+0

Обратите также внимание на то, что команда 'latex-replace-in-math' должна запускаться в' latex- mode' from auctex.Но это стандартно, если вы открываете LaTeX-файлы. – Tobias

2

Столкнувшись с проблемами, описанными в моем комментарии к ответу Тобиаса, я решил эту проблему, добавив две функции query-replace-tex-math-regexp и perform-replace-tex-math к моему .emacs, которые работают следующим образом:

Функция query-replace-tex-math-regexp является по существу только дословная копия query-replace-regexp, только что он называет perform-replace-tex-math вместо perform-replace в последней строке и perform-replace-tex-math является лишь слегка модифицированная версия perform-replace с блоком

;; filter out matches not in math mode. 
((not (texmathp)) 
(setq skip-filtered-count (1+ skip-filtered-count))) 

добавляют непосредственно перед линией

;; Optionally ignore invisible matches. 

texmathp определен в AucTeX и испытания s находится ли курсор в математической среде, как я узнал из here.

(Код для оригинальных функций, которые под лицензией GNU General Public License, можно найти here.)

Полный код в моем .emacs выглядит следующим образом:

(defun query-replace-tex-math-regexp (regexp to-string &optional delimited start end backward) 
    "Replace some things after point matching REGEXP with TO-STRING, but only in AucTeX math mode. 
As each match is found, the user must type a character saying 
what to do with it. For directions, type \\[help-command] at that time. 

In Transient Mark mode, if the mark is active, operate on the contents 
of the region. Otherwise, operate from point to the end of the buffer. 

Use \\<minibuffer-local-map>\\[next-history-element] \ 
to pull the last incremental search regexp to the minibuffer 
that reads REGEXP, or invoke replacements from 
incremental search with a key sequence like `C-M-s C-M-s C-M-%' 
to use its current search regexp as the regexp to replace. 

Matching is independent of case if `case-fold-search' is non-nil and 
REGEXP has no uppercase letters. Replacement transfers the case 
pattern of the old text to the new text, if `case-replace' and 
`case-fold-search' are non-nil and REGEXP has no uppercase letters. 
\(Transferring the case pattern means that if the old text matched is 
all caps, or capitalized, then its replacement is upcased or 
capitalized.) 

Ignore read-only matches if `query-replace-skip-read-only' is non-nil, 
ignore hidden matches if `search-invisible' is nil, and ignore more 
matches using `isearch-filter-predicate'. 

If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp 
to be replaced will match a sequence of whitespace chars defined by the 
regexp in `search-whitespace-regexp'. 

Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace 
only matches surrounded by word boundaries. A negative prefix arg means 
replace backward. 

Fourth and fifth arg START and END specify the region to operate on. 

In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, 
and `\\=\\N' (where N is a digit) stands for 
whatever what matched the Nth `\\(...\\)' in REGEXP. 
`\\?' lets you edit the replacement text in the minibuffer 
at the given position for each replacement. 

In interactive calls, the replacement text can contain `\\,' 
followed by a Lisp expression. Each 
replacement evaluates that expression to compute the replacement 
string. Inside of that expression, `\\&' is a string denoting the 
whole match as a string, `\\N' for a partial match, `\\#&' and `\\#N' 
for the whole or a partial match converted to a number with 
`string-to-number', and `\\#' itself for the number of replacements 
done so far (starting with zero). 

If the replacement expression is a symbol, write a space after it 
to terminate it. One space there, if any, will be discarded. 

When using those Lisp features interactively in the replacement 
text, TO-STRING is actually made a list instead of a string. 
Use \\[repeat-complex-command] after this command for details." 
    (interactive 
    (let ((common 
     (query-replace-read-args 
     (concat "Query replace" 
      (if current-prefix-arg 
       (if (eq current-prefix-arg '-) " backward" " word") 
      "") 
      " regexp" 
      (if (and transient-mark-mode mark-active) " in region" "")) 
     t))) 
    (list (nth 0 common) (nth 1 common) (nth 2 common) 
     ;; These are done separately here 
     ;; so that command-history will record these expressions 
     ;; rather than the values they had this time. 
     (if (and transient-mark-mode mark-active) 
      (region-beginning)) 
     (if (and transient-mark-mode mark-active) 
      (region-end)) 
     (nth 3 common)))) 
    (perform-replace-tex-math regexp to-string t t delimited nil nil start end backward)) 





(defun perform-replace-tex-math (from-string replacements 
       query-flag regexp-flag delimited-flag 
      &optional repeat-count map start end backward) 
    "Subroutine of `query-replace'. Its complexity handles interactive queries. 
Don't use this in your own program unless you want to query and set the mark 
just as `query-replace' does. Instead, write a simple loop like this: 

    (while (re-search-forward \"foo[ \\t]+bar\" nil t) 
    (replace-match \"foobar\" nil nil)) 

which will run faster and probably do exactly what you want. Please 
see the documentation of `replace-match' to find out how to simulate 
`case-replace'. 

This function returns nil if and only if there were no matches to 
make, or the user didn't cancel the call." 
    (or map (setq map query-replace-map)) 
    (and query-flag minibuffer-auto-raise 
     (raise-frame (window-frame (minibuffer-window)))) 
    (let* ((case-fold-search 
     (if (and case-fold-search search-upper-case) 
      (isearch-no-upper-case-p from-string regexp-flag) 
     case-fold-search)) 
     (nocasify (not (and case-replace case-fold-search))) 
     (literal (or (not regexp-flag) (eq regexp-flag 'literal))) 
     (search-string from-string) 
     (real-match-data nil)  ; The match data for the current match. 
     (next-replacement nil) 
     ;; This is non-nil if we know there is nothing for the user 
     ;; to edit in the replacement. 
     (noedit nil) 
     (keep-going t) 
     (stack nil) 
     (replace-count 0) 
     (skip-read-only-count 0) 
     (skip-filtered-count 0) 
     (skip-invisible-count 0) 
     (nonempty-match nil) 
    (multi-buffer nil) 
    (recenter-last-op nil) ; Start cycling order with initial position. 

     ;; If non-nil, it is marker saying where in the buffer to stop. 
     (limit nil) 

     ;; Data for the next match. If a cons, it has the same format as 
     ;; (match-data); otherwise it is t if a match is possible at point. 
     (match-again t) 

     (message 
      (if query-flag 
       (apply 'propertize 
        (substitute-command-keys 
         "Query replacing %s with %s: (\\<query-replace-map>\\[help] for help) ") 
        minibuffer-prompt-properties)))) 

    ;; If region is active, in Transient Mark mode, operate on region. 
    (if backward 
    (when end 
     (setq limit (copy-marker (min start end))) 
     (goto-char (max start end)) 
     (deactivate-mark)) 
     (when start 
    (setq limit (copy-marker (max start end))) 
    (goto-char (min start end)) 
    (deactivate-mark))) 

    ;; If last typed key in previous call of multi-buffer perform-replace 
    ;; was `automatic-all', don't ask more questions in next files 
    (when (eq (lookup-key map (vector last-input-event)) 'automatic-all) 
     (setq query-flag nil multi-buffer t)) 

    ;; REPLACEMENTS is either a string, a list of strings, or a cons cell 
    ;; containing a function and its first argument. The function is 
    ;; called to generate each replacement like this: 
    ;; (funcall (car replacements) (cdr replacements) replace-count) 
    ;; It must return a string. 
    (cond 
    ((stringp replacements) 
     (setq next-replacement replacements 
      replacements  nil)) 
    ((stringp (car replacements)) ; If it isn't a string, it must be a cons 
     (or repeat-count (setq repeat-count 1)) 
     (setq replacements (cons 'replace-loop-through-replacements 
           (vector repeat-count repeat-count 
             replacements replacements))))) 

    (when query-replace-lazy-highlight 
     (setq isearch-lazy-highlight-last-string nil)) 

    (push-mark) 
    (undo-boundary) 
    (unwind-protect 
    ;; Loop finding occurrences that perhaps should be replaced. 
    (while (and keep-going 
      (if backward 
      (not (or (bobp) (and limit (<= (point) limit)))) 
       (not (or (eobp) (and limit (>= (point) limit))))) 
      ;; Use the next match if it is already known; 
      ;; otherwise, search for a match after moving forward 
      ;; one char if progress is required. 
      (setq real-match-data 
       (cond ((consp match-again) 
       (goto-char (if backward 
         (nth 0 match-again) 
          (nth 1 match-again))) 
       (replace-match-data 
        t real-match-data match-again)) 
       ;; MATCH-AGAIN non-nil means accept an 
       ;; adjacent match. 
       (match-again 
       (and 
        (replace-search search-string limit 
          regexp-flag delimited-flag 
          case-fold-search backward) 
        ;; For speed, use only integers and 
        ;; reuse the list used last time. 
        (replace-match-data t real-match-data))) 
       ((and (if backward 
         (> (1- (point)) (point-min)) 
        (< (1+ (point)) (point-max))) 
         (or (null limit) 
         (if backward 
          (> (1- (point)) limit) 
         (< (1+ (point)) limit)))) 
       ;; If not accepting adjacent matches, 
       ;; move one char to the right before 
       ;; searching again. Undo the motion 
       ;; if the search fails. 
       (let ((opoint (point))) 
        (forward-char (if backward -1 1)) 
        (if (replace-search search-string limit 
           regexp-flag delimited-flag 
           case-fold-search backward) 
         (replace-match-data 
        t real-match-data) 
        (goto-char opoint) 
        nil)))))) 

     ;; Record whether the match is nonempty, to avoid an infinite loop 
     ;; repeatedly matching the same empty string. 
     (setq nonempty-match 
     (/= (nth 0 real-match-data) (nth 1 real-match-data))) 

     ;; If the match is empty, record that the next one can't be 
     ;; adjacent. 

     ;; Otherwise, if matching a regular expression, do the next 
     ;; match now, since the replacement for this match may 
     ;; affect whether the next match is adjacent to this one. 
     ;; If that match is empty, don't use it. 
     (setq match-again 
     (and nonempty-match 
      (or (not regexp-flag) 
      (and (if backward 
        (looking-back search-string) 
       (looking-at search-string)) 
        (let ((match (match-data))) 
       (and (/= (nth 0 match) (nth 1 match)) 
        match)))))) 

     (cond 
     ;; Optionally ignore matches that have a read-only property. 
     ((not (or (not query-replace-skip-read-only) 
      (not (text-property-not-all 
       (nth 0 real-match-data) (nth 1 real-match-data) 
       'read-only nil)))) 
     (setq skip-read-only-count (1+ skip-read-only-count))) 
     ;; Optionally filter out matches. 
     ((not (funcall isearch-filter-predicate 
          (nth 0 real-match-data) (nth 1 real-match-data))) 
     (setq skip-filtered-count (1+ skip-filtered-count))) 
     ;; filter out matches not in math mode. 
     ((not (texmathp)) 
     (setq skip-filtered-count (1+ skip-filtered-count))) 
     ;; Optionally ignore invisible matches. 
     ((not (or (eq search-invisible t) 
      ;; Don't open overlays for automatic replacements. 
      (and (not query-flag) search-invisible) 
      ;; Open hidden overlays for interactive replacements. 
      (not (isearch-range-invisible 
       (nth 0 real-match-data) (nth 1 real-match-data))))) 
     (setq skip-invisible-count (1+ skip-invisible-count))) 
     (t 
     ;; Calculate the replacement string, if necessary. 
     (when replacements 
      (set-match-data real-match-data) 
      (setq next-replacement 
      (funcall (car replacements) (cdr replacements) 
       replace-count))) 
     (if (not query-flag) 
     (progn 
      (unless (or literal noedit) 
      (replace-highlight 
      (nth 0 real-match-data) (nth 1 real-match-data) 
      start end search-string 
      regexp-flag delimited-flag case-fold-search backward)) 
      (setq noedit 
      (replace-match-maybe-edit 
      next-replacement nocasify literal 
      noedit real-match-data backward) 
      replace-count (1+ replace-count))) 
      (undo-boundary) 
      (let (done replaced key def) 
     ;; Loop reading commands until one of them sets done, 
     ;; which means it has finished handling this 
     ;; occurrence. Any command that sets `done' should 
     ;; leave behind proper match data for the stack. 
     ;; Commands not setting `done' need to adjust 
     ;; `real-match-data'. 
     (while (not done) 
      (set-match-data real-match-data) 
      (replace-highlight 
      (match-beginning 0) (match-end 0) 
      start end search-string 
      regexp-flag delimited-flag case-fold-search backward) 
      ;; Bind message-log-max so we don't fill up the message log 
      ;; with a bunch of identical messages. 
      (let ((message-log-max nil) 
      (replacement-presentation 
      (if query-replace-show-replacement 
       (save-match-data 
        (set-match-data real-match-data) 
        (match-substitute-replacement next-replacement 
           nocasify literal)) 
       next-replacement))) 
      (message message 
          (query-replace-descr from-string) 
          (query-replace-descr replacement-presentation))) 
      (setq key (read-event)) 
      ;; Necessary in case something happens during read-event 
      ;; that clobbers the match data. 
      (set-match-data real-match-data) 
      (setq key (vector key)) 
      (setq def (lookup-key map key)) 
      ;; Restore the match data while we process the command. 
      (cond ((eq def 'help) 
      (with-output-to-temp-buffer "*Help*" 
       (princ 
       (concat "Query replacing " 
        (if delimited-flag 
        (or (and (symbolp delimited-flag) 
         (get delimited-flag 'isearch-message-prefix)) 
         "word ") "") 
        (if regexp-flag "regexp " "") 
        (if backward "backward " "") 
        from-string " with " 
        next-replacement ".\n\n" 
        (substitute-command-keys 
        query-replace-help))) 
       (with-current-buffer standard-output 
       (help-mode)))) 
      ((eq def 'exit) 
      (setq keep-going nil) 
      (setq done t)) 
      ((eq def 'exit-current) 
      (setq multi-buffer t keep-going nil done t)) 
      ((eq def 'backup) 
      (if stack 
       (let ((elt (pop stack))) 
        (goto-char (nth 0 elt)) 
        (setq replaced (nth 1 elt) 
        real-match-data 
        (replace-match-data 
         t real-match-data 
         (nth 2 elt)))) 
       (message "No previous match") 
       (ding 'no-terminate) 
       (sit-for 1))) 
      ((eq def 'act) 
      (or replaced 
       (setq noedit 
        (replace-match-maybe-edit 
        next-replacement nocasify literal 
        noedit real-match-data backward) 
        replace-count (1+ replace-count))) 
      (setq done t replaced t)) 
      ((eq def 'act-and-exit) 
      (or replaced 
       (setq noedit 
        (replace-match-maybe-edit 
        next-replacement nocasify literal 
        noedit real-match-data backward) 
        replace-count (1+ replace-count))) 
      (setq keep-going nil) 
      (setq done t replaced t)) 
      ((eq def 'act-and-show) 
      (if (not replaced) 
       (setq noedit 
        (replace-match-maybe-edit 
        next-replacement nocasify literal 
        noedit real-match-data backward) 
        replace-count (1+ replace-count) 
        real-match-data (replace-match-data 
          t real-match-data) 
        replaced t))) 
      ((or (eq def 'automatic) (eq def 'automatic-all)) 
      (or replaced 
       (setq noedit 
        (replace-match-maybe-edit 
        next-replacement nocasify literal 
        noedit real-match-data backward) 
        replace-count (1+ replace-count))) 
      (setq done t query-flag nil replaced t) 
      (if (eq def 'automatic-all) (setq multi-buffer t))) 
      ((eq def 'skip) 
      (setq done t)) 
      ((eq def 'recenter) 
      ;; `this-command' has the value `query-replace', 
      ;; so we need to bind it to `recenter-top-bottom' 
      ;; to allow it to detect a sequence of `C-l'. 
      (let ((this-command 'recenter-top-bottom) 
        (last-command 'recenter-top-bottom)) 
       (recenter-top-bottom))) 
      ((eq def 'edit) 
      (let ((opos (point-marker))) 
       (setq real-match-data (replace-match-data 
          nil real-match-data 
          real-match-data)) 
       (goto-char (match-beginning 0)) 
       (save-excursion 
       (save-window-excursion 
        (recursive-edit))) 
       (goto-char opos) 
       (set-marker opos nil)) 
      ;; Before we make the replacement, 
      ;; decide whether the search string 
      ;; can match again just after this match. 
      (if (and regexp-flag nonempty-match) 
       (setq match-again (and (looking-at search-string) 
          (match-data))))) 
      ;; Edit replacement. 
      ((eq def 'edit-replacement) 
      (setq real-match-data (replace-match-data 
         nil real-match-data 
         real-match-data) 
        next-replacement 
        (read-string "Edit replacement string: " 
              next-replacement) 
        noedit nil) 
      (if replaced 
       (set-match-data real-match-data) 
       (setq noedit 
       (replace-match-maybe-edit 
        next-replacement nocasify literal noedit 
        real-match-data backward) 
       replaced t)) 
      (setq done t)) 

      ((eq def 'delete-and-edit) 
      (replace-match "" t t) 
      (setq real-match-data (replace-match-data 
         nil real-match-data)) 
      (replace-dehighlight) 
      (save-excursion (recursive-edit)) 
      (setq replaced t)) 
      ;; Note: we do not need to treat `exit-prefix' 
      ;; specially here, since we reread 
      ;; any unrecognized character. 
      (t 
      (setq this-command 'mode-exited) 
      (setq keep-going nil) 
      (setq unread-command-events 
        (append (listify-key-sequence key) 
         unread-command-events)) 
      (setq done t))) 
      (when query-replace-lazy-highlight 
      ;; Force lazy rehighlighting only after replacements. 
      (if (not (memq def '(skip backup))) 
      (setq isearch-lazy-highlight-last-string nil))) 
      (unless (eq def 'recenter) 
      ;; Reset recenter cycling order to initial position. 
      (setq recenter-last-op nil))) 
     ;; Record previous position for^when we move on. 
     ;; Change markers to numbers in the match data 
     ;; since lots of markers slow down editing. 
     (push (list (point) replaced 
;;; If the replacement has already happened, all we need is the 
;;; current match start and end. We could get this with a trivial 
;;; match like 
;;; (save-excursion (goto-char (match-beginning 0)) 
;;;   (search-forward (match-string 0)) 
;;;     (match-data t)) 
;;; if we really wanted to avoid manually constructing match data. 
;;; Adding current-buffer is necessary so that match-data calls can 
;;; return markers which are appropriate for editing. 
       (if replaced 
       (list 
       (match-beginning 0) 
       (match-end 0) 
       (current-buffer)) 
        (match-data t))) 
       stack)))))) 

     (replace-dehighlight)) 
    (or unread-command-events 
    (message "Replaced %d occurrence%s%s" 
     replace-count 
     (if (= replace-count 1) "" "s") 
     (if (> (+ skip-read-only-count 
       skip-filtered-count 
       skip-invisible-count) 0) 
      (format " (skipped %s)" 
       (mapconcat 
        'identity 
        (delq nil (list 
        (if (> skip-read-only-count 0) 
         (format "%s read-only" 
          skip-read-only-count)) 
        (if (> skip-invisible-count 0) 
         (format "%s invisible" 
          skip-invisible-count)) 
        (if (> skip-filtered-count 0) 
         (format "%s filtered out" 
          skip-filtered-count)))) 
        ", ")) 
      ""))) 
    (or (and keep-going stack) multi-buffer))) 
+1

Использование '(texmathp)' является хорошим (+1). Но вместо переопределения всех элементов 'query-replace' вы можете установить переменную' replace-re-search-function'. См. Новую часть моего ответа. – Tobias

+0

Отлично, это лучший подход. Я оставляю свой ответ здесь, потому что кто-то, желающий сделать некоторые более общие модификации 'query-replace', все равно может оказаться полезным. Благодаря! – cgogolin

3

Мои решение вдохновлено Тобиасом, но использует isearch-filter-predicate для фильтрации вместо изменения внутренних элементов query-replace-regexp. Для этого требуется, по крайней мере, Emacs 24.

Кроме того, я использую только поиск с учетом регистра и замену для математики, поэтому я установил (case-fold-search nil) в функции ниже.

(defun latex-replace-in-math() 
"Call `query-replace-regexp' with `isearch-filter-predicate' set to filter out matches outside LaTeX math environments." 
(interactive) 
(let ((isearch-filter-predicate 
(lambda (BEG END) 
    (save-excursion (save-match-data (goto-char BEG) (texmathp))))) 
(case-fold-search nil)) 
(call-interactively 'query-replace-regexp))) 
+0

Для замены 'n -> N' сначала введите' \ ', затем 'N', как указано в ответе @ Tobias. Он отлично работает на spacemacs 0200.9 с emacs 25.3.2. Большое спасибо, это сэкономит мне много времени при изменении обозначения для обзора моей статьи –

Смежные вопросы