1

I'm experiencing a weird bug.

If I understand correctly, LaTeX plain pages principle consists in pages following a document mark triggered by maintitle or a chapter/section mention. Each time a main title or a chapter/section LaTeX command is issued, the chapter/section mark is called. By default, that mark is displayed in the header according to the format defined by the plainpage style.

Redefining that plain page style with \fancypagestyle{plain} allows us to override this default behavior.

If I want to apply the same header/footer algorithm for ALL pages, I just need to redefine the plain page style and apply that style to the document.

However, it seems the new command I defined is not accessible in that environment for plain pages.

\documentclass{report}
\makeatletter
\usepackage{pgfopts}

% This is what we do here. We define commands like \@wgetdoc@title@maintitle
% that we need to call manually to execute their content.
\newif\if@wgetdoc@title@ownpage
\pgfkeys{
    /wgetdoc/title/.cd,
    % maintitle/.code={\ifx#1\@empty\else\edef\@wgetdoc@title@maintitle{#1}\fi},
    maintitle/.store in=\@wgetdoc@title@maintitle,
    maintitle/.value required,
    subtitle/.store in=\@wgetdoc@title@subtitle,
    author/.store in=\@wgetdoc@title@author,
    filename/.store in=\@wgetdoc@title@filename,
    ownpage/.is if=@wgetdoc@title@ownpage
}

\renewcommand{\title}[1][]{%

    % The following command is a shortcut and marginally quicker than
    % \pgfkeys{/wgetdoc/title/.cd, #1}
    % The command cannot end with the trailing / though.
    \pgfqkeys{/wgetdoc/title}{#1}

    \@ifundefined{@wgetdoc@title@filename}{

        % Do not use the following check. This macro is only available in
        % xkeyval and allows just checking if a key is defined in a family from
        % a list of families.
        \@ifundefined{@wgetdoc@title@maintitle}{
            \ClassError{wgetdoc}{You did not specify a main title}{}
        }{}

        % Check if maintitle is empty as it: maintitle=,subtitle=lorem
        % or maintitle={},subtitle=lorem
        % No need to check further as pgfkeys trims white spaces and
        % checks performed either by \ifblank (etoolbox) or
        % \@ifmtarg (ifmtarg) are lost
        \ifx\@wgetdoc@title@maintitle\@empty
            \ClassError{wgetdoc}{The main title you specified is empty}{}
        \fi

        % Custom horizontale rule only local to this environment
        \newcommand{\@wgetdoc@title@hrule}{\rule{\linewidth}{1mm}}

        % If this boolean key is absent of the title command, this will return
        % false. If it is only present, it will return true. Any
        % value other than 'true' or 'false' is non accepted and will make the
        % compilation crash.
        \if@wgetdoc@title@ownpage
            \begin{titlepage}
                \begin{center}

                    \@wgetdoc@title@hrule%
                    \vspace{0.4cm}

                    % We always need to define \par in scope for a font size
                    % change, otherwise, if the title is ever longer than a
                    % line, it will wrap to the next line with huge characters
                    % on a normal baseline.
                    {\Huge\textbf{\@wgetdoc@title@maintitle}\par}%

                    \vspace{0.4cm}%
                    \@wgetdoc@title@hrule

                    \@ifundefined{@wgetdoc@title@subtitle}{}{
                        \vspace{1.5cm}
                        {\Large{\@wgetdoc@title@subtitle}\par}%
                    }

                    \@ifundefined{@wgetdoc@title@author}{}{
                        % Adds vertical space which will not be suppressed at the
                        % beginning or end of a page. Text following that statement
                        % will be at the bottom of the page.
                        \vspace*{\fill}
                        {\emph{Author: \@wgetdoc@title@author}\par}%
                    }

                \end{center}
            \end{titlepage}%
        \else
            \begin{center}
                {\huge\textbf{\@wgetdoc@title@maintitle}\par}
                \@ifundefined{@wgetdoc@title@subtitle}{}{
                    {\large{\@wgetdoc@title@subtitle}\par}%
                }
            \end{center}
            \@ifundefined{@wgetdoc@title@author}{}{
                {\emph{Author: \@wgetdoc@title@author}\par}%
            }
            \@wgetdoc@title@hrule%
        \fi

    }{
    }
}


\usepackage{fancyhdr}
\newcommand{\@wgetdoc@header@centervalue}{}
\fancypagestyle{plain}{

    \fancyhf{}
    \@ifundefined{@wgetdoc@title@subtitle}{}{
        \renewcommand{\@wgetdoc@header@centervalue}{\@wgetdoc@title@subtitle}
    }
    \fancyhead[C]{\@wgetdoc@header@centervalue}
}
\pagestyle{plain}


\usepackage{lipsum}
\makeatother
\begin{document}

    \title[maintitle=Some title,
          subtitle=\textsc{some sub},
          author=This is me,ownpage=true]

    \chapter{My chapter name}

    \section{My section name}

    \lipsum[4-57]



\end{document}

If I remove the condition line 105 :

\@ifundefined{@wgetdoc@title@subtitle}{}{
    \renewcommand{\@wgetdoc@header@centervalue}{\@wgetdoc@title@subtitle}
}

but I let the renewcommand enabled, this is working like expected and my header is defined properly for all pages.

Any solution to this problem?

A link to the code on Github Gist, if you prefer that platform as it has line numbering: https://gist.github.com/wget/e8da2f2fb35aa741b8ddf497c827941d

  • 1
    You're setting \pagestyle{plain} before \title is used. At that time the subtitle macro is not undefined. Solution: \title{...}\pagestyle{plain} or even better: Make \title a declarative macro, that does try to typeset the title already, so you can use \title...\pagestyle{plain} even before \begin{document}. You need a (self-defined) version of \maketitle of course then after \begin{document}. – user31729 Aug 28 '17 at 10:20
  • @ChristianHupfer Thanks for the idea. I actually have put my title definition in a new command \@wgetdoc@customtitle then have redefined \title to call just \@wgetdoc@customtitle\pagestyle{plain}. This is indeed working for this MWE, but not for my whole class :-/ – wget Aug 28 '17 at 11:48
  • @ChristianHupfer And I did not understand by "At that time the subtitle macro is not undefined". Per the condition, I'm checking it is defined not undefined. This is \@ifundefined{VAR}{} {MYCODE}. MY CODE is in the else part of the ifundefined. – wget Aug 28 '17 at 11:52
  • See Ulrike's answer. She says basically the same in more words ;-) – user31729 Aug 28 '17 at 17:44
2

Your problem is that the plain pagestyle is called in two places. You can easily test this by adding a \show\x:

\fancypagestyle{plain}{
    \show\x
    \fancyhf{}
    \@ifundefined{@wgetdoc@title@subtitle}{}{
        \renewcommand{\@wgetdoc@header@centervalue}{\@wgetdoc@title@subtitle}
    }
    \fancyhead[C]{\@wgetdoc@header@centervalue}
}

The first time it is called at the \pagestyle{plain}. At this time the subtitle command is not defined, and so you get almost everywhere empty headers. The second time is in the \thispagestyle{plain} in the chapter command. Now subtitle is defined as you don't call \pgfqkeys{/wgetdoc/title}{#1} in a group. So this page shows the subtitle.

On the whole I do find a bit dangerous that you base your code so much on the order of the commands. Imho it would be better to put the \pagestyle at the end of the title command if it should rely on its options.

| improve this answer | |
  • Thanks to you and Christian. I declared a new command redefining my default title command. That command now has a trailing statement \thispagestyle{plain}. This plus the order of elements (the \header command must appear first in the document in order to work properly) did the trick. Actually since this is part of my own class, their users must follow the minimal working example I have written in order for my class to work properly. So I assume I won't encounter issues with it, but if you have ideas to avoid twisty hallways, let me know :) Thanks again. – wget Sep 3 '17 at 17:48
  • 1
    @wget almost all document classes that have a \title don't typeset with that command, it just saves its argument for use in \maketitle if you are not following that convention it would be better to give the command a different name. – David Carlisle Sep 3 '17 at 18:28
  • @DavidCarlisle Thanks. I'll leave it as it for now, since this is my own class, but I'll pay attention for the future. Added a comment to my class. :) – wget Sep 3 '17 at 18:59

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.