
La meta
Mi objetivo es tener contadores de páginas continuas (y posiblemente de secciones) para varios documentos independientes. El propósito es una disertación acumulativa en la que cada artículo debe conservar el diseño de la revista tanto como sea posible, pero la escuela requiere una paginación continua. Podría decirse que se verá feo, como varios papeles pegados, pero eso es esencialmente lo que es.
Soy consciente de que la forma limpia de proceder probablemente sería extraer la información de formato de los .cls
archivos de las revistas y empaquetarla en entornos, pero eso probablemente sería mucho trabajo para alguien tan analfabeto TeX
como yo. Por lo tanto, probé, con cierto éxito, un enfoque alternativo: un truco usando el xr
paquete. Pero quedan algunas cuestiones residuales.
Primero déjame explicarte lo que he estado haciendo:
mi configuración
Tengo un archivo principal que incluye la introducción y las conclusiones. Tanto su contador de páginas como su contador de secciones deberían comenzar en 1, por lo que tengo que actualizarlos con los valores ingresados desde el último capítulo del cuerpo solo en el punto de ruptura. He tenido problemas al intentar usarlo \setcounter{page}{\pageref{external-endfile}}
dentro del documento, lo que parece tener que ver con la representación de la \pageref
salida de 'como una cadena en lugar de un número entero, y parece que el babel
paquete lo activa, por lo que introduzco los números en un \newcounter
archivo que luego lea los contadores reales cuando sea necesario. Así es como se ve este archivo principal:
\documentclass{article}
\usepackage{xr} %imports labels from external document
\externaldocument[finalCh]{file1} %prefix external labels to avoid name clashes
\newcounter{finalcount}
\setcounter{finalcount}{\pageref{finalChendfile}}% probably not the most elegant way to pack the input file's page number into a numberical variable, but it works.
\stepcounter{finalcount}% +1 since counters are initialised at 0
\newcounter{othersectioncount}
\setcounter{othersectioncount}{\ref{finalChendfile}}
\usepackage{ifthen} %conditionals
\newcommand{\exportcounters}{
\ifthenelse{%
\isodd{\thepage}} % if current page is odd-numbered
{\newpage \ % new page, forced space to make sure the following command is actually parsed, i.e. the page not treated as totally empty
}%
{\relax}
\label{endfile}
\newpage
}
%... other packages
\usepackage[english]{babel} %for some reason I don't understand, this clashes with treating \pageref as a number, so you have to put it *after* determining the page number
\usepackage{lipsum}
\begin{document}
\tableofcontents
\section{Introduction}
\subsection{Subsection}
\lipsum[1-2]
\newpage
\subsection{Another subsection}
\exportcounters
\setcounter{section}{\theothersectioncount}
\section{Conclusions}
\setcounter{page}{\thefinalcount} %load the final pagenumber of the last chapter here
\lipsum[4-40]
\end{document}
Además de eso, tengo un archivo para el capítulo, que se ve así:
\documentclass{article}
\usepackage{substr}
\usepackage{xr} %imports labels from external document
\usepackage{ifthen} %conditionals
\externaldocument[intro]{introandextro} %prefix external labels to avoid name clashes
\addtocounter{page}{\pageref{introendfile}}
\newcommand{\exportcounters}{
\ifthenelse{%
\isodd{\thepage}} % if current page is odd-numbered
{\newpage \ % new page, forced space to make sure the following command is actually parsed, i.e. the page not treated as totally empty
}%
{\relax}
\label{endfile}
\newpage
}
\usepackage{lipsum}
%\setcounter{section}{2}
\begin{document}
\setcounter{section}{\ref{introendfile}}
\section{Chapter I}
\subsection{intro}
\lipsum[1-4]
\newpage
\subsection{Chapter 1 body}
\lipsum[5-44]
\exportcounters
\label{endfile}
\end{document}
Con esta configuración, sólo necesito ejecutar dos veces cada "pdflatex introandextro", "pdflatex file1" y nuevamente "pdflatex introandextro" para obtener una numeración continua de páginas y secciones. (Tengo un script de shell para hacer eso por mí). También tengo un script de Python para extraer toda toc
la información relevante de los diferentes aux
archivos y compilar el archivo principal con eso toc
para obtener una tabla de contenidos que haga referencia a todas las secciones. no importa en qué archivo aparezcan, en su mayoría funciona como debería.
Como debería, \addtocounter{page}{\pageref{introendfile}}
importa el contador de páginas al final de la introducción al archivo1. Además, como debería, \setcounter{section}{\ref{introendfile}}
come la parte de la sección del valor de retorno de las referencias externas (1.2 en este caso) y la usa apropiadamente para configurar el contador de la sección. Desafortunadamente, no sabe qué hacer con el resto de la expresión, por lo que la escupe de nuevo, escribiendo ".2" en la parte superior de la página. Eso es feo, así que estoy tratando de deshacerme de él. Mi corazonada es que el mejor método para esto sería redefinir temporalmente \label
inside \exportcounters
para que solo envíe el comando de sección superior a .aux
y .toc
, pero mi texto simple no es lo suficientemente bueno como para saber por dónde empezar.
Problemas residuales
Entonces mi pregunta: ¿Alguien puede darme sugerencias sobre cómo redefinir el \label
comando -adecuadamente? En otras palabras, ¿cómo puedo hacer para que se indique en el .aux
archivo -en \newlabel{endfile}{{<thesection>}{12}}
lugar \newlabel{endfile}{{<\thesection>.<\thesubsection>}{12}}
de estar incrustado en una subsección o más profundamente? (Alternativamente, ¿cómo puedo quitar la parte de '.' antes de introducirla en \setcounter{section}{...}
? Lo intenté \SubStringBefore
, pero eso produce una cadena en lugar de un número, lo que me arroja un error de "Número faltante, tratado como cero" durante la compilación).
Un segundo problema que tengo es la necesidad de insertar un lugar explícito \newpage
donde quiero que termine la primera página en ambos documentos; de lo contrario, se ejecutaría durante dos páginas de texto. Este comportamiento parece ser desencadenado por xr
(o la conjunción de xr
y lipsum
). ¿Es este un problema conocido? ¿Existen soluciones alternativas que no impliquen \newpage
mensajes de correo electrónico explícitos?
Otro problema (realmente bastante menor) es que pdflatex se queja del uso de \ref
en el preámbulo ("Falta \begin{document}"), pero estoy bien con ignorarlo si el resultado parece correcto.
¿O tal vez sea posible abordar este problema desde un ángulo completamente diferente? ¿Existe alguna herramienta para ayudar a las personas que no entienden mucho de TeX a empaquetar .cls
comandos de formato en un entorno? Algo como \importasenvironment{<environmentname>}{<classname>.cls}
?
Respuesta1
La importación del valor de página y sección de un documento anterior se puede lograr mediante paquete zref
, módulo lastpage
y xr
.
Primer documento
El primer documento DocumentA
guarda las propiedades pagevalue
en sectionvalue
la lista de propiedades LastPage
escrita por la etiqueta LastPage
, establecida por paquete zref-lastpage
.
Archivo de ejemplo DocumentA.tex
, el primer documento:
\documentclass{article}
\usepackage{zref-lastpage}
\makeatletter
\zref@ifpropundefined{pagevalue}{% it is defined by some modules of zref
\zref@newprop*{pagevalue}[0]{\number\value{page}}%
}{}
\zref@newprop{sectionvalue}[0]{\number\value{section}}%
\zref@addprops{LastPage}{pagevalue,sectionvalue}
\makeatother
\begin{document}
\section{Section A of first document}
\section{Section B of first document}
\newpage
\section{Section C of first document}
\section{Section D of first document}
\end{document}
El paquete zref-lastpage
hace el trabajo:
- Llegar alrealfinal del documento (a través del paquete
atveryend
). - Escribiendo en el
.aux
archivo vía\immediate\write
.\label
utiliza\write
para obtener el número de página correcto, pero esto requiere que se genere la página siguiente. Después de la última página, no existe tal página. El paquete también se encarga de la corrección del número de página.
El .aux
archivo contiene:
\zref@newlabel{LastPage}{\default{4}\page{2}\abspage{2}\pagevalue{2}\sectionvalue{4}}
Siguiente documento
El siguiente documento importa los datos de la etiqueta LastPage
del documento anterior y configura los contadores. También utiliza el código del documento anterior para definir las propiedades y escribir los valores de los contadores para el siguiente documento.
Archivo de ejemplo DocumentB.tex
, el siguiente documento:
\documentclass{article}
\usepackage{zref-lastpage,zref-xr}
\makeatletter
\zref@ifpropundefined{pagevalue}{% it is defined by some modules of zref
\zref@newprop*{pagevalue}[0]{\number\value{page}}%
}{}
\zref@newprop{sectionvalue}[0]{\number\value{section}}%
\zref@addprops{LastPage}{pagevalue,sectionvalue}
\zexternaldocument[pre-]{DocumentA}\relax
\zref@ifrefundefined{pre-LastPage}{%
\@latex@error{Zref label `LastPage' of `DocumentA' is undefined}\@ehc
}{%
\setcounter{page}{%
\numexpr\zref@extractdefault{pre-LastPage}{pagevalue}{0}+1\relax
}%
\setcounter{section}{%
\zref@extractdefault{pre-LastPage}{sectionvalue}{0}%
}%
}
\makeatother
\begin{document}
\section{Section E of second document}
\section{Section F of second document}
\newpage
\section{Section G of second document}
\section{Section H of second document}
\end{document}
Luego, la primera sección del segundo documento Section E of second document
se numera con 5 y comienza en la página 3.
Respuesta2
La respuesta de Heiko Oberdiek resuelve el caso base de varios documentos que se complementan perfectamente entre sí.
Para el caso algo más complejo de un archivo principal que incluye partes anteriores y posteriores a los capítulos que se van a incluir, es decir, que pasa por sus contadores a un documento externo en un punto arbitrario del documento y luego recupera el mismo documento u otros documentos externos. contadores también dentro del documento, logré un ajuste definiendo \importcounters
comandos \exportcounters
y llamándolos en los lugares apropiados. Probablemente se pueda reducir aún más, pero esto es lo más cerca que estoy en este momento basándose en la publicación de Heiko Oberdiek.
\documentclass{article}
\usepackage{zref-lastpage,zref-xr}
\makeatletter
\zref@ifpropundefined{pagevalue}{% it is defined by some modules of zref
\zref@newprop*{pagevalue}[0]{\number\value{page}}%
}{}
\zref@newprop{sectionvalue}[0]{\number\value{section}}%
%\zref@addprops{LastPage}{pagevalue,sectionvalue}%
\zexternaldocument[pre-]{DocumentB}\relax
\zref@ifrefundefined{pre-LastPage}{%
\@latex@error{Zref label `LastPage' of `DocumentB' is undefined}\@ehc
}{%
\newcounter{@otherpage}
\setcounter{@otherpage}{%
\numexpr\zref@extractdefault{pre-LastPage}{pagevalue}{0}+1\relax
}%
\newcounter{@othersection}
\setcounter{@othersection}{%
\zref@extractdefault{pre-LastPage}{sectionvalue}{0}%
}%
}
\newcommand{\importcounters}{% enables importing the external page and section counters at an arbitrary point in the document
\setcounter{section}{\the@othersection}
\setcounter{page}{\the@otherpage}
}
\newcommand{\exportcounters}{% exporting counters after the intro rather than at the end of the document
\cleardoublepage \ %
\zref@labelbyprops{LastIntroPage}{pagevalue,sectionvalue}
}
\makeatother
\usepackage[english]{babel}
\begin{document}
\section{Section A of first document}
\section{Section B of first document}
\exportcounters
\newpage
\importcounters
\section{Section C of first document}
\section{Section D of first document}
\subsection{D 1}
\subsection{D 2}
\end{document}
(En DocumentB.tex
, el único cambio es que alimento los contadores en pre-LastIntroPage
lugar de pre-LastPage
).
Mi próximo objetivo es descubrir cómo utilizar write18
para pausar el archivo principal y pasar a la compilación de los archivos dependientes antes de continuar, pero eso es una pregunta aparte.