目标
我的目标是为几篇独立文档设置连续的页码(可能还有章节)计数器。目的是形成一篇累积论文,其中每篇论文应尽可能保留期刊的布局,但学校要求连续分页。可以说它看起来很丑,就像几篇论文粘在一起一样,但本质上就是这样。
我知道最简洁的办法可能是从日志文件中提取格式信息.cls
并打包到环境中,但对于像我这样文盲的人来说,这可能工作量很大TeX
。因此,我尝试了一种替代方法,并取得了一些成功:使用软件包进行破解xr
。但仍存在一些问题。
让我首先解释一下我一直在做的事情:
我的设置
我有一个包含引言和结论的主文件。它的页数计数器和节数计数器都应该从 1 开始,所以我必须在断点处使用从正文最后一章输入的值来更新它们。我在尝试\setcounter{page}{\pageref{external-endfile}}
在文档中使用时遇到了问题,这似乎与\pageref
将 的输出表示为字符串而不是整数有关,并且似乎是由包触发的,babel
所以我将数字输入到 中,\newcounter
然后在需要时将其读入实际计数器。这个主文件如下所示:
\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}
除此之外,我还有一个该章节的文件,如下所示:
\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}
使用此设置,我只需运行两次“pdflatex introandextro”、“pdflatex file1”和再次运行“pdflatex introandextro”即可获得连续的页面和章节编号。(我有一个 shell 脚本可以帮我完成这项工作。)我还有一个 Python 脚本,用于toc
从不同的aux
文件中提取所有相关信息,并使用该脚本编译主文件,以便toc
获得引用所有章节的目录,无论它们出现在哪个文件中,它基本上都可以正常工作。
正如它应该的那样,\addtocounter{page}{\pageref{introendfile}}
将介绍末尾的页面计数器导入到 file1 中。同样,正如它应该的那样,它\setcounter{section}{\ref{introendfile}}
吞噬了外部引用返回值的部分(在本例中为 1.2),并适当地使用它来设置部分计数器。不幸的是,它不知道如何处理表达式的其余部分,因此它再次将其吐出,在页面顶部写入“.2”。这很难看,所以我想摆脱它。我的直觉是,最好的方法是暂时重新定义\label
within,\exportcounters
以便它只将最顶层的分段命令发送到.aux
和.toc
,但我的纯文本还不够好,不知道从哪里开始。
残留问题
所以我的问题是:有人能给我提示如何\label
适当地重新定义 -command 吗?换句话说,我如何让它告诉 -file,.aux
而\newlabel{endfile}{{<thesection>}{12}}
不是\newlabel{endfile}{{<\thesection>.<\thesubsection>}{12}}
尽管嵌入在子部分或更深层?(或者,如何在将其输入之前从 '.' 中删除部分\setcounter{section}{...}
?我试过了,\SubStringBefore
但这会产生一个字符串而不是一个数字,在编译期间抛出“缺少数字,视为零”错误。)
我遇到的第二个问题是,\newpage
我需要在两个文档中插入一个明确的结束位置,否则它将运行两页的文本。此行为似乎是由(或和xr
的结合)触发的。这是一个已知问题吗?是否有任何不涉及明确s 的解决方法?xr
lipsum
\newpage
另一个(实际上相当小的)问题是 pdflatex 抱怨序言中的使用\ref
(“缺少 \begin{document}”),但如果结果看起来正确,我很乐意忽略它。
或者也许可以从完全不同的角度来解决这个问题?是否有一个工具可以帮助那些不太了解纯 TeX 的人将.cls
格式化命令打包到环境中?类似的东西\importasenvironment{<environmentname>}{<classname>.cls}
?
答案1
可以通过包zref
、模块lastpage
和来从以前文档中导入页面和章节值xr
。
第一份文件
第一个文档DocumentA
保存了由包设置的标签写入的属性pagevalue
列表。sectionvalue
LastPage
LastPage
zref-lastpage
示例文件DocumentA.tex
,第一个文档:
\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}
软件包zref-lastpage
完成的工作:
- 到达真实的文档结束(通过包
atveryend
)。 .aux
通过\immediate\write
.写入文件\label
可获得\write
正确的页码,但这需要输出下一页。最后一页之后没有这样的页面。此外,该包还负责更正页码。
该.aux
文件包含:
\zref@newlabel{LastPage}{\default{4}\page{2}\abspage{2}\pagevalue{2}\sectionvalue{4}}
下一个文档
下一个文档从上一个文档的标签导入数据LastPage
并设置计数器。它还使用上一个文档的代码来定义属性并为下一个文档写入计数器值。
示例文件DocumentB.tex
,下一个文档:
\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}
然后第二份文件的第一部分Section E of second document
编号为5,从第3页开始。
答案2
Heiko Oberdiek 的答案完美地解决了几个相互构建的文档的基本情况。
对于主文件包含要包含的章节之前和之后部分的情况,即在文档中的任意位置将其计数器传递给外部文档,然后检索文档中相同或另一个外部文档的计数器,我通过定义\importcounters
和\exportcounters
命令并在适当的位置调用它们进行了调整。它可能可以进一步减少,但这是我目前在 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}
(在 中,唯一的变化是我用而不是 来DocumentB.tex
喂计数器。)pre-LastIntroPage
pre-LastPage
我的下一个目标是研究如何write18
使主文件暂停并转到依赖文件的编译然后再继续,但这是一个单独的问题。