Цель

Цель

Цель

Моя цель — иметь непрерывные счетчики страниц (и, возможно, разделов) для нескольких независимых документов. Цель — кумулятивная диссертация, где каждая статья должна максимально сохранять макет журнала, но школа требует непрерывной пагинации. Возможно, это будет выглядеть уродливо, как несколько склеенных вместе статей, но по сути это то, чем оно является.

Я знаю, что чистый способ продолжить, вероятно, будет заключаться в извлечении информации о форматировании из файлов журналов .clsи упаковке в окружения, но это, вероятно, будет большой работой для кого-то столь неграмотного в простом, TeXкак я. Поэтому я попробовал, с некоторым успехом, альтернативный подход: хак с использованием пакета xr. Но есть некоторые остаточные проблемы.

Позвольте мне сначала объяснить, чем я занимаюсь:

Моя установка

У меня есть основной файл, который включает введение и выводы. Его pagecounter и sectioncounter должны начинаться с 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», чтобы получить непрерывную нумерацию страниц и разделов. (У меня есть скрипт оболочки, который делает это за меня.) У меня также есть скрипт Python для извлечения всей tocнеобходимой информации из различных auxфайлов и компиляции основного файла с ней в качестве своего, tocчтобы получить оглавление, ссылающееся на все разделы, независимо от того, в каком файле они находятся, что в основном работает так, как и должно.

Как и должно быть, \addtocounter{page}{\pageref{introendfile}}импортирует pagecounter в конце введения в file1. Также, как и должно быть, \setcounter{section}{\ref{introendfile}}съедает часть section возвращаемого значения внешних ссылок (в данном случае 1.2) и соответствующим образом использует ее для установки section counter. К сожалению, он не знает, что делать с остальной частью выражения, поэтому он снова выплевывает его, записывая ".2" в верхней части страницы. Это уродливо, поэтому я пытаюсь от этого избавиться. Моя догадка заключается в том, что лучшим методом для этого было бы временно переопределить \labelвнутри \exportcountersтак, чтобы он отправлял только самую верхнюю команду секционирования в .auxand .toc, но мой простой текст недостаточно хорош, чтобы знать, с чего начать.

Остаточные проблемы

Итак, мой вопрос: может ли кто-нибудь подсказать, как \labelправильно переопределить -команду? Другими словами, как мне заставить ее сообщать -файлу, .auxа \newlabel{endfile}{{<thesection>}{12}}не \newlabel{endfile}{{<\thesection>.<\thesubsection>}{12}}несмотря на то, что она встроена в подраздел или глубже? (Или как мне убрать часть от '.' перед тем, как поместить ее в \setcounter{section}{...}? Я пробовал \SubStringBefore, но это выдает строку вместо числа, выдавая мне ошибку «Отсутствует число, рассматривается как ноль» во время компиляции.)

Вторая проблема, с которой я столкнулся, заключается в необходимости вставить explicit \newpageтам, где я хочу, чтобы первая страница заканчивалась в обоих документах, иначе он будет продолжаться на протяжении двух страниц текста. Такое поведение, похоже, вызвано xr(или конъюнкцией xrand lipsum). Известна ли эта проблема, и есть ли какие-либо обходные пути, которые не включают explicit \newpages?

Другая (на самом деле совсем незначительная) проблема заключается в том, что 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

Ответ Хайко Обердика идеально решает базовый случай нескольких документов, которые просто дополняют друг друга.

Для несколько более сложного случая основного файла, который включает части как до, так и после глав, которые должны быть включены, т. е. который передает свои счетчики внешнему документу в произвольной точке документа, а затем извлекает счетчики того же или другого внешнего документа также внутри документа, я сумел сделать подстройку, определив команды \importcountersи \exportcountersи вызвав их в соответствующих местах. Вероятно, это можно еще сократить, но это самое близкое, что я получил на данный момент, основываясь на посте Хайко Обердика.

\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чтобы основной файл остановился и перешел к компиляции зависимых файлов, прежде чем двигаться дальше, но это тема для отдельного вопроса.

Связанный контент