Comment supprimer une macro LaTeX tout en préservant son contenu texte?

11

Dans TeXStudio en appuyant sur ALT+ DELdans une macro LaTeX comme celle-ci \macroname{content}alors que le curseur se trouve juste avant le premier, {cela supprimera tout sauf son content(comme indiqué ci-dessous).

entrez la description de l'image ici
Placez le curseur (point) juste avant la première accolade:

entrez la description de l'image ici

Hit ALT+ DELet vous obtenez:

entrez la description de l'image ici

Comment y parvenir dans Emacs?

Mise
à jour Selon la clarification de T.Verron, il y a un problème C-c C-f C-dcar il se plaint d'une erreur de parenthèse déséquilibrée lorsqu'il est exécuté dans certaines macros dans LaTeX. Prenons l'exemple ci-dessous:
entrez la description de l'image ici

jette cette erreur: up-list: Scan error: "Unbalanced parentheses", 8074, 1. \ textenglish {} appartient au package polyglossia.

Comment se débarrasser de cette mise en garde?

doctorat
la source
Hem, la mise en garde avec la réponse actuelle n'est pas de savoir si auctex fait la police de la macro ou non, c'est de savoir si la macro est une spécification de police en latex (probablement telle que définie par TeX-font-list) ou non. Par exemple, essayez avec \sectionou \footnote, AUCTeX connaît ces macros et les fait caractériser, mais C-c C-f C-dse plaindra de parenthèses déséquilibrées.
T. Verron
Même si je peux mettre TeX-font-listà jour cela pour inclure mes macros nouvellement introduites, cela reste une solution de contournement sous-optimale. Sinon, je ne sais pas ce qui empêche d'avoir une fonction eLISP pour y faire face!
doctorat du

Réponses:

11

Essayez cette fonction:

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

Limitation: ne fonctionne pas avec les macros verbatim. Cette fonction générera une erreur ( Wrong type argument: integer-or-marker-p, nil) si l'argument universel est supérieur au nombre de macros entourant le point.

Liez la fonction à votre raccourci préféré. Par exemple

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

pour le lier M-DEL.

Si votre tampon a ( !est le point)

\onemacro{\anothermacro{!argument}}

puis C-2 M-DELvous donnera

\anothermacro{argument}
giordano
la source
Si le point à l' intérieur le plus profond groupe (gr1(gr2(gr3(gr4))))voulez - vous dire par un préfixe C-upuis 2 il me donnera: (gr1(gr2))? s'il en est ainsi, cela doit être brillant. J'espère que vous avez eu le temps de le faire.
doctorat du
Je l'ai lié à M-DELaimer dans TexStudio. Merci.
doctorat du
@doctorate Eh bien, non, mon idée est de supprimer uniquement la deuxième macro, gr3dans votre cas. Voir la réponse mise à jour. Vous pouvez implémenter ce que vous avez suggéré en dotimesentourant whenla version originale de la réponse.
giordano
Grande fonction! Maintenant, il se comporte comme un macro-pacman intelligent ! une mise en garde cependant; lorsque l'argument est grand et qu'il renvoie une erreur, le point saute quelque part en arrière. Pouvez-vous le faire se plaindre en se tenant à sa place actuelle?
doctorat du
@giordano Y a-t-il une chance que cela se transforme en AucTex? C'est très utile!
Tyler
9

Depuis le nœud manuel AUCTeX sur Changer la police :

C-c C-f C-d

Delete the innermost font specification containing point.
Dan
la source
c'était une pièce très pratique dans la documentation que j'ai ratée. Merci.
doctorat du
Mais cela ne fonctionne que pour les spécifications de police (et la vérification est logique, par exemple car \emph{\randommacro{test}}elle supprimera le \emph).
T. Verron
@ T.Verron: bonne clarification. Je ne suis pas au courant d'un moyen intégré de le faire pour les macros LaTeX arbitraires.
Dan
4

Voici une fonction simple pour supprimer la macro contenant au point:

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

D'où, avec *comme point:

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

Compte tenu de la fonction ci-dessus, il s'agit d'une ligne unique pour supprimer toutes les macros au point:

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

D'où, encore une fois avec *comme point:

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