5

I use a counter for my Questions. I use fancyhdr. I need to show the first and last values of the value of the counter on a page at its header.

In the following example, Page 2 header should read: Questions: 1-2

Page 3 header should read: Questions: 2-3

Page 4 header should read: Questions: 4-5

Page 5 header should read: Question: 6

I tried several suggestions given on the internet. None worked for me! In particular on page 3, when LaTeX decides to put question 4 on the next page, the counter is already incremented and the header then reads Questions 2-4, whereas Question 4 is now totally on the next page. And of course I could never get Question: 6 alone on the header.

Here is my LaTeX file:

%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[12pt]{amsbook}
\usepackage{fancyhdr}
\usepackage{lipsum}

\newcounter{beans}
\setcounter{beans}{1}

\pagestyle{fancy}
\fancyhf{}
\fancyhead[RE]{Dante}
\fancyhead[LO]{Meaning of Life}
\fancyfoot[LE,RO]{\thepage}

\textheight 7cm

\begin{document}
\chapter{Gate}
{\bf \thebeans.  Question: }
\lipsum[\thebeans]
\stepcounter{beans}

{\bf \thebeans.  Question: }
\lipsum[\thebeans]
\stepcounter{beans}

{\bf \thebeans.  Question: }
\lipsum[\thebeans]
\stepcounter{beans}

{\bf \thebeans.  Question: }
\lipsum[\thebeans]
\stepcounter{beans}

{\bf \thebeans.  Question: }
Fusce mauris. Vestibulum luctus nibh at lectus.
Sed bibendum, nulla a faucibus semper, leo velit ultricies tellus, ac
venenatis arcu wisi vel nisl. Vestibulum diam. Aliquam pellentesque,
augue quis sagittis posuere, turpis lacus congue quam, in hendrerit
risus eros eget felis. Maecenas eget erat in sapien mattis porttitor.
Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo
\stepcounter{beans}

{\bf \thebeans.  Question: }
\lipsum[\thebeans]
Fusce mauris. Vestibulum luctus nibh at lectus.
Sed bibendum, nulla a faucibus semper, leo velit ultricies tellus, ac
venenatis arcu wisi vel nisl. Vestibulum diam. Aliquam pellentesque,
augue quis sagittis posuere, turpis lacus congue quam, in hendrerit
risus eros eget felis. Maecenas eget erat in sapien mattis porttitor.
Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo
\stepcounter{beans}

\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%

Thank you.

  • i only know how to do this with plain tex. the value of a counter needs to be put into a \mark. then, in the header, the \firstmark and \lastmark are called (these marks are coordinated by the output routine, which "knows" what is on each page). the best way to do this is probably to create an environment that steps the counter at the beginning, not at the end, and immediately marks it. i will try to work on this later, unless someone else gets there first. – barbara beeton Apr 10 '18 at 17:09
  • Do you want to replace the current header, or add to the other side? – John Kormylo Apr 10 '18 at 22:10

2 Answers2

4

Instead of writing to the aux file you can use mark registers. This has the advantage of only needing one LaTeX run instead of two. The code also adresses the comments from the other answer: "Question 2-2" is replaced by "Question 2" and Questions running over multiple pages are supported.

\documentclass[12pt]{amsbook}
\usepackage{fancyhdr}
\usepackage{lipsum}

\newmarks\beansmark
\newcounter{beans}

\newcommand{\beancounter}{%
  \leavevmode
  \stepcounter{beans}%
  \marks\beansmark{\arabic{beans}}%
}

\newcommand{\beanhead}{%
  \begingroup
    \edef\firstbean{\firstmarks\beansmark}%
    \edef\lastbean{\botmarks\beansmark}%
    \ifx\firstbean\lastbean
      Question \firstbean
    \else
      Question \firstbean--\lastbean
    \fi
  \endgroup
}

\pagestyle{fancy}
\fancyhf{}
\fancyhead[RE]{Dante}
\fancyhead[LE]{\beanhead}
\fancyhead[LO]{Meaning of Life}
\fancyhead[RO]{\beanhead}
\fancyfoot[LE,RO]{\thepage}

\textheight 7cm

\begin{document}
\chapter{Gate}

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]


\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]

\beancounter
{\bf \thebeans.  Question: }
Fusce mauris. Vestibulum luctus nibh at lectus.
Sed bibendum, nulla a faucibus semper, leo velit ultricies tellus, ac
venenatis arcu wisi vel nisl. Vestibulum diam. Aliquam pellentesque,
augue quis sagittis posuere, turpis lacus congue quam, in hendrerit
risus eros eget felis. Maecenas eget erat in sapien mattis porttitor.
Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]
Fusce mauris. Vestibulum luctus nibh at lectus.
Sed bibendum, nulla a faucibus semper, leo velit ultricies tellus, ac
venenatis arcu wisi vel nisl. Vestibulum diam. Aliquam pellentesque,
augue quis sagittis posuere, turpis lacus congue quam, in hendrerit
risus eros eget felis. Maecenas eget erat in sapien mattis porttitor.
Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo

\end{document}
  • Thank you Marcel. Your code achieves everything I wished to see on the headers. Best of luck with your math studies. – Sinan Sertoz Apr 11 '18 at 09:42
2

The only reliable way to determine which page some text winds up on is to write it to the aux file. It takes two runs to update the headers.

Macro \beancounter steps beans and write \thepage to the aux file. It must be in the same line as Question, hence the \leavevmode.

Macro \myhead searches for all the questions on this page and formats the header.

\documentclass[12pt]{amsbook}
\usepackage{fancyhdr}
\usepackage{lipsum}

\newcounter{beans}
\newcounter{done}
\setcounter{done}{1}
\newif{\ifdone}

\makeatletter
\newcommand{\beancounter}{\leavevmode\stepcounter{beans}%
  \protected@write{\@auxout}{}{\string\gdef\string\beanpage\roman{beans}{\thepage}}}

\newcommand{\myhead}{\bgroup
  \donefalse
  \let\firstbean=\empty
  \let\lastbean=\empty
  \loop
    \@ifundefined{beanpage\roman{done}}{\donetrue}{%
      \ifnum\c@page=\csname beanpage\roman{done}\endcsname\relax
        \ifx\empty\firstbean\relax \edef\firstbean{\thedone}\fi
        \edef\lastbean{\thedone}
      \else
        \ifnum\c@page<\csname beanpage\roman{done}\endcsname\relax \donetrue\fi
      \fi}
  \ifdone\else\stepcounter{done}\repeat
  \ifx\empty\firstbean
  \else
    \ifx\firstbean\lastbean
      Question \firstbean
    \else
      Question \firstbean-\lastbean
    \fi
  \fi
\egroup}
\makeatother

\pagestyle{fancy}
\fancyhf{}
\fancyhead[RE]{Dante}
\fancyhead[LE]{\myhead}
\fancyhead[LO]{Meaning of Life}
\fancyhead[RO]{\myhead}
\fancyfoot[LE,RO]{\thepage}

\textheight 7cm

\begin{document}
\chapter{Gate}

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]


\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]

\beancounter
{\bf \thebeans.  Question: }
Fusce mauris. Vestibulum luctus nibh at lectus.
Sed bibendum, nulla a faucibus semper, leo velit ultricies tellus, ac
venenatis arcu wisi vel nisl. Vestibulum diam. Aliquam pellentesque,
augue quis sagittis posuere, turpis lacus congue quam, in hendrerit
risus eros eget felis. Maecenas eget erat in sapien mattis porttitor.
Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo

\beancounter
{\bf \thebeans.  Question: }
\lipsum[\thebeans]
Fusce mauris. Vestibulum luctus nibh at lectus.
Sed bibendum, nulla a faucibus semper, leo velit ultricies tellus, ac
venenatis arcu wisi vel nisl. Vestibulum diam. Aliquam pellentesque,
augue quis sagittis posuere, turpis lacus congue quam, in hendrerit
risus eros eget felis. Maecenas eget erat in sapien mattis porttitor.
Vestibulum porttitor. Nulla facilisi. Sed a turpis eu lacus commodo

\end{document}
John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • Thank you John. May I ask for more? :) (i) Instead of "Question 2-2", can we have just "Question 2" (ii) Sometimes the text of a question, say Question 6, runs over several pages. In that case I need to put "Question 6" at the header of each such page. Can it be done? Thank you for sharing your wisdom. Best. -Sinan – Sinan Sertoz Apr 11 '18 at 07:49
  • @SinanSertoz: John answered your question as you posted it and it is rather annoying to demand more after an answer has been given. –  Apr 11 '18 at 12:27
  • @ChristianHupfer In my original question I explicitly asked for "Question 6" instead of "Question 6-6". Moreover I sincerely appreciated John's solution. It would be a waste of time and space to make a separate post just for my question (ii) above. Besides this is a friendly platform to share ideas. No need to be annoyed when two other people are quite happy with their exchange of ideas. :) – Sinan Sertoz Apr 11 '18 at 14:51
  • Not a problem. The hard work was done. – John Kormylo Apr 11 '18 at 16:44