¿Cómo eliminar una macro LaTeX mientras se preserva su contenido de texto?

11

En TeXStudio presionando ALT+ DELen una macro LaTeX como esta \macroname{content}mientras el cursor se encuentra justo antes del primero, {se eliminará todo eso excepto su content(como se muestra a continuación).

ingrese la descripción de la imagen aquí
Coloque el cursor (punto) justo antes del primer soporte rizado:

ingrese la descripción de la imagen aquí

Hit ALT+ DELy obtienes:

ingrese la descripción de la imagen aquí

¿Cómo lograr esto en Emacs?

Actualización
Según la aclaración de T.Verron, existe un problema, C-c C-f C-dya que se queja del error de paréntesis desequilibrado cuando se ejecuta dentro de algunas macros en LaTeX. Considere el siguiente ejemplo:
ingrese la descripción de la imagen aquí

lanza este error: up-list: Scan error: "Unbalanced parentheses", 8074, 1. \ textenglish {} pertenece al paquete de poliglosia.

¿Cómo deshacerse de esta advertencia?

doctorado
fuente
Hem, la advertencia con la respuesta actual no se trata de si auctex fontifica la macro o no, se trata de si la macro es una especificación de fuente de látex (probablemente definida por TeX-font-list) o no. Por ejemplo, intente con \sectiono \footnote, AUCTeX conoce estas macros y las tipifica, pero C-c C-f C-dse quejará de paréntesis desequilibrados.
T. Verron
Incluso si puedo actualizar esto TeX-font-listpara incluir mis macros recién introducidas, esto sigue siendo una solución subóptima. De lo contrario, ¡no sé qué implica tener una función eLISP para manejarlo!
doctorado

Respuestas:

11

Prueba esta función:

(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))))

Limitación: no funciona con macros literales. Esta función arrojará un error ( Wrong type argument: integer-or-marker-p, nil) si el argumento universal es mayor que el número de macros que encierra el punto.

Vincula la función a tu atajo favorito. Por ejemplo

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

para atarlo M-DEL.

Si su búfer tiene ( !es punto)

\onemacro{\anothermacro{!argument}}

entonces C-2 M-DELte daré

\anothermacro{argument}
giordano
fuente
Si el punto dentro del grupo más interno (gr1(gr2(gr3(gr4))))quieres decir con un prefijo, C-uentonces 2 me dará (gr1(gr2)):? si es así, eso debe ser brillante. Espero que hayas tenido tiempo de hacerlo.
doctorado
Lo limité a M-DELgustar en TexStudio. Gracias.
doctorado
@doctorate Bueno, no, mi idea es eliminar solo la segunda macro, gr3en su caso. Ver la respuesta actualizada. Se puede aplicar lo que usted sugiere envolviendo una dotimesalrededor whende la versión original de la respuesta.
giordano
Gran función! Ahora se comporta como un inteligente macro-pacman ! una advertencia sin embargo; Cuando el argumento es grande y arroja un error, el punto salta hacia atrás. ¿Puedes hacer quejarse mientras está parado en su lugar actual?
Doctorado
@giordano ¿Hay alguna posibilidad de que esto llegue a AucTex? ¡Es muy útil!
Tyler
9

Desde el nodo manual de AUCTeX al cambiar la fuente :

C-c C-f C-d

Delete the innermost font specification containing point.
Dan
fuente
esa fue una pieza muy útil en la documentación que me perdí. Gracias.
doctorado
Pero solo funciona para las especificaciones de fuente (y la verificación tiene sentido, por ejemplo \emph{\randommacro{test}}, porque eliminará la \emph).
T. Verron
@ T.Verron: buena aclaración. No conozco una forma integrada de hacer esto para las macros arbitrarias de LaTeX.
Dan
4

Aquí hay una función simple para eliminar la macro que contiene en el punto:

(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))

Por lo tanto, con *como punto:

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

Dada la función anterior, es un trazador de líneas para eliminar todas las macros en el punto:

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

Por lo tanto, nuevamente con *como punto:

\footnote{Here's a \textbf{footnote with \emph{emphasized * text}}} 
  => Here's a footnote with emphasized text
Dan
fuente