Cuaderno de GNUtas

La función shell-command-on-region (Emacs)

Gnu Emacs viene con varias funciones nativas para ejecutar comandos de shell. Una de ellas, shell-command-on-region, me resulta especialmente interesante y merecedora de un pequeño comentario por estas gnutas. Se invoca, para empezar, de forma interactiva (M-x shell-command-on-region RET) y acude para hacer lo que su nombre indica; es decir, nos pregunta que escribamos un comando en el minibúfer y lo ejecuta sobre la región de texto que tengamos marcada. Un comando (entiéndase) que sea razonablemente aplicable a una porción de texto. Esto da mucho juego para algunos casos y situaciones prácticas. Por ejemplo, imaginemos que estamos en un documento de Org y queremos exportar una región determinada a HTML. Nuestro mejor candidato para comando de shell sería entonces Pandoc:

pandoc -f org -o archivo_salida.html

Pero tal vez queramos automatizar este proceso y definir para ello nuestra propia función. Se podría empezar haciendo un defun que nos leyera el nombre que queremos darle al archivo de salida (sin la extensión):

(defun nombre-archivo ()
  (format "%s" (read-file-name "Nombre del archivo (sin extensión)...?:")))

Y a continuación, la función propiamente dicha. Ésta ha de llamarse interactivamente sobre una región: (interactive "r"). Y como argumentos el principio y final de dicha región, y así los nombramos sin rompernos demasiado la cabeza: (&optional principio final). El cuerpo de la función es básicamente una expresión let, compuesta de una única variable (archivo-salida), a la que hemos asignado como valor la funcioncilla de más arriba, y las acciones que se ejecutan a partir de esa variable: correr Pandoc, abrir una ventana a la derecha, mover el foco a esta ventana y abrir en ella el archivo resultante.

(defun exporta-region-org-html (&optional principio final)
 (interactive "r")
 (let
((archivo-salida (nombre-archivo)))
(shell-command-on-region principio final (format "pandoc -f org -o %s.html" archivo-salida))
(split-window-horizontally)
(other-window 1)
(find-file (format "%s.html" archivo-salida))))

Lo bueno de haber definido previamente nuestra pequeña función que lee el nombre del archivo sin la extensión es que podemos aprovecharlo para más funciones de exportación. En este caso, de Org a Markdown, con una estructura calcada a la anterior, salvo por la extensión:

(defun exporta-region-org-markdown (&optional principio final)
 (interactive "r")
 (let
((archivo-salida (nombre-archivo)))
(shell-command-on-region principio final (format "pandoc -f org -o %s.md" archivo-salida))
(split-window-horizontally)
(other-window 1)
(find-file (format "%s.md" archivo-salida))))

Por supuesto, si queremos hacer algo mucho más global y elaborado (con condicionales y demás) el campo está abierto a la imaginación. Pero con esto podemos salir muy bien del paso, habida cuenta de que no es muy habitual (creo) que necesitemos exportar una región.

Publicado: 13/06/2019

Última actualización: 13/06/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