Como excluir uma macro LaTeX enquanto preserva seu conteúdo de texto?


11

No TeXStudio, pressionando ALT+ DELem uma macro LaTeX como esta, \macroname{content}enquanto o cursor está logo antes do primeiro {, resultará na exclusão de tudo isso, exceto o seu content(como mostrado abaixo).

insira a descrição da imagem aqui
Coloque o cursor (ponto) antes do primeiro colchete:

insira a descrição da imagem aqui

Pressione ALT+ DELe você obtém:

insira a descrição da imagem aqui

Como conseguir isso no Emacs?

Atualização
De acordo com o esclarecimento de T.Verron, existe um problema, C-c C-f C-dpois se queixa de erro de parêntese desequilibrado quando executado em algumas macros no LaTeX. Considere o exemplo abaixo:
insira a descrição da imagem aqui

lança este erro: up-list: Scan error: "Unbalanced parentheses", 8074, 1. \ textenglish {} pertence ao pacote de poliglossia.

Como se livrar dessa ressalva?


Entretanto, a ressalva com a resposta atual não é se o auctex tipifica a macro ou não, mas se a macro é uma especificação de fonte de látex (provavelmente como definida por TeX-font-list) ou não. Por exemplo, tente com \sectionou \footnote, o AUCTeX conhece essas macros e as fontifica, mas C-c C-f C-dreclama com parênteses desequilibrados.
precisa saber é o seguinte

Mesmo se eu puder atualizar isso TeX-font-listpara incluir minhas macros recém-introduzidas, isso continuará sendo uma solução subótima. Caso contrário, não sei o que impede ter uma função eLISP para lidar com isso!
doutorado

Respostas:


11

Tente esta função:

(defun mg-TeX-delete-current-macro (&optional arg)
  "Remove the current macro.
With an optional argument ARG, delete just the ARG-th macro
starting from the innermost."
  (interactive "*p")
  (let (macro end)
    (when 
    (dotimes (i arg macro)
      (goto-char (TeX-find-macro-start))
      (setq macro (TeX-current-macro)
        end (TeX-find-macro-end))
      ;; If we need to look for an outer macro we have to "exit" from the
      ;; current one.
      (backward-char))
      ;; Return to the beginning of the macro to be deleted.
      (forward-char)
      (re-search-forward
       (concat (regexp-quote TeX-esc) macro "\\(?:\\[[^]]*\\]\\)?"
           TeX-grop "\\(\\(.\\|\n\\)*\\)")
       end t)
      (replace-match "\\1")
      ;; Delete the closing brace.
      (delete-backward-char 1))))

Limitação: não funciona com macros do tipo literal. Esta função gerará um erro ( Wrong type argument: integer-or-marker-p, nil) se o argumento universal for maior que o número de macros do ponto de fechamento.

Vincule a função ao seu atalho favorito. Por exemplo

(eval-after-load "tex"
  '(local-set-key (kbd "M-DEL") 'mg-TeX-delete-current-macro))

para ligá-lo M-DEL.

Se o seu buffer tiver ( !é ponto)

\onemacro{\anothermacro{!argument}}

então C-2 M-DELvai te dar

\anothermacro{argument}

Se o ponto dentro do grupo mais interno (gr1(gr2(gr3(gr4))))você quer dizer com um prefixo, C-uentão 2 me dará (gr1(gr2)):? se é assim, deve ser brilhante. Espero que você tenha tido tempo para fazê-lo.
doctorado

Eu M-DELliguei para gostar no TexStudio. Obrigado.
doctorado

@ doctorate Bem, não, minha idéia é excluir apenas a segunda macro, gr3no seu caso. Veja a resposta atualizada. Você pode implementar o que você sugeriu envolvendo uma dotimesvolta whenda versão original da resposta.
Giordano

Ótima função! Agora ele se comporta como um macro-pacman inteligente ! uma ressalva; quando o argumento é grande e gera um erro, o ponto salta para trás em algum lugar. Você pode fazê-lo reclamar enquanto está em seu lugar atual?
doutorado

@giordano Alguma chance disso chegar ao AucTex? É muito útil!
Tyler

9

No nó manual do AUCTeX em Alterar a fonte :

C-c C-f C-d

Delete the innermost font specification containing point.

essa foi uma peça muito útil na documentação que eu perdi. Obrigado.
doutorado

Mas ele funciona apenas para especificações de fonte (e a verificação faz sentido, por exemplo, porque \emph{\randommacro{test}}ela excluirá o \emph).
T. Verron

@ T.Verron: bom esclarecimento. Não conheço uma maneira integrada de fazer isso para macros arbitrárias do LaTeX.
Dan

4

Aqui está uma função simples para remover a macro que contém no ponto:

(defun TeX-remove-macro ()
  "Remove current macro and return `t'.  If no macro at point,
return `nil'."
  (interactive)
  (when (TeX-current-macro)
    (let ((bounds (TeX-find-macro-boundaries))
          (brace  (save-excursion
                    (goto-char (1- (TeX-find-macro-end)))
                    (TeX-find-opening-brace))))
      (delete-region (1- (cdr bounds)) (cdr bounds))
      (delete-region (car bounds) (1+ brace)))
    t))

Portanto, com *como ponto:

\footnote{Here's a * footnote} 
  => Here's a footnote

Dada a função acima, é uma linha única remover todas as macros no ponto:

(defun TeX-remove-all-macros ()
  "Remove all containing macros for text at point."
  (interactive)
  (while (TeX-remove-macro)))

Portanto, novamente com *o ponto:

\footnote{Here's a \textbf{footnote with \emph{emphasized * text}}} 
  => Here's a footnote with emphasized text
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.