# Saving the value of a text macro at the start of the page.

I have a macro that stores some text. I'd like to print the text of that macro as it was at the start of the page in the header, and as it is at the end of the page in the footer. I can do this for counters like so:

\documentclass{article}
\usepackage{scrpage2,lipsum}
\makeatletter
\newcounter{ctr}
\newcounter{@ctr}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}
\makeatother

When the header is set, (at the end of the page) it outputs the value of the internal counter @ctr and then sets that counter to be the value of the counter used by the user ctr. It sets it to the value at the end of the page (which will be the value at the beginning of the new page (which is what I want)).

When I try the "analogous" process for a macro that contains text rather than for a counter, I don't get what I want: the header is set with the value of the macro as it is at the end of the page. How can I fix this?

The following MWE shows the problem. The counter and the text should always refer to the same number, but they don't.

\documentclass{article}
\usepackage{scrpage2,lipsum}

\makeatletter

\newcounter{ctr}
\newcounter{@ctr}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}

\def\thetext{First text}
\def\@thetext{\thetext}
\ifoot{\thetext}

\makeatother

\begin{document}
\lipsum[1-4]

{\Large Becoming Second text}\stepcounter{ctr}
\def\thetext{Second text}

\lipsum[5-7]

{\Large Becoming Third text}\stepcounter{ctr}
\def\thetext{Third text}

\lipsum[8-11]

{\Large Becoming Fourth text}\stepcounter{ctr}
\def\thetext{Fourth text}

\lipsum[12]
\end{document}

This looks to me like it's probably some sort of expansion problem. I tried playing with \edef instead of \def but if I couldn't get the desired result. What am I doing wrong?

• I am trying to solve a similar problem tex.stackexchange.com/questions/20512/…. – Peter Grill Jul 19 '11 at 17:24
• Your system will not work in reliable way for counters either. Due to the asynchronous page breaking there is the danger that you get values from following pages. If you want to put variable text depending on the content of the current page in the headers always use \mark-command. – Ulrike Fischer Jul 20 '11 at 9:43

You need to use \edef (expanding \def) or better \xdef (global expand) instead of \def, otherwise you simply define \@thetext to expand to \thetext which then expands to its then current definition. So constantly saying \def\@thetext{\thetext} doesn't change its definition at all. What you want to do is to assign the current value of \thetext to \@thetext not "reference" it.

LaTeX provides an extended version called \protected@xdef which takes care that the \protect will work properly in its argument. (There is also a \protected@edef.)

\def\thetext{First text}
\def\@thetext{\thetext}
\ifoot{\thetext}
• \xdef being a mix of \edef and \gdef, or a \global\edef – ℝaphink Jul 19 '11 at 15:29
• This can have adverse effects if \thetext is not completely expandable; \protected@xdef would be safer. – egreg Jul 19 '11 at 15:30
• @egreg: Very good point! I will edit this in. – Martin Scharrer Jul 19 '11 at 15:31
• @Raphink: \xdef is the same as \global\edef. Also, \gdef is simply a short version of \global\def. – Martin Scharrer Jul 19 '11 at 15:36
• The first definition of \@thetext needs to be \xdef or \edef as well. Otherwise, the first couple of pages get it wrong... And just using \edef isn't enough inside the \ifoot you need it to be global... – Seamus Jul 19 '11 at 15:40

Here's a first approximation using \marks:

\documentclass{article}
\usepackage{lipsum,etex}
\usepackage{scrpage2}

\makeatletter

\newmarks\grillmark

\newcounter{ctr}
\newcounter{@ctr}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}

\ifnum\value{page}=1
\expandafter\firstmarks
\else
\expandafter\topmarks
\fi\grillmark}% changed per Martin's suggestion
\ifoot{\botmarks\grillmark}

\makeatother

\begin{document}
\marks\grillmark{First text}
\lipsum[1-4]

{\Large Becoming Second text}\stepcounter{ctr}
\marks\grillmark{Second text}

\lipsum[5-7]

{\Large Becoming Third text}\stepcounter{ctr}
\marks\grillmark{Third text}

\lipsum[8-11]

{\Large Becoming Fourth text}\stepcounter{ctr}
\marks\grillmark{Fourth text}

\lipsum[12]

{\Large Becoming Fifth text}\stepcounter{ctr}
\marks\grillmark{Fifth text}
\lipsum[13-15]
\vspace{0.75in}% Enough to get to end of page

{\Large Becoming Sixth text}\stepcounter{ctr}
\marks\grillmark{Sixth text}
\lipsum[16]
\end{document}

The explanation is in the TeXbook or TeX by Topic: generalized marks work the same as the standard marks in TeX, with the difference that the commands have a final "s" and need a number after them. Here the number is allocated through \newmarks provided by etex. The standard marks are available also as \marks0 for setting a mark and \firstmarks0, \topmarks0 and \botmarks0 for retrieving the marks. There are 32767 mark classes: more than enough, I believe.

• The \grillmarks work pretty good (nice name BTW). But with the example above there are a few minor issues: Bottom of Page 3 has the number 6, but should be 5. Top of Page 4 should have "Sixth text" instead of "Fifth text". – Peter Grill Jul 20 '11 at 2:27
• Actually you should use two marks, one for the top and one for the bottom. The problem of a section starting at the top of the page should be solvable with Javier's trick. – egreg Jul 20 '11 at 7:48
• Sorry, don't know what Javier's trick refers to? – Peter Grill Jul 20 '11 at 8:12
• @Peter Oh, sorry! I worked thinking it was your question! The marks should be called \seamusmark, instead. There's a trick of Javier Bezos in his titlesec package just for this. – egreg Jul 20 '11 at 8:21
• Yeah, my problem which I linked to in the comment to this question is pretty much identical so can see how they can be confused. – Peter Grill Jul 20 '11 at 8:25

This is not an answer, but a comment. I need to add code, hence posting it here.

It appears that there is an issue with this solution if the value of the macro changes at the top of a page. The following MWE includes the fixes suggested by Martin and Seamus, and has additional Fifth and Sixth test to illustrate the problem:

\documentclass{article}
\usepackage{lipsum}
\usepackage{scrpage2}

\makeatletter

\newcounter{ctr}
\newcounter{@ctr}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}

\def\thetext{First text}
\xdef\@thetext{\thetext}% changed \def to \xdef per Seamus's comment
\ifoot{\thetext}

\makeatother

\begin{document}
\lipsum[1-4]

{\Large Becoming Second text}\stepcounter{ctr}
\def\thetext{Second text}

\lipsum[5-7]

{\Large Becoming Third text}\stepcounter{ctr}
\def\thetext{Third text}

\lipsum[8-11]

{\Large Becoming Fourth text}\stepcounter{ctr}
\def\thetext{Fourth text}

\lipsum[12]

{\Large Becoming Fifth text}\stepcounter{ctr}
\def\thetext{Fifth text}
\lipsum[13-15]
\vspace{0.75in}% Enough to get to end of page

{\Large Becoming Sixth text}\stepcounter{ctr}
\def\thetext{Sixth text}
\lipsum[16]
\end{document}

Note that bottom of Page 3 should have referred to 5, and not 6.

• It's due to the asynchronous behavior of the page splitting procedure: TeX always typesets an entire paragraph before deciding where to split a page. The only safe way is to use the \label-\ref mechanism, probably with the refcount package to be sure of using actual numbers and not typesetting instructions. – egreg Jul 19 '11 at 21:14
• Of course there is also the "mark" mechanism; with e-TeX one has plenty of marks to play with. – egreg Jul 19 '11 at 21:28
• That sounds interesting. Where can I find example usage of that? The documentation I found via Google does not have much info on this. – Peter Grill Jul 19 '11 at 21:33
• See my answer. :) – egreg Jul 19 '11 at 21:48