在頁首中插入預先定義的段落編號

在頁首中插入預先定義的段落編號

我正在處理的翻譯文字具有已在來源中定義的「段落」編號,我必須保持一致性。因此我不能用來\theparagraph產生數字。為了增加複雜性,許多段落沒有編號;此外,有些段落有範圍(1-10等)。這些預定義的數字已存在於我的文件中。

出於美觀原因,我想在頁眉中而不是在段落前面顯示這些數字。我正在使用 fancyhdr。在頁眉中,它們將出現在兩頁上,並且前面帶有節號(而不是章節)。因此每個頁面標題將包含以下內容:

AB-C

其中 A 是節號,B 是頁面上第一個段落的編號(當然,這通常是上一頁最後一個段落的延續),C 是頁面上最後一個段落的編號。

這應該足夠複雜,但此外我們還需要處理範圍。在這種情況下,對於 B 編號,我們選擇範圍中的第一個數字;對於 C 號,我們選擇最後一個。

因此,如果頁面上第一段的範圍為 10-14,最後一段的範圍為 16-18,則該頁面的頁首將為 A.10-18。

我希望這是清楚的,如果需要額外的解釋,請告訴我。

更多細節。各部分從一個新頁面開始,我使用 titlesec 進行此操作。 (出於某種原因,我在下面給出的 MWE 在實際開始之前將第 2 部分放入標題中,我還沒有對此進行檢查。)

這些部分,就像段落一樣,有硬編碼的數字,所以我們可以使用它們,如果它更容易的話。然而,與段落不同的是,節號是簡單且連續的,所以我認為讓 LaTeX 對它們進行計數可能更簡單,因為這就是它默認想要做的。但無論哪種方式都可以。

這是一個 MWE。我不確定執行此操作的最佳方法,但我已將 MWE 從原始範例更改為改編自下面 Andrew 的答案的範例。我已經接受他的答案是正確的,這在很大程度上是正確的,但是在使用程式碼時我發現了許多錯誤,我在下面列出了這些錯誤。

\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 中,但它出現在我的完整文件中。 Andrew 建議將 1 替換為 0 並\sectionmark沒有解決問題。如果我能顯示這個錯誤,我將更新 MWE。

  2. 在 frontmatter 中會出現一些頁首/頁尾資料,而這些內容都應該是空的頁面樣式。它們出現在任何標題之前的頁面上。請參閱 MWE 的第二個空白頁。

  3. 在某些情況下,段落編號的計數不正確。這齣現在 MWE 的最後兩頁。倒數第二頁應該是16-19,但卻是16-20;最後一頁應該是19-20。這種情況在我的完整文件中經常發生,並且似乎在有孤兒時發生。

  4. 最後一頁也顯示了另一個小錯誤:當「範圍」只有一個段落時,它應該只顯示一個。例如,不應使用“20-20”,而應僅使用“20”。

  5. 段落範圍的處理不完全依照指定。例如,第三段的範圍為 3-5,因此第 4 頁標題應以第一的這個範圍的段落,但它有 5-20 個。

  6. 節的最後一個標題給了不正確的節號。它有以下部分的部分編號。例如,MWE 第 5 頁的編號為 2.20-30,但它位於第一部分,因此應為 1.20-30。

答案1

好問題!這是執行此操作的一種方法。我劫持了該\paragraph命令,以便它會列印給定的參數\textbf{#1},然後設定段落計數器,\firstpara\lastpara透過呼叫該命令\setparagraph作為#1-0-|參數。

\setparagraph巨集有點棘手,因為它需要接受可以看起來像單一數字(例如6)或一系列數字(例如 )的參數7-21。它透過期望需要以格式給出的三個參數來實現這一點#1-#2-#3|。所以 if是\setparagraph #1=6 #2=0 #3 7-21 \paragraph then6的參數,而for 。\paragraph then the arguments forare,andis empty. Ifis the argument to#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是由於空的 pagetysle 並不是真正空的。更準確地說,它沒有設定\headrulewidth為零。

  2. 我不使用,fancyhdr所以這很可能是錯誤的,但在我看來,您最好定義自己的精美頁面樣式。我paragraph在上面定義了頁面樣式。我這樣做是因為我喜歡fancy頁面樣式與其他樣式不能很好地配合。

  3. \sectionbreak使用的命令似乎titlesec是導致您的問題的原因6。我懷疑它在調用之前增加了節計數器,\sectionbreak因此這就是導致標頭錯誤的原因。我透過避免\sectionbreak並重新定義部分命令來解決這個問題。

相關內容