1

I'm trying to generate a document that has two different possible headers, one for the first page of the document and the first page of sections, and one for all other pages. All pages should have footers that give the page number.

I'm using fancyhdr and have defined page styles associated with each header, and the problem I'm running into is how to correct for the fact that the header for first pages is larger than that for the others. When I switch from one to the other, I have to force the geometry to be recalculated, most notably so that the footer doesn't get pushed off the page when I increase the headheight. I've put the recalculation of the geometry in the page style definition so that they're called together, and if I call \pagestyle{either style}, I get the expected results.

The part where I'm lost is that I'd like to be able to use \thispagestyle for the first pages of each section, and when I try to do so I get the appropriate heading but not the appropriate geometry.

Here's a MWE that shows the problem:

\documentclass[a5paper,12pt]{article}
\usepackage[showframe]{geometry}
\usepackage{fancyhdr}
\renewcommand{\headrulewidth}{2pt}
\setlength{\parindent}{0cm}

\fancypagestyle{firstpages}{%
  \newgeometry{includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom = 1cm, headheight=57pt}
  \rhead{Long header\\line2\\line3\\line4}
  \cfoot{\thepage} 
  }

\fancypagestyle{others}{%
  \newgeometry{includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom=1cm, headheight=15pt}
  \lhead{}
  \chead{}
  \rhead{Normal header}
  \cfoot{\thepage}
  }

\begin{document}

\pagestyle{firstpages}
Text under big header

\pagebreak
\pagestyle{others}
Text under little header

\pagebreak
\thispagestyle{firstpages}
Text under big header

\pagebreak
Text under little header

\pagebreak
\pagestyle{firstpages}
Text under big header

\end{document} 

The pages where the style is defined by \pagestyle (1, 2, 4, 5) are fine, but on page 3, where \thispagestyle is used, the boxes associated with the geometry don't shift and (I think as a consequence) the footer is pushed off the page.

I haven't found a description of differences between \pagestyle and \thispagestyle that I'd expect to be causing this behaviour, but clearly something is. Is there a way of making this work? (Alternatively, I'd be happy to hear of a different way to make just the first page of an otherwise-undemarcated section differ from the rest of the section without a known page-break location.) I'm not a very experienced Latex user, so let me know if I'm overlooking anything obvious.

5
  • 1
    Welcome to TeX.SX! I don't think it's a good idea to use \newgeometry as part of a pagestyle. Anyway, fancyhdr expects the head height to be the same across the document.
    – egreg
    Commented Mar 2, 2017 at 21:41
  • Do you have suggestions for how to handle the case of multiple head heights then? (I'm trying to imitate an existing document, so the closer to matching it I can be the better.)
    – Sora
    Commented Mar 2, 2017 at 22:16
  • There should be no need to change the headheight. Set it to the height needed for the small header, let the large header stick out of it and move the section/text on the pages with large header down with a simple \vspace. Commented Mar 2, 2017 at 22:26
  • Okay, that does work. I had discarded that idea a while ago because I couldn't figure out how to keep fancyhdr from changing the headheight itself, but that's a solved issue now that I know how to look. I'm still confused by the differences between \pagestyle and \thispagestyle, but that can be a problem for next time.
    – Sora
    Commented Mar 2, 2017 at 23:27
  • \thispagestyle is only for the current page, afterwards the old page style before is used, i.e. \thispagestyle 'eclipses' the outer page style for a 'moment', applies its own settings, the page is shipped out, the old pagestyle is reactivated.
    – user31729
    Commented Mar 2, 2017 at 23:43

3 Answers 3

2

Partial answer: A call to \pagestyle is executed immediately. A call to \thispagestyle is only executed as part of the page shipout routine - that ensures that it will supersede whatever \pagestyle might be in effect (or be called after \thispagestyle on the same page). For that reason, \pagestyle shows the desired result, while \thispagestyle doesn't - the page, with its dimensions, have already been assembled.

From the LaTeX kernel:

\def\pagestyle#1{%
  \@ifundefined{ps@#1}%
    \undefinedpagestyle
    {\@nameuse{ps@#1}}}
\def\thispagestyle#1{%
  \@ifundefined{ps@#1}%
    \undefinedpagestyle
    {\global\@specialpagetrue\gdef\@specialstyle{#1}}}

Note how \pagestyle{<style>} calls \@nameuse{ps@<style>}, while \thispagestyle{<style>} just sets a flag - \@specialpagetrue and stores the style in \@specialstyle. Only later (as part of \@outputpage) is the style applied.

0
2

EDIT:\newgeometry moved out of \thispagestyle after Pieter van Oostrum's comment and answer.


As pointed by Werner and Pieter van Oostrum in theirs answers, it's seems not possible to change correctly the page geometry from \thispagestyle.

I suggest then to define a new command to change temporary the geometry

\NewDocumentCommand{\thispagegeometry}{ m }
  {%
    \newgeometry{#1}
    \AddToHookNext{shipout/after}
      {%
        \globaldefs=1
        \restoregeometry
        \globaldefs=0
      }
  }

This will change the geometry for one page only. But unlike \thispagestyle it should be inserted at the beginning of the page (as \newgeometry insert a \clearpage). The geometry is restored in the following page, using the hook shipout/after. Note that since the code inside \AddToHokNext is evaluated inside a group (locally), \globaldef=1 is used to make lengths assignations global.

Example:

\documentclass[a5paper,12pt]{article}

\usepackage[showframe]{geometry}
\usepackage{fancyhdr}
\renewcommand{\headrulewidth}{2pt}
\setlength{\parindent}{0cm}

\fancypagestyle{firstpages}
  {%
    \rhead{Long header\\line2\\line3\\line4}
    \cfoot{\thepage}
  }

\fancypagestyle{others}
  {%
    \lhead{}
    \chead{}
    \rhead{Normal header}
    \cfoot{\thepage}
  }

\NewDocumentCommand{\thispagegeometry}{ m }
  {%
    \newgeometry{#1}
    \AddToHookNext{shipout/after}
      {%
        \globaldefs=1
        \restoregeometry
        \globaldefs=0
      }
  }

\newgeometry
  {includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom=1cm, headheight=15pt}

\begin{document}

\thispagegeometry
  {includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom = 1cm, headheight=57pt}
\pagestyle{firstpages}

Text under big header

\pagebreak
\pagestyle{others}

Text under little header

\pagebreak
\thispagegeometry
  {includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom = 1cm, headheight=57pt}
\thispagestyle{firstpages}

Text under big header

\pagebreak

Text under little header

\pagebreak
\thispagegeometry
  {includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom = 1cm, headheight=57pt}
\pagestyle{firstpages}

Text under big header

\end{document}
2
  • This doesn't work. See my answer. Commented May 20 at 20:32
  • @PietervanOostrum I edited my answer. Thanks.
    – jlab
    Commented May 21 at 20:35
1

The solution by @jlab doesn't work. As @Werner had noticed in his answer, the code in \thispagestyle{firstpages} will be run in the output routine, i.e. when the final page is built. It does affect the headheight, and the code even sets textheight to the proper value, but this has no effect as the page has already been built with the previous headheight. You can see this if you run @jlabs answer, on page 3 the footer with the page number disappears. It is pushed down below the paper border.

So you should do the \newgeometry{includeheadfoot, left=1cm, right=1cm, top=.5cm, bottom = 1cm, headheight=57pt} together with the \thispagestyle{firstpages}. Best would be to put this together in a macro.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .