
目標
我的目標是為多個獨立文件提供連續的頁面(可能還有部分)計數器。目的是一篇累積性論文,每篇論文應盡可能保留期刊的佈局,但學校要求連續分頁。可以說它看起來很醜,就像幾張紙黏在一起一樣,但本質上就是這樣。
我知道,乾淨的方法可能是從日誌檔案中提取格式資訊並將其打包到環境中,但這對像我這樣.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
inside \exportcounters
,以便它只將最上面的分段命令發送到.aux
和.toc
,但我的純文字不夠好,不知道從哪裡開始。
遺留問題
所以我的問題是:任何人都可以給我提示如何\label
適當地重新定義 - 命令嗎?換句話說,我如何讓它告訴.aux
文件\newlabel{endfile}{{<thesection>}{12}}
,而不是\newlabel{endfile}{{<\thesection>.<\thesubsection>}{12}}
儘管嵌入到小節或更深層? (或者,如何在將其輸入到 '.' 之前將其剝離\setcounter{section}{...}
?我已經嘗試過\SubStringBefore
,但這會產生一個字符串而不是數字,在編譯過程中向我拋出“缺少數字,被視為零”錯誤。
我遇到的第二個問題是,需要\newpage
在兩個文件中我希望第一頁結束的位置插入明確的內容,否則它將運行兩頁的文字。這種行為似乎是由(或和xr
的結合)觸發的。這是一個已知問題嗎?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
使主文件暫停並在繼續之前移動到依賴文件的編譯,但這是一個單獨的問題。