Cuaderno de GNUtas

Escribir el preámbulo de LaTeX en Org mediante un bloque de código

Para mis proyectos «de envergadura» en Org Mode (trabajos de composición tipográfica, por lo general, que suponen libros extensos y complejos) suelo definir el preámbulo de LATEX en un documento aparte, generado desde otro documento de Org, muy detallado, mediante la funcionalidad org-babel-tangle. Y para los documentos rápidos del día a día tengo una serie de plantillas y clases ya preparadas («clases», entiéndase, más en la manera que las entiende Org, es decir, lo que cargamos mediante la directiva #+org-LaTeX-class:). El problema está en los documentos de escala intermedia, donde necesitamos escribir un preámbulo ad hoc, definir ciertas macros, probar este u otro paquete y demás. Como sabe cualquier usuario medio de Org Mode, las líneas del preámbulo de cara a la exportación a LATEX se escriben en org mediante la directiva (o «keyword») #+LaTeX_Header:. Pero aquí viene el engorro. Lo que escribimos así debe estar siempre en una línea. A poco que el preámbulo tenga algo de complejidad tendremos que añadir múltiples líneas que comiencen con #+LaTeX_Header:, y esto, naturalmente, supone una tarea pesada y tediosa. ¿Por qué no escribir, mejor, nuestro preámbulo dentro de un bloque de código LATEX? Las ventajas son obvias: tendremos más libertad de escritura (no hace falta añadir la dichosa directiva antes de cada línea) y además lo podemos hacer con el LaTeX-mode activado, puesto que estamos dentro de un bloque LATEX y seremos capaces de editarlo siempre que queramos. Veremos en esta GNUta varias maneras de conseguir esto.

Antes de nada, partamos de un preámbulo de ejemplo (con unas cuantas declaraciones y un poco de código Lua introducido mediante la primitiva directlua), que escribiremos en un bloque LATEX, con el argumento de cabecera («header argument») para que nos silencie los resultados y los exporte:

#+NAME:preamble
#+begin_src latex :results silent :exports results
  \usepackage{luacode}
  \usepackage{fontspec}
  \directlua
  {
  fonts.handlers.otf.addfeature
  {
     name = "ktest",
     type = "kern",
     data =
        {
           ["A"] = { ["V"] = -45 },
        },
  }
  }
  \setmainfont{Linux Libertine O}
  [RawFeature={+ktest}]
#+end_src

La forma torpe

La primera manera de hacerlo que se me ocurrió fue la de pasar el contenido en bruto de nuestro bloque de código a una variable, y tratar ésta mediante código Elisp (una expresión let), incluído en un segundo bloque de código:

#+begin_src emacs-lisp :var x=preamble :results raw :exports results
  (let* ((lines (split-string x "\n" nil))
         (headers (mapconcat (lambda
                           (line)
                           (unless (equal line "")
                             (format "#+LaTeX_Header: %s" line)))
                         lines "\n")))
    headers)
#+end_src

En el proceso de la exportación, este último bloque arrojaría los siguientes resultados, que es precisamente lo que queríamos conseguir:

#+RESULTS:
#+LaTeX_Header: \usepackage{luacode}
#+LaTeX_Header: \usepackage{fontspec}
#+LaTeX_Header: \directlua
#+LaTeX_Header: {
#+LaTeX_Header: fonts.handlers.otf.addfeature
#+LaTeX_Header: {
#+LaTeX_Header:    name = "ktest",
#+LaTeX_Header:    type = "kern",
#+LaTeX_Header:    data =
#+LaTeX_Header:       {
#+LaTeX_Header:  ["A"] = { ["V"] = -45 },
#+LaTeX_Header:       },
#+LaTeX_Header: }
#+LaTeX_Header: }
#+LaTeX_Header: \setmainfont{Linux Libertine O}
#+LaTeX_Header: [RawFeature={+ktest}]

Y asunto arreglado. Pero todavía tenemos otra forma mucho más sencilla de hacerlo.

La forma fetén: usar noweb

Charles Berry, en efecto, me comentó en la lista de correo de Org Mode que por qué no me ahorraba el segundo bloque con el código Elisp y tiraba de algo mucho más simple: el argumento de cabecera noweb, que nos permite enlazar varios bloques de código. Burro de mí, cómo no se me había ocurrido. Claro, la cosa así se aligera una barbaridad. Si en nuestro bloque LATEX (con el contenido del preámbulo, recordemos) añadimos como único argumento de cabecera :exports none (es decir, le prohibimos que se exporte, pero no que se evalúe), nos bastaría con escribir este segundo y sencillo bloque:

#+begin_src latex :noweb yes :results raw
,#+LaTeX_HEADER: <<preamble>>
#+end_src

que nos generaría la esperada lista de directivas #+LaTeX_Header: para nuestro preámbulo1.

Publicado: 17/02/21

Última actualización: 16/08/23


Índice general

Acerca de...

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

Notas:

1

Siempre y cuando tengamos incluido en la lista org-babel-load-languages el cons cell (latex . t), para que se evalúen los bloques LATEX.

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