分离某些页面的页面几何形状(不使用 \newpage)

分离某些页面的页面几何形状(不使用 \newpage)

我有不同的文档类别,有些页面的页面几何形状不同。通常第一页的页眉或页脚较大。

几何学包允许使用 存储不同的几何图形\savegeometry并使用 加载它们\loadgeometry。如果几何图形变化的位置是预先知道的并且通过 定义\newpage,则这种方法很有效。

如果没有明确指定几何变化的位置\newpage但应该在某个页面之后,这并不直接,如下例所示:

\documentclass{scrartcl}
\usepackage{blindtext}
%
% Select approach
%
% 1: Separate page geometry for first page
% 2: Same page geometry for all pages but adjusted header, \vspace at document begin and \enlargethispage for first page
% 3: No \loadgeometry, \afterpage or other geometry modifications
\newcounter{approach}
\setcounter{approach}{1}
%
% Select test case
%
% 1: Two sections and text [passed with approach 1 and 2]
% 2: One section and text [failed with approach 1 but passed with approach 2]
% 3: One section and itemize (split over two pages) surrounded by text [failed with approach 1 but passed with approach 2]
% And probably many other test cases that will fail with approach 1...
% Approach results per definition in a not desired result
\newcounter{testcase}
\setcounter{testcase}{1}
%
% Page geometry
%
\usepackage[showframe]{geometry}
%
\newgeometry{margin=20mm, headheight=\baselineskip, footskip=2\baselineskip, includehead, includefoot}
\savegeometry{standard}
%
\ifnum\value{approach}=1
    \newgeometry{margin=20mm, headheight=4\baselineskip, footskip=4\baselineskip, includehead, includefoot}
    \savegeometry{title}
\fi
%
\loadgeometry{standard}
\setlength{\footheight}{\baselineskip}
%
% Page styles
%
\usepackage{scrlayer-scrpage}
%
\newcommand*{\headerstandard}{Document (Approach \arabic{approach}, Test case \arabic{testcase}) \hfill Date}
\newcommand*{\headertitle}{\headerstandard\\ Item\\ Item\\ Item}
%
\setkomafont{pagenumber}{}
\newcommand*{\footerstandard}{Id \hfill Page \pagemark}
\newcommand*{\footertitle}{Info\\ Info\\ \footerstandard}
%
\defpagestyle{standard}{%
    {}{}{\headerstandard}%
}{%
    {}{}{\smash{\parbox[b]{\textwidth}{\footerstandard}}}%
}
\ifnum\ifnum\value{approach}=1 1\else\ifnum\value{approach}=3 1\else 0\fi\fi=1% \value{approach}=1 or \value{approach}=3
    \defpagestyle{title}{%
        {}{}{\headertitle}%
    }{%
        {}{}{\smash{\parbox[b]{\textwidth}{\footertitle}}}%
    }
\fi
\ifnum\value{approach}=2
    \defpagestyle{title}{%
        {}{}{\smash{\parbox[t]{\textwidth}{\headertitle}}}%
    }{%
        {}{}{\smash{\parbox[b]{\textwidth}{\footertitle}}}%
    }
\fi
\pagestyle{standard}
%
% Title page
%
\ifnum\value{approach}=1
    \usepackage{afterpage}
    %
    \renewcommand*{\maketitle}{%
        \thispagestyle{title}%
        \loadgeometry{title}%
        % ...
        \afterpage{\aftergroup\restoregeometry}%
    }
\fi
\ifnum\value{approach}=2
    \renewcommand*{\maketitle}{%
        \thispagestyle{title}%
        \vspace*{3\baselineskip}% Hack to simulate bigger head height
        \vspace{-\parskip}%
        \vspace{-\baselineskip}%
        \vspace{-1.535\baselineskip}% Hack two remove vertical space inserted if followed by section
        % ...
        \enlargethispage{-3\baselineskip}% Hack has not exact the same result as in approach 1
    }
\fi
\ifnum\value{approach}=3
    \renewcommand*{\maketitle}{%
        \thispagestyle{title}%
        % ...
    }
\fi
%
\AtBeginDocument{\maketitle}
%
% Document with test cases
%
\begin{document}
\ifnum\value{testcase}=1
    \section{Section}%
    \blindtext[6]%
    \section{Section}%
    \blindtext[3]%
\fi
\ifnum\value{testcase}=2
    \section{Section}%
    \blindtext[6]%
\fi
\ifnum\value{testcase}=3
    \section{Section}%
    \blindtext[5]%
    \blinditemize[7]%
    \blindtext[5]%
\fi
\end{document}

我发现并尝试了一种方法(称为方法 1\afterpage在示例中)使用后页包裹:

在这种方法中,我为第一页使用了单独的页面几何形状,但在提供的三个测试用例中的最后两个中失败了。请参见未更改的页眉高度,以及测试用例 3 中\vbox第二页底部的溢出:

  1. 2.3.

作为替代方案,我尝试了第二种方法(称为方法 2在示例中),参考如下:

因此,我保留了所有页面的相同页面几何形状,但调整了页眉,将其添加到\vspace页面开头和\enlargethispage第一页。这种方法通过了所有测试用例,但在代码实现中存在一些问题。我必须添加一个正值\vspace以适应更大的页眉高度,并添加一个负值\vspace以删除从下一节添加的垂直空间。此外,\enlargethispage结果文本高度与方法 1 不同:

  1. 2.3.

最后我的问题是:

  1. 是否有可能使方法 1\afterpage可靠地工作?
  2. 另外,是否可以自动计算页眉和页脚的高度?在示例中,我针对一种特殊情况手动定义了它们,尽管在其他情况下它应该可以自动运行。

非常感谢您的帮助。

更新:

根据@David Carlisle 的评论,我添加了第三种方法(称为方法 3在更新的示例中)来自方法 1 \loadgeometry,没有\afterpage或其他几何修改。但这种方法按照定义会导致不理想的结果。因此,文本主体高度是恒定的,并且第一页上具有较大高度的页眉在顶部不与第二页上的页眉对齐。第一页上具有较大高度的页脚在底部与第二页上的页脚对齐,但与文本主体发生冲突:

我还必须说,方法 2 也没有带来几何变化,但有一些\vspace技巧。

答案1

这是一个解决方案。

\documentclass{scrartcl}
\usepackage{mwe}
\newcounter{testcase}
\setcounter{testcase}{3}

\usepackage[showframe]{geometry}

\usepackage{etoolbox}

\makeatletter 
\def\Gmt@restore{}
\apptocmd\Gm@savelength{%
  \g@addto@macro\Gmt@restore{\global\expandafter\noexpand\expandafter\csname
  #1\endcsname\expandafter=\expandafter\the\csname #1\endcsname\relax}}{}{}
\patchcmd{\@outputpage}{\global \@colht \textheight}{\Gmt@restore@pkg \global \@colht \textheight}{}{} 
\makeatother

\newgeometry{margin=20mm, headheight=\baselineskip, footskip=2\baselineskip, includehead, includefoot}
\savegeometry{standard}

\makeatletter 
\edef\Gmt@restore@pkg{\Gmt@restore
 \global\expandafter\let\expandafter\noexpand\expandafter\Gmt@restore@pkg\noexpand\empty}%
\makeatother

\newgeometry{margin=20mm, headheight=4\baselineskip, footskip=4\baselineskip, includehead, includefoot}
\savegeometry{title}

\loadgeometry{standard}

\setlength{\footheight}{\baselineskip}
\usepackage{scrlayer-scrpage}
\newcommand*{\headerstandard}{Document (Approach 1, Test case 2) \hfill Date}
\newcommand*{\headertitle}{\headerstandard\\ Item\\ Item\\ Item}
\setkomafont{pagenumber}{}
\newcommand*{\footerstandard}{Id \hfill Page \pagemark}
\newcommand*{\footertitle}{Info\\ Info\\ \footerstandard}
\defpagestyle{standard}{%
    {}{}{\headerstandard}%
}{%
    {}{}{\smash{\parbox[b]{\textwidth}{\footerstandard}}}%
}
\defpagestyle{title}{%
        {}{}{\headertitle}%
    }{%
        {}{}{\smash{\parbox[b]{\textwidth}{\footertitle}}}%
    }
\pagestyle{standard}

\renewcommand*{\maketitle}{%
    \thispagestyle{title}%
    \loadgeometry{title}%%
}
\AtBeginDocument{\maketitle}
\begin{document}
\ifnum\value{testcase}=1
    \section{Section}%
    \blindtext[6]%
    \section{Section}%
    \blindtext[3]%
\fi
\ifnum\value{testcase}=2
    \section{Section}%
    \blindtext[6]%
\fi
\ifnum\value{testcase}=3
    \section{Section}%
    \blindtext[5]%
    \blinditemize[7]%
    \blindtext[5]%
\fi  
\end{document}

相关内容