# Weird interaction between everyhook and fancyhdr

In a document I'm working on, I'd like whitespace to be added before a custom environment, but only if that environment doesn't immediately follow a sectioning command (\section, \subsection, etc). I figured I could set up a paragraph counter via the everyhook package, and use the etoolbox package's \pretocmd macro to patch \@startsection to reset the paragraph counter. That seemed to work fine, but I noticed some odd behavior in the spacing produced... after some debugging, I whittled it down to a strange interaction between everyhook and fancyhdr. Here's a minimal example demonstrating what's happening:

\documentclass[12pt]{article}
\usepackage{blindtext}
\usepackage{everyhook}
\usepackage{fancyhdr}

\newcounter{paranum}
\PushPreHook{par}{\stepcounter{paranum}}

\pagestyle{fancy}

\begin{document}

\theparanum: \blindtext

\theparanum: \blindtext

\theparanum: \blindtext

\theparanum: \blindtext

\theparanum: \blindtext

\theparanum: \blindtext
\end{document}


This generates

Everything counts along fine on the first page, but on the second, the count jumps from 5 to 12. Removing the \pagestyle{fancy} command fixes this. Why? And more importantly, how can I keep using the fancyhdr package while also being able to accurately number paragraphs?

-

Call

\usepackage[excludeor]{everyhook}


which will suppress evaluating the \everypar tokens inside the output routine.

It's possible to get the same behavior without fancyhdr: just say

\pagestyle{myheadings}


and

\section*{Heading}
\markright{\protect\parbox{3cm}{abc}}


The paragraph built inside the \parbox will cause the hook to be executed and the counter stepped. With the excludeor option this doesn't happen.

-
Thanks! I figured it had something to do with paragraphs being created inside the header, but I had no idea how to fix it. Is there a relatively straightforward reason why this affects the counter on the second paragraph of the second page in my example, and not the first paragraph? –  Dan Sep 12 '12 at 8:14
Yes: the output routine acts asynchronously. TeX gathers more material than fits on a page in order to find the best break point and always entire paragraphs are stored. So your paragraph 5 is typeset (in memory) and only after that operation the output routine acts. –  egreg Sep 12 '12 at 8:24

As you'd "like whitespace to be added before a custom environment, but only if that environment doesn't immediately follow a sectioning command", I suggest to simply add a test for the @nobreak switch at the start of your environment. @nobreak is true only immediately after headings.

\documentclass{article}

\newcommand*{\sometext}{Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Etiam lobortis facilisis sem. Nullam nec mi et
neque pharetra sollicitudin. Praesent imperdiet mi nec ante. Donec
ullamcorper, felis non sodales commodo, lectus velit ultrices augue,
a dignissim nibh lectus placerat pede.}

\makeatletter
\newenvironment{testenv}{%
\itshape
\if@nobreak
\else
\vspace{50pt}%
\fi
}{%
}
\makeatother

\usepackage{blindtext}

\begin{document}

\sometext

\begin{testenv}
\sometext
\end{testenv}


Did not know about \@nobreak. This a much better solution than the one I came up with. Is \@nobreak only set after headings, or are there other cases where it is also set and might cause issues? –  Dan Sep 12 '12 at 8:22
@Dan Quoting source2e, p. 54: "The @nobreak switch is set true used when in vertical mode and no page break should occur. (Right now, it is used only by the section heading commands to inhibit page breaking after a heading.)" –  lockstep Sep 12 '12 at 8:26