Cuaderno de GNUtas

Revoltijo Elisp (I)

Una función para navegar por los argumentos de macros simples de LaTeX

Lo que viene a hacer esta función es lo siguiente. Despliega una lista navegable y autocompletiva (mediante Ido) de las veces que aparece en nuestro documento un comando de LaTeX, por el cual nos ha preguntado previamente. Pero la gracia aquí estriba en que lo que muestra en la lista son los pasajes que encierran los argumentos obligatorios (y sólo ésos) de ese comando. Por ejemplo, serviría si queremos ver una lista de los pasajes que en nuestro documento están en cursiva con el comando \textit. O una lista de todo lo que contiene la macro \label{...}. Nos muestra todo eso, y luego podemos saltar de allí al pasaje escogido. Como otros posibles usos, también podemos ver una lista de las propiedades OpenType que hemos añadido de manera directa mediante el comando de fontspec \addfontfeatures. O podemos listar los pasajes encerrados en un comando de Babel, como \foreignlanguage{greek}. Sirve, por tanto, para comandos de este tipo (con o sin argumento opcional).

Se me ocurrió escribir esta función como una versión de propósito general de otra que incluí en el modo menor que escribí para trabajar con el paquete reledmac.sty para ediciones críticas filológicas en LaTeX. En ese caso, la función listaba los argumentos de un sólo tipo de comando. En esta versión, nos pregunta por el comando (textit, label, emph, etc.) y nos construye la lista a partir de ahí. Por cierto, hay que escribir el comando en el prompt sin la barra invertida: si quisiésemos listar todos los énfasis y navegar por ellos, bastaría llamar a la función y escribir emph. Pasemos, sin más preámbulo, al código y a su explicación.

Por supuesto, si es preciso, deberemos requerir antes ido y smartparens. El primero viene incluido en Emacs. El segundo hay que instalarlo (M-x package-refresh-contents seguido de M-x package-install <RET> smartparens

(require 'ido)
(require 'smartparens)

A continuación, una pequeña función de la que luego sacaremos provecho. Delimita una región entre dos argumentos (a y b) y la convierte en una cadena de texto:

(defun elemento-lista-cosa (a b)
  (save-restriction
  (narrow-to-region a b)
  (buffer-string)))

Y también definimos esta otra, que lleva por argumento (macro-latex) el nombre del comando LaTeX que queremos buscar, junto a dos variables locales (x e y) que serán dos delimitadores. Finalmente, añade a la recién definida lista lista-cosa (sí, los nombres que voy escogiendo no es que sean muy evocadores) el argumento obligatorio de la macro de LaTeX, pero obviando (caso de que lo haya) el argumento opcional.

(defun lista-latex (macro-latex)
  (let
      ((x (make-marker))
       (y (make-marker)))
    (setq lista-cosa nil)
  (save-excursion
    (goto-char (point-min))
    (while
        (re-search-forward (concat "\\\\" macro-latex "\\(\\[.+\\]\\)*" "{") nil t)
            (set-marker x (point))
    (sp-end-of-sexp)
    (set-marker y (point))
    (add-to-list 'lista-cosa (elemento-lista-cosa x y))))))

Ya sólo nos queda definir la función que genere la lista del contenido de los argumentos obligatorios de la macro de LaTeX solicitada:

(defun crea-lista-latex ()
  (setq macro (read-from-minibuffer "Macro LaTeX: "))
  (lista-latex macro)
(mapcar 'identity lista-cosa))

Y la función principal, que es la que llama a Ido y hace todo:

(defun ido-cosas-latex (argumento)
  (interactive  (list (ido-completing-read "Lista macros LaTeX: " (crea-lista-latex) nil t)))
  (goto-char (point-min))
  (occur (concat "\\\\" macro "\\(\\[.+\\]\\)*" "{" argumento)))

Podemos añadirle un atajo de teclado a este ido-cosas-latex. Por último, si no nos gusta que Ido despliegue su lista autocompletiva de manera horizontal, que es el comportamiento por defecto, podremos instalar la biblioteca ido-vertical-mode.

Y como un gif vale más que mil palabras:

ido-cosas-latex.gif

Publicado: 07/09/2019

Última actualización: 07/09/2019


Índice general

Acerca de...

Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.

© Juan Manuel Macías
Creado con esmero en
GNU Emacs