对于带有 fancyhdr 的普通页面,在 fancypagestyle 环境中无法访问自己的命令

对于带有 fancyhdr 的普通页面,在 fancypagestyle 环境中无法访问自己的命令

我遇到了一个奇怪的错误。

如果我理解正确的话,LaTeX 纯页面原理是页面遵循由主标题或章节/部分提及触发的文档标记。每次发出主标题或章节/部分 LaTeX 命令时,都会调用章节/部分标记。默认情况下,该标记根据页面样式定义的格式显示在标题中plain

重新定义普通的页面样式\fancypagestyle{plain}可以让我们覆盖此默认行为。

如果我想对所有页面应用相同的页眉/页脚算法,我只需要重新定义普通页面样式并将该样式应用于文档。

但是,我定义的新命令似乎无法在该纯页面环境中访问。

\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}

如果我删除条件行 105:

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

但是我让 renewcommand 启用了,它按预期工作,并且我的标题在所有页面上都正确定义。

这个问题有解决办法吗?

如果您喜欢该平台,请参阅 Github Gist 上的代码链接,因为它有行号:https://gist.github.com/wget/e8da2f2fb35aa741b8ddf497c827941d

答案1

您的问题是,普通的 pagestyle 在两个地方被调用。您可以通过添加以下内容轻松测试这一点\show\x

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

第一次是在 中调用的\pagestyle{plain}。此时 subtitle 命令尚未定义,因此几乎到处都是空标题。第二次是在\thispagestyle{plain}chapter 命令中。现在 subtitle 已定义,因为您没有\pgfqkeys{/wgetdoc/title}{#1}在组中调用。因此此页面显示 subtitle。

总体而言,我确实觉得将代码过多地基于命令顺序有点危险。我认为,如果要依赖选项,最好将 放在\pagestyletitle 命令的末尾。

相关内容