Incluir parte de un documento LaTeX en otro
Siempre es buena práctica en LATEX incluir las secciones y capítulos de un documento como ficheros externos. Trabajar de
esta forma con un documento maestro resulta más cómodo a la hora de controlar y depurar el código, además de que podemos
compilar sólo partes del documento a voluntad. Pero, a diferencia del comando en línea de Org Mode #+INCLUDE:
, la
macro \input
de LATEX no permite incluir sólo partes de un documento. Por ejemplo desde la línea tal a la línea cual.
Hay una serie de escenarios donde este requerimiento podría tener sentido, como en caso de que queramos reutilizar un
preámbulo de otro documento. O incluir otro documento sin su preámbulo. En todo caso, ya que la carencia es importante y
me hacía falta contar con una funcionalidad así, se me ocurrió escribir esta serie de macros que vienen a hacernos el
apaño. Todas comparten las siguientes características:
- Generan un script durante la compilación
- Ejecutan el comando de bash
sed
, que es en realidad el que hace el trabajo - Crean un documento en el mismo directorio con el texto a incluir
Como puede verse, no es una solución del todo limpia, pues produce archivos nuevos en el directorio de trabajo; ni es
una solución cien por cien LATEX, al echar mano de un comando de bash. Pero, bueno, es lo que hay y funcionar, funciona.
Pasemos, pues, a describir estas macros, que por comodidad las definimos mediante el paquete xparse
. Empezamos, por tanto,
cargando dicho paquete:
\usepackage{xparse}
Y como nos hará falta definir antes una pequeña función en Lua, también cargamos luacode
:
\usepackage{luacode}
Y, acto continuo, definimos la función, que se encargará de hacer ejecutable y ejecutar el script generado en la
compilación, y de añadir la macro \input
con el texto a incluir:
\begin{luacode} function mi_input (y) local x = io.popen([[chmod +x extraer_doc.sh && ./extraer_doc.sh]]) local y = "\\input{temp.tex}" tex.print (y) x:close () end \end{luacode}
Nuestra primera macro definida con xparse
admite tres argumentos obligatorios: línea desde, línea hasta y fichero a
incluir. Y como argumentos opcionales: término a sustituir en temp.tex
(vale usar también expresiones regulares) y
término con que sustituir. Por ejemplo, si de un fichero que queremos incluir, llamado mifichero.tex
, queremos cargar
de la línea 10 a la 20, y que se sustituya en lo que cargamos cualquier ocurrencia de la cadena «Juan Gómez» por la
cadena «Sr. Gómez», pondríamos en nuestro documento: \MiInput{10}{20}{mifichero.tex}[Juan Gómez][Sr. Gómez]
:
\DeclareDocumentCommand\MiInput{ m m m o o }{% \newwrite\script \immediate\openout\script=extraer_doc.sh \immediate\write\script{\string##!/bin/bash} \immediate\write\script{sed -ne #1,#2p #3 > temp.tex;} \IfNoValueF {#4#5} {\immediate\write\script{sed -i 's/#4/#5/g' temp.tex}} \immediate\write\script{exit}% \immediate\closeout\script% {\directlua{mi_input()}}}
Esta variante admite un sólo argumento opcional para añadir lo que se quiera al script (por ejemplo, múltiples reemplazos sobre el archivo temp.tex usando el comando sed, etc.)
\DeclareDocumentCommand\MiInputvar{ m m m o }{% \newwrite\script \immediate\openout\script=extraer_doc.sh \immediate\write\script{\string##!/bin/bash} \immediate\write\script{sed -ne #1,#2p #3 > temp.tex;} \IfNoValueF {#4} {\immediate\write\script{#4}} \immediate\write\script{exit}% \immediate\closeout\script% {\directlua{mi_input()}}}
Y esta tercera y última variante nos cargará un documento, pero sólo la parte que se encuentre entre el
\begin{document}
y el \end{document}
. Útil, por ejemplo, para reutilizar otro documento de LATEX. Admite un único
argumento obligatorio, que es el documento a incluir:
\DeclareDocumentCommand\MiInputContenido{ m }{% \newwrite\script \immediate\openout\script=extraer_doc.sh \immediate\write\script{\string##!/bin/bash} \immediate\write\script{sed -n '/^\\begin{document}/,/^\\end{document}/p' #1 > temp.tex} \immediate\write\script{sed -i 's/\\begin{document}\|\\end{document}//g' temp.tex} \immediate\write\script{exit}% \immediate\closeout\script% {\directlua{mi_input()}}}
La compilación ha de ser con LuaLATEX desde la terminal, añadiendo la opción -shell-escape
.
∞
Publicado: 29/06/20
Última actualización: 21/01/22
Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.