Вставка предопределенных номеров абзацев в верхний колонтитул страницы

Вставка предопределенных номеров абзацев в верхний колонтитул страницы

Я имею дело с переведенными текстами, имеющими номера "абзацев", которые уже определены в источнике, с которыми я должен соблюдать последовательность. Поэтому я не могу использовать \theparagraphдля генерации номеров. Чтобы добавить сложности, многие абзацы не имеют номеров; и, кроме того, некоторые абзацы имеют диапазон (1-10 и т. д.). Эти предопределенные номера уже присутствуют в моем документе.

Я хотел бы представить эти номера в заголовке страницы, а не перед абзацем, по эстетическим причинам. Я использую fancyhdr. В заголовке страницы они будут отображаться на обеих страницах и будут предшествовать номеру раздела (не главы). Таким образом, каждый заголовок страницы будет включать следующее:

АБ-С

Где A — номер раздела, B — номер первого абзаца на странице (который, конечно, часто будет продолжением последнего абзаца с предыдущей страницы), а C — номер последнего абзаца на странице.

Это должно быть достаточно сложно, но вдобавок нам нужно обрабатывать диапазоны. В таких случаях для нашего числа B мы выбираем первую цифру в диапазоне; для числа C мы выбираем последнюю.

Таким образом, если первый абзац на странице имеет диапазон 10–14, а последний — 16–18, то заголовок этой страницы будет иметь значение A.10–18.

Надеюсь, это понятно. Пожалуйста, дайте мне знать, если потребуются дополнительные пояснения.

Еще несколько деталей. Разделы начинаются на новой странице, что я делаю с помощью titlesec. (По какой-то причине MWE, который я привожу ниже, помещает раздел 2 в заголовок до того, как он фактически начинается, я не проверял это.)

Разделы, как и абзацы, имеют жестко заданные номера, поэтому мы можем использовать их, если это облегчит задачу. Однако, в отличие от абзацев, номера разделов просты и последовательны, поэтому я считаю, что, вероятно, проще позволить LaTeX подсчитывать их, поскольку это то, что он хочет делать по умолчанию. Но любой из вариантов хорош.

Вот MWE. Я не уверен, как лучше это сделать, но я изменил MWE из моего оригинального примера на адаптированный из ответа Эндрю ниже. Я принял его ответ как правильный, что в значительной степени так и есть, но при использовании кода я обнаружил ряд ошибок, которые я перечисляю ниже.

\documentclass{book}
\usepackage{lipsum}
\setlipsumdefault{1}
\usepackage{titlesec}

% fancy headings as defined by the OP except we need to be more careful
% with plain headings
\usepackage{fancyhdr}
\fancypagestyle{plain}{% need to reset \firstpara on pages without headers
  \fancyhf{} % clear all header and footer fields
  \renewcommand{\headrulewidth}{0pt}
  \fancyfoot[C]{\bfseries \thepage}
  \xdef\firstpara{\lastpara}
}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[LE,RO]{\thepage}
\fancyhead[CO]{\rightmark}
\renewcommand{\sectionmark}[1]{%
   \markright{#1}%
   \def\firstpara{1}\def\lastpara{1}% reset counters each section
}
\fancyhead[CE]{\leftmark}
\renewcommand{\chaptermark}[1]{\markboth{#1}{}}
\fancyhead[LO,RE]{\thesection.\theparagraph}

\newcommand{\sectionbreak}{\clearpage\thispagestyle{plain}}
\renewcommand\thesection{\arabic{section}}

% now the macros for tracking the paragraph numbers
\def\firstpara{1}%    set to 1 by default
\def\lastpara{1}% set to 1 by default
\def\setparagraph#1-#2-#3|{%
   % if \firstpara=0 => new page => set \firstpara
   \ifnum\firstpara=0\def\firstpara{#1}\fi%
   % if #2=0 => only #1 is meaningful to set \lastpara to this
   % otherwise use #2
   \ifnum#2=0\def\lastpara{#1}\else\def\lastpara{#2}\fi%
}
\def\paragraph#1{%\textbf{#1}\space
  \setparagraph#1-0-|%
}
\def\theparagraph{%
  % if \firstpara=\lastpara print only \firstpara otherwise print a range
  \ifnum\firstpara=\lastpara\firstpara\else\firstpara--\lastpara\fi
  % reset firstpara and lastpara
  \xdef\firstpara{\lastpara}%
  %\let\lastpara\relax%
}

% back to the MWe
\begin{document}

\null
\pagestyle{empty}

\newpage

\newpage

\pagestyle{fancy}

\chapter{A Chapter}

\section{First Section}

\paragraph{1}\lipsum

\paragraph{2}\lipsum

\paragraph{3-5}\lipsum

\paragraph{6}\lipsum

\paragraph{7-17}\lipsum

\paragraph{18}\lipsum

\paragraph{19-20}\lipsum

\paragraph{21-28}\lipsum

\paragraph{29}\lipsum

\paragraph{30}\lipsum

\section{Second Section}

\paragraph{1}\lipsum

\paragraph{2}\lipsum

\paragraph{3-5}\lipsum

\paragraph{6}\lipsum

\paragraph{7-17}\lipsum

\paragraph{18}\lipsum

\paragraph{19-20}\lipsum

\paragraph{21-28}\lipsum

\paragraph{29}\lipsum

\paragraph{30}\lipsum

\section{Third Section}

\paragraph{1}\lipsum

\paragraph{2}\lipsum

\paragraph{3}\lipsum

\paragraph{4}\lipsum

\paragraph{5}\lipsum

\paragraph{6}\lipsum

\paragraph{7}\lipsum

\paragraph{8}\lipsum

\paragraph{9}\lipsum

\paragraph{10}\lipsum

\paragraph{11}\lipsum

\paragraph{12}\lipsum

\paragraph{13}\lipsum

\paragraph{14}\lipsum

\paragraph{15}\lipsum

\paragraph{16}\lipsum

\paragraph{17}\lipsum

\paragraph{18}\lipsum

\paragraph{19}\lipsum

\paragraph{20}\lipsum

\end{document}

Вот ошибки, о которых я знаю:

  1. Стиль страницы с новым разделом простой, поэтому заголовка нет, что правильно. Однако на следующей странице, т. е. на первой странице раздела, имеющего заголовок, номер первого абзаца всегда равен 1, тогда как это должен быть соответствующий номер абзаца для первого абзаца на этой странице, как и везде. На самом деле я не могу заставить эту ошибку отображаться в MWE, но она отображается в моем полном документе. Предложение Эндрю заменить 1 на 0 в не \sectionmarkрешило проблему. Я обновлю MWE, если смогу заставить эту ошибку отображаться.

  2. В титульном листе появляется некоторый материал верхнего/нижнего колонтитула, тогда как все они должны быть пустыми в стиле страницы. Они появляются на страницах, которые предшествуют любому заголовку. Смотрите вторую пустую страницу MWE.

  3. В некоторых случаях подсчет номеров абзацев неверен. Это видно в MWE на последних двух страницах. Предпоследняя страница должна быть 16-19, но это 16-20; а последняя страница должна быть 19-20. Это встречается довольно часто в моем полном документе и, по-видимому, происходит, когда есть сирота.

  4. На последней странице также показана еще одна небольшая ошибка: когда есть «диапазон» только из одного абзаца, то должен отображаться только один. Например, вместо «20-20» должно быть только «20».

  5. Обработка диапазонов абзацев не совсем соответствует указанному. Третий абзац, например, имеет диапазон 3-5, поэтому заголовок страницы 4 должен начинаться спервыйабзац этого диапазона, но вместо этого он имеет 5-20.

  6. Последний заголовок раздела дает неправильный номер раздела. Он имеет номер раздела следующего раздела. Страница 5 MWE, например, имеет номер 2.20-30, но она находится в первом разделе, поэтому она должна быть 1.20-30.

решение1

Хороший вопрос! Вот один из способов сделать это. Я перехватил команду \paragraphтак, чтобы она печатала аргумент, который ей дан using \textbf{#1}, а затем устанавливала счетчики абзацев \firstparaи \lastpara, вызывая команду \setparagraphс #1-0-|аргументом.

Макрос \setparagraphнемного сложен, так как ему нужно принимать аргументы, которые могут выглядеть как одно число, например 6, или как диапазон чисел, например 7-21. Он делает это, ожидая три аргумента, которые должны быть заданы в формате #1-#2-#3|. Так что если 6это аргумент для \paragraph then the arguments for\setparagraph are#1=6 ,#2=0 and#3 is empty. If7-21 is the argument to\paragraph then #1=7, #2=21и #3=0для \setparagaph.

После этого я играю в некоторые игры, чтобы убедиться, что \firstparaи \lastparaвсегда установлены на соответствующие значения с проверками типа \ifnum\firstpara=0.... Диапазоны абзацев в заголовках печатаются с использованием \theparagraph, и этот макрос также сбрасывает \firstparaи \lastparaтак, чтобы счетчики были правильными для следующей страницы.

Вот пример выходных данных (с номерами абзацев для ясности):

введите описание изображения здесь

и вот код (с номерами абзацев для справки):

РЕДАКТИРОВАТЬНемного обновил код, чтобы учесть пункты 1-6 в обновленном посте.

\documentclass{book}
\usepackage{lipsum}
\setlipsumdefault{1}
\usepackage{titlesec}
%\usepackage[hmargin=63mm,vmargin=68mm]{geometry}

% fancy headings as defined by the OP except we need to be more careful
% with plain headings
\usepackage{fancyhdr}
\fancypagestyle{empty}{
  \fancyhf{}
  \renewcommand{\headrulewidth}{0pt}
}
\fancypagestyle{plain}{
  \fancyhf{}% clear all header and footer fields
  \renewcommand{\headrulewidth}{0pt}
  \renewcommand{\footrulewidth}{0pt}
  \fancyfoot[C]{\bfseries \thepage}%
  % need to reset \firstpara on pages without headers
  \xdef\firstpara{\midpara}%
}
\fancypagestyle{paragraphs}{
  \fancyhead[LE,RO]{\thepage}
  \fancyhead[CO]{\rightmark}
  \fancyhead[CE]{\leftmark}
  \fancyhead[LO,RE]{\ifnum\firstpara>0\relax\thesection.\theparagraph\fi}
}
\renewcommand{\chaptermark}[1]{\markboth{#1}{}}
\renewcommand{\sectionmark}[1]{%
   \markright{#1}%
   % reset paragraph counters in each section
   \def\firstpara{0}\def\midpara{0}\def\lastpara{0}
}
%\newcommand{\sectionbreak}{\newpage\thispagestyle{plain}}
\let\realSection\section
\renewcommand\section[2][\relax]{\clearpage%
  \thispagestyle{plain}%
  \ifx#1\relax\relax\realSection{#2}%
  \else\realSection[#1]{#2}%
  \fi
}
\renewcommand\thesection{\arabic{section}}

% now the macros for tracking the paragraph numbers
\def\firstpara{0}%    set to 1 by default
\def\midpara{0}%    set to 1 by default
\def\lastpara{0}% set to 1 by default
\def\setparagraph#1-#2-#3|{\def\midpara{#1}%
   % if \firstpara=0 => new page => set \firstpara
   \ifnum\firstpara=0\relax\def\firstpara{#1}\fi%
   % if #2=0 => only #1 is meaningful to set \lastpara to this
   % otherwise use #2
   \ifnum#2=0\relax\def\lastpara{#1}%
   \else\def\lastpara{#2}%
   \fi%
}
\def\paragraph#1{\textbf{#1}\space
  \setparagraph#1-0-|%
}
\def\theparagraph{%
  % if \firstpara=\lastpara print only \firstpara otherwise print a range
  \ifnum\firstpara=\lastpara\relax\firstpara\else\firstpara--\lastpara\fi
  % reset firstpara and lastpara
  \xdef\firstpara{\midpara}%
  %\let\lastpara\relax%
}

% back to the MWe
\begin{document}

\null
\pagestyle{empty}

\newpage

\newpage

\pagestyle{paragraphs}

\chapter{A Chapter}

\section{First Section}

\paragraph{1}\lipsum

\paragraph{2}\lipsum

\paragraph{3-5}\lipsum

\paragraph{6}\lipsum

\paragraph{7-17}\lipsum

\paragraph{18}\lipsum

\paragraph{19-20}\lipsum

\paragraph{21-28}\lipsum

\paragraph{29}\lipsum

\paragraph{30}\lipsum

\section{Second Section}

\paragraph{1}\lipsum

\paragraph{2}\lipsum

\paragraph{3-5}\lipsum

\paragraph{6}\lipsum

\paragraph{7-17}\lipsum

\paragraph{18}\lipsum

\paragraph{19-20}\lipsum

\paragraph{21-28}\lipsum

\paragraph{29}\lipsum

\paragraph{30}\lipsum

\section{Third Section}

\paragraph{1}\lipsum

\paragraph{2}\lipsum

\paragraph{3}\lipsum

\paragraph{4}\lipsum

\paragraph{5}\lipsum

\paragraph{6}\lipsum

\paragraph{7}\lipsum

\paragraph{8}\lipsum

\paragraph{9}\lipsum

\paragraph{10}\lipsum

\paragraph{11}\lipsum

\paragraph{12}\lipsum

\paragraph{13}\lipsum

\paragraph{14}\lipsum

\paragraph{15}\lipsum

\paragraph{16}\lipsum

\paragraph{17}\lipsum

\paragraph{18}\lipsum

\paragraph{19}\lipsum

\paragraph{20}\lipsum

\end{document}

Примечания

  1. Проблема 2была в том, что пустая страница не была на самом деле пустой. Точнее, она не устанавливалась \headrulewidthна ноль ноль.

  2. Я не использую fancyhdr, так что это вполне может быть неправильно, но мне кажется, что вам лучше определить свой собственный стиль страницы. Я определил paragraphстиль страницы выше. Я сделал это, потому что мне показалось, что fancyстиль страницы не очень хорошо сочетается с другими стилями.

  3. Команда \sectionbreak, используемая, titlesecкажется, является причиной вашей проблемы 6. Я подозреваю, что она увеличивает счетчик разделов перед вызовом, \sectionbreakпоэтому заголовок был неправильным. Я обошёл это, избежав \sectionbreakи вместо этого переопределив команду раздела.

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