Cuaderno de GNUtas

Exportar bloques de código a LaTeX desde Org (opciones fancyvrb y la muy fetén minted)

Cuando exportamos desde Org Mode a LaTeX, los típicos bloques de código se traducirán por defecto en el archivo de salida como el veterano y siempre precario entorno verbatim. Esto supone un doble inconveniente: por un lado, verbatim carece de resaltado de sintaxis para los distintos lenguajes de programación. Por otro, con este entorno es bastante habitual que las líneas de código salgan desbordadas del márgen derecho de la página. Por suerte, todo eso se puede evitar fácilmente, de manera que podamos producir en nuestro archivo LaTeX resultante vistosos y perfectos bloques de código. Hay muchas formas de conseguirlo, pero aquí nos limitaremos a las dos soluciones que resultan, a mi juicio, más satisfactorias.

Usar fancyvrb

Esta opción es la más recomendable, pienso, si no vamos a necesitar escibir demasiados bloques de código. El paquete para LaTeX fancyvrb maneja por defecto el entorno Verbatim (ojo a la mayúscula que lo distingue del entorno estándar) que produce unos bloques de código bastante aceptables y sin desbordamiento de líneas. Escribiremos, entonces, en nuestra cabecera del documento *.org la opción:

#+LaTeX_HEADER: \usepackage{fancyvrb}

para que se nos mande al preámbulo del documento de LaTeX exportado. Ahora bien, ¿cómo hacemos para que se nos devuelva al exportar un entorno Verbatim (capitalizado, el que queremos) y no el viejo verbatim? Fácil. Podemos crear un filtro de exportación definiendo una función que se ejecute siempre y cuando la salida sea LaTeX, y únicamente durante el post-proceso. Lo podemos hacer de manera local para un sólo documento de Org. Si es así, encerraremos nuestra función en un bloque de código con los parámetros necesarios de cara a su evaluación por el sistema:

#+begin_src emacs-lisp :exports results :results none
(defun fancyvrb-latex (texto backend info)
  "reemplaza el entorno verbatim para fancyvrb"
(when (org-export-derived-backend-p backend 'latex)
(replace-regexp-in-string "{verbatim}"  "{Verbatim}" texto)))
#+end_src

Y, justo antes de este bloque, anclaremos la función al filtro apropiado:

#+BIND: org-export-filter-final-output-functions (fancyvrb-latex)

Por supuesto, tenemos que activar antes en nuestro archivo de inicio la posibilidad de usar la opción BIND en Org:

(setq org-export-allow-bind-keywords t)

¿Qué implica el haber hecho todo eso? Pues, simplemente, que el bloque de código anterior no se exportará como tal sino que se evaluará (ergo, será ejecutado), y la función que reemplaza un entorno por otro (ojo, sólo cuando exportamos a LaTeX) entrara en acción únicamente cuando se llegue al output final.

Usar minted

Ahora bien, si lo que queremos es ser la envidia de todo el vecindario y presumir de unos bloques de código con un resaltado de sintaxis a todo color y completo según sea cada lenguaje de programación, la mejor opción es el novedoso paquete de LaTeX minted. La buena noticia es que Org lo soporta, siempre que añadamos esto a nuestro archivo de inicio:

;; para exportar bloques de códico org a LaTeX con minted
(setq org-latex-listings 'minted)

Podemos, además, añadir muchas opciones de minted (véase la documentación del paquete para más información). Yo, por ejemplo, tengo éstas:

(setq org-latex-minted-options
     '(("frame" "lines") ("linenos=true") ("breaklines")))

Es decir, pido que cada bloque se me encierre entre dos filetes, se numeren las líneas y se corten aquéllas que desbordan el margen (colocando una discreta flechita que indica la continuación de la línea de código truncada: un detallejo muy de agradecer).

Para que minted funcione bien, no obstante, hay dos requisitos importantes:

  1. Tener instalado el resaltador de sintaxis de Python Pygmentize;
  2. Compilar nuestro documento LaTeX con la coletilla shell-escape.

Para lo primero no hay problema, pues Pygmentize no debe faltar en ninguna distro. Para lo segundo tampoco. Basta con indicarlo en nuestro archivo de inicio, como yo tengo desde hace tiempo (en mi caso para que compile siempre con LuaTeX), y por triplicado para que se actualicen siempre las tablas de contenido y otras cosas que necesitan más de una compilación:

(setq org-latex-pdf-process
      '("lualatex -shell-escape -interaction nonstopmode -output-directory %o %f"
	"lualatex -shell-escape -interaction nonstopmode -output-directory %o %f"
	"lualatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

Una vez cumplido todo lo anterior, cuando exportemos a LaTeX, y si tenemos (por ejemplo) un bloque de código en elisp, éste se traducirá en el archivo de salida así:

\begin{minted}[frame=lines,linenos=true,breaklines]{emacs-lisp}
nuestro código
\end{minted}

Es más, podemos añadirle un atributo de objeto flotante y un encabezado, si escribimos justo antes de nuestro bloque de código en el documento Org:

#+CAPTION: Nuestro precioso bloque de código en elisp
#+ATTR_LaTeX: :float t

Y ya, la guinda, para redefinir el literal de los encabezados, añadimos la opción global a nuestro documento de Org:

#+LaTeX_HEADER: \renewcommand{\listingscaption}{Cuadro de código}

minted.png

Figura 1: Resultado de la exportación del bloque de código en Latex com minted

Publicado: 17/06/2019

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