7

I am dealing with translated texts that have "paragraph" numbers which are already defined in the source, with which I must keep consistency. Hence I can't use \theparagraph to generate the numbers. To add to the complexity, many paragraphs don't have numbers; and in addition, some paragraphs have a range (1-10, etc.). These predefined numbers are already present in my document.

I would like to present these numbers in the page header rather than in front of the paragraph, for aesthetic reasons. I am using fancyhdr. In the page header they would appear on both pages, and would be preceded by the section number (not chapter). So each page header would include the following:

A.B-C

Where A is the section number, B is the number of the first paragraph on the page—which will, of course, often be a continuation of the last paragraph from the previous page—and C is the number of the last paragraph on the page.

This should be complicated enough, but in addition we need to handle ranges. In such cases, for our B number, we select the first digit in the range; for the C number, we select the last.

So if the first paragraph on the page had the range 10-14, and the last had 16-18, the header for that page would have A.10-18.

I hope that's clear, please let me know if additional explanation is needed.

A few more details. Sections start on a new page, which I do using titlesec. (For some reason the MWE I give below puts section 2 in the header before it actually starts, I haven't checked into this.)

The sections, like the paragraphs, have hard-coded numbers, so we can use these if it makes it easier. However, unlike the paragraphs, the section numbers are simple and sequential, so I figure it is probably simpler to let LaTeX count them, since that's what it wants to do by default. But either way is fine.

Here is a MWE. I'm not sure of the best way to do this, but I have changed the MWE from my original example to one adapted from Andrew's answer below. I've accepted his answer as correct, which to a large degree it is, but on using the code I discovered a number of bugs, which I list below.

\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}

Here's the bugs I am aware of:

  1. The pagestyle with a new section is plain, so there is no header, which is correct. However, on the next page, i.e. the first page in a section that has a header, the first paragraph number is always 1, whereas it should be the relevant paragraph number for the first paragraph on that page, as it is everywhere else. In fact I can't get this bug to show up in the MWE, but it does in my full document. Andrew's suggestion to replace 1 with 0 in the \sectionmark didn't fix the problem. I'll update the MWE if I can get this bug to show.

  2. In the frontmatter some header/footer material appears, whereas these should all be pagestyle empty. They appear on the pages that precede any heading. See the second blank page of the MWE.

  3. In some cases the counting of the paragraph numbers is incorrect. This appears in the MWE on the last two pages. The second last page should be 16-19, but it is 16-20; and the last page should be 19-20. This occurs fairly frequently in my full document, and appears to happen when there is an orphan.

  4. The last page also shows another minor bug: when there is a "range" of only one paragraph, it should show only one. E.g. instead of "20-20" it should have just "20".

  5. The handling of paragraph ranges is not exactly as specified. The third paragraph, for example, has a range of 3-5, so the page 4 header should start with the first paragraph of this range, but instead it has 5-20.

  6. The last header of a section gives the incorrect section number. It has the section number of the following section. Page 5 of the MWE, for example, has the number 2.20-30, but it is in the first section, so it should be 1.20-30.

  • without compilable example we can't see. – touhami Jul 29 '15 at 5:42
  • What happens when you have paragraph A.B at the top of the page, followed by a new section and paragraph C.D at the bottom of the page? How would you present that in the header? – Werner Jul 29 '15 at 6:41
  • I've supplied a MWE, though I'm not sure how much use it will be. Obviously it produces output that I don't want. @Werner, sections start a new page, so this problem won't arise. I've added this to the original post to clarify. – Sujato Jul 29 '15 at 9:41
  • 1
    I have updated my code to address 1-5. I don't believe that 4 was ever an issue but I have checked and it is not a problem currently. Similarly 3 seemed OK before but it does works now. I suspect that 6 is a fancyhr problem but I have not confirmed this. There is one more problem: if TeX moves an entire paragraph from the bottom of one page to the top of the next then last paragraph number on the first of these pages will be wrong and the first paragraph number on the second page will be wrong. Not sure what to do about this, however. Will think about it. – Andrew Aug 5 '15 at 14:19
  • 1
    Problem 2 is an artifact of your MWE: it is caused the \pagestyle{empty} command. It sounds like you want \pagestyle{plain} here. Similarly, 6 seems to be caused by some titlesec weirdness. Finally, 5 is fixed. See edit below and, in particular, the note at the end. – Andrew Aug 6 '15 at 13:45
7

Nice question! Here is one way of doing this. I have hijacked the \paragraph command so that it prints the argument that it is given using \textbf{#1} and it then sets paragraph counters, \firstpara and \lastpara, by calling the command \setparagraph with #1-0-| as the argument.

The \setparagraph macro is a little tricky as it needs to accept arguments that can look like either a single number, such as 6, or a range of numbers, such as 7-21. It does this by expecting three arguments that need to given in the format #1-#2-#3|. So if 6 is the argument to \paragraph then the arguments for\setparagraphare#1=6,#2=0and#3is empty. If7-21is the argument to\paragraph then #1=7, #2=21 and #3=0 for \setparagaph.

After this I play some games to make sure that \firstpara and \lastpara are always set to appropriate values with checks like \ifnum\firstpara=0.... The paragraph ranges in the headings are printed using \theparagraph and this macro also resets \firstpara and \lastpara so that the counters will be correct for the next page.

Here is some sample output (with the paragraph numbers in to make it clear):

enter image description here

and here is the code (with the paragraph numbers included for reference):

EDIT Updated code slightly to cater for 1-6 in updated post.

\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}

Notes

  1. Problem 2 was due to the empty pagetysle not really being empty. More precisely, it didn't set \headrulewidth to zero zero.

  2. I don't use fancyhdr so this could well be wrong, but it seems to me that you are better off defining your own fancy page style. I have defined a paragraph page style above. I did this because I fond the fancy page style was not playing well with the other styles.

  3. The \sectionbreak command used by titlesec seems to be the cause of your problem 6. I suspect that it is incrementing the section counter before calling \sectionbreak so this is what caused the header to be wrong. I have hacked around this by avoiding \sectionbreak and instead redefining the section command.

  • I got interrupted in my previous comment, sorry. What I meant to say was: This is very close to what I want, congrats @Andrew, some serious TeX-fu there! A couple more refinements are needed, though: first, the initial paragraph number in the header ("B" in my OP), is the first paragraph number on that page—it needs to be the last paragraph number of the previous page. (One reason is that in some cases there will not be any numbers actually appearing on a page.) Second, I want to have the paragraph numbers in the header instead of at the start of the paragraphs, not in addition. – Sujato Jul 29 '15 at 12:59
  • 1
    @Sujato I have just edited the solution in light of your comments. The image still contains paragraph numbers so that you can see what is happening but he code no longer produces them. You will also need to reset \firstpara and \lastpara at the start of each chapter. Must do some work now:) – Andrew Jul 29 '15 at 13:13
  • That's perfect, thanks so much. I am out of my depth here, so I have no idea how to reset \firstpara and \lastpara, so if you get a chance to let me know that it would be much appreciated. – Sujato Jul 29 '15 at 13:19
  • @Sujato Assuming that paragraph numbers reset at each section my last edit should take care of this---if not move the extra code from \sectionmark to \chaptermark. – Andrew Jul 29 '15 at 13:31
  • I've been using your code and I've discovered a couple of bugs. (1) The pagestyle with a new section is plain, so there is no header, which is correct. However, on the next page, i.e. the first page in a section that has a header, the first paragraph number is always 1, whereas it should be the relevant paragraph number for the first paragraph on that page, as it is everywhere else. (2) In the frontmatter some header/footer material appears, whereas these should all be pagestyle empty. They appear on the pages that precede any heading, including the ToC. – Sujato Jul 31 '15 at 9:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.