1

I am trying to automize setting the correct \headheight following Heiko Oberdiek's approach. It is based on the fact that the fancyhdr package usually increases the \headheight as required and saves this value at the very end to a file. The problem is that when using the calc package that value does not seem to change (although the log file still claims "We now make it that large for the rest of the document.").

I know that I could avoid the calc package by using \dimexpr and friends but I need the mathtools package which requires the calc package.

Does anyone have an idea how to get the correct value for \headheight even if the calc package is used?

\documentclass{article}
\usepackage{blindtext}
\usepackage{calc} % this suppresses fancyhdr's feature of increasing \headheight as required


% ===== save header and footer height =====
% https://tex.stackexchange.com/a/117810/120953
\usepackage{atveryend}
\makeatletter
\AtVeryEndDocument{%
    \if@filesw % respect \nofiles
        \begingroup
            % same write register as environment `filecontents` uses
            \chardef\reserved@c=15 %
            \immediate\openout\reserved@c=\jobname.heights\relax
            \immediate\write\reserved@c{%
                \string\setlength{\string\headheight}{\the\headheight}%
            }%
            \immediate\write\reserved@c{%
                \string\setlength{\string\footskip}{\the\footskip}%
            }%
            \immediate\closeout\reserved@c
        \endgroup
        \showthe\headheight
    \fi
}
\makeatother

%\InputIfFileExists{\jobname.heights}{}{} % I have commented this out for testing
\usepackage[
    includehead,
    includefoot,
    showframe,
]{geometry}


% ===== header & footer =====
\usepackage{fancyhdr}
\usepackage{lastpage}
\usepackage{graphicx}
\pagestyle{fancy}

\fancyhead{}
\fancyhead[L]{a rather long header\\ which needs to be broken into several lines}
%\fancyhead[R]{\includegraphics[height=\dimexpr\the\headheight-4.3501pt\relax]{icon}}

\fancyfoot{}
\fancyfoot[R]{page \thepage \ of \pageref{LastPage}}
\fancyfoot[L]{some footer}

\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}


% ===== test document =====
\begin{document}
    \blinddocument
\end{document}
  • fancyhdr doesn't usually increase headheight, it just warns, and increases it if the settings are inconsistent with the specified heading. Rather than use this file to save this error-correction it woul dbe more natural just to set up the correct settings using the geometry package in the first place. – David Carlisle Feb 11 '17 at 8:53
2

fancyhdr uses \global\setlength in one place which isn't supported LaTeX syntax and it doesn't work at all if calc is loaded. It is easy to avoid it in this case just delete \setlength and use a primitive assignment.

\documentclass{article}
\usepackage{blindtext}
\usepackage{calc} % this suppresses fancyhdr's feature of increasing \headheight as required


% ===== save header and footer height =====
% http://tex.stackexchange.com/a/117810/120953
\usepackage{atveryend}
\makeatletter
\AtVeryEndDocument{%
    \if@filesw % respect \nofiles
        \begingroup
            % same write register as environment `filecontents` uses
            \chardef\reserved@c=15 %
            \immediate\openout\reserved@c=\jobname.heights\relax
            \immediate\write\reserved@c{%
                \string\setlength{\string\headheight}{\the\headheight}%
            }%
            \immediate\write\reserved@c{%
                \string\setlength{\string\footskip}{\the\footskip}%
            }%
            \immediate\closeout\reserved@c
        \endgroup
        \showthe\headheight
    \fi
}
\makeatother

%\InputIfFileExists{\jobname.heights}{}{} % I have commented this out for testing
\usepackage[
    includehead,
    includefoot,
    showframe,
]{geometry}


% ===== header & footer =====
\usepackage{fancyhdr}

\makeatletter
\def\@fancyvbox#1#2{\setbox0\vbox{#2}\ifdim\ht0>#1\@fancywarning
  {\string#1 is too small (\the#1): ^^J Make it at least \the\ht0.^^J
    We now make it that large for the rest of the document.^^J
    This may cause the page layout to be inconsistent, however\@gobble}%
  \dimen0=#1\relax
  \global#1\ht0\ht0=\dimen0\fi
  \box0}
\makeatother

\usepackage{lastpage}
\usepackage{graphicx}
\pagestyle{fancy}

\fancyhead{}
\fancyhead[L]{a rather long header\\ which needs to be broken into several lines}
%\fancyhead[R]{\includegraphics[height=\dimexpr\the\headheight-4.3501pt\relax]{icon}}

\fancyfoot{}
\fancyfoot[R]{page \thepage \ of \pageref{LastPage}}
\fancyfoot[L]{some footer}

\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}


% ===== test document =====
\begin{document}
    \blinddocument
\end{document}
| improve this answer | |
  • I left your code as it is not relevant to the question but it isn't really safe to use \chardef\reserved@c=15 % it could be overwritten without warning by other writing in the document. It would be better to allocate a \newwrite for this use in the preamble and use that instead of 15, or just use \@auxout and write to the aux file which would simplify things and avoid having to re-input. – David Carlisle Feb 10 '17 at 22:44
  • thank you, I will change that in my code. I had copied that from the answer I have provided a link to. – jakun Feb 10 '17 at 22:59
  • @DavidCarlisle The use of \reserved@c is perfect safe here. See the grouping that restores the meaning of \reserved@c. Also, the code in the group does not contain macro expansion that avoids the problem, that a macro expands to and uses \reserved@c. – Heiko Oberdiek Feb 10 '17 at 23:39
  • 1
    @Heiko it wasn't reserved@c I was worried about but \write15, filecontents is restricted to the beginning of the document so can assume its free but if someone has allocated \newwrites up to 15 then this may or may not trip up depending on the use – David Carlisle Feb 11 '17 at 0:31
  • 1
    @DavidCarlisle it seems to me that the aux file would not be the desired way here because as Joseph Wright states in this answer tex.stackexchange.com/a/120978 the aux file is read after the preamble but as far as I understand changing \headheight should happen before loading the geometry package. – jakun Feb 11 '17 at 8:26

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.