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?

doutorado
fonte
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}
Giordano
fonte
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.
Dan
fonte
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
Dan
fonte