定义要定位在特定页面上的环境

定义要定位在特定页面上的环境

我正在尝试创建一个包(基于gcard),除了现有的将所有四个环境打印在同一页上且前两个环境颠倒的选项之外,它还提供允许将四个环境打印在页面的正面和背面(翻译:在两页上,第二页上下颠倒)的选项。该gcard包提供了四个环境frontcoverbackcoverinsideleft和,并使用和包将它们放置在单个页面上的insideright特定位置和方向(无论在文件中调用环境的顺序如何) 。我可以制作一个修改过的包文件,以适当调整四个环境的大小,并将对相对于对中的另一个放置在正确的位置(即,和从左到右正面朝上,和和从左到右上下颠倒),但我无法让里面的对出现在第二页上。.textextposgraphicxgcard2.stybackcoverfrontcoverinsiderightinsideleft

我试图通过使用和标志来确定当前页面,在环境定义中添加一个\newpage参数,就像问题中那样begin\AtBeginShipout\if如何跟踪环境内的页面变化?,但我的尝试没有成功(参见\iffalse \fi发布的 MWE 中的配对)。我还想过尝试将一些东西放入\AtEndDocument分组框中,就像在课堂上做的那样faltblat.cls(可从 CTAN 获得,这里例如),但我无法弄清楚如何将环境放入包定义中的特定框中(并且我无法理解该类文件中的注释,因为我不懂该语言)。我甚至尝试将命令添加\newpagebegin参数中,但这似乎也不起作用。

我还想强制执行每个环境只能被调用一次的规则,因为目前如果你调用一个环境两次,那么它会将两个参数覆盖在同一位置,但这更像是一种奖励。

有人能帮我把环境放到合适的页面上吗?有人能帮我确保每个环境最多只打印一次调用吗?

gcard2.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{gcard2}[2007/08/21 simple greeting card package]
\DeclareOption{showboxes}{\PassOptionsToPackage{showboxes}{textpos}}
\newif\iftwosided
\DeclareOption{twosided}{
    \twosidedtrue
}
\DeclareOption{onesided}{
    \twosidedfalse
}
\ExecuteOptions{onesided}
\ProcessOptions
\RequirePackage[absolute]{textpos}
\RequirePackage{graphicx}
\RequirePackage{calc}
\RequirePackage{geometry}
\RequirePackage{atbegshi}

\iftwosided
    \geometry{landscape}
\else
    \geometry{portrait}
\fi
% main code begins here; each panel will be typeset and stored in 
% the box register \paneltext
\newsavebox{\paneltext}

% Define lengths 
\newlength{\gcguttermargin}
\newlength{\gcedgemargin}
\newlength{\gctopmargin}
\newlength{\gcbottommargin}
\newlength{\panelwidth}
\newlength{\panelheight}

\newif\ifnewpage\newpagetrue

% Set default values for margins.  These are the apparent margins after
% the card has been folded.  The user should set these four to taste.
% All four panels use the same margins.
% Here, edge and gutter are set the same, as are top and bottom; that's
% not required, and it's okay to use 4 different values.
\iftwosided
    %Margins for two-sided
    \setlength{\gcguttermargin}{0.4 in} % inside of panel  
    \setlength{\gcedgemargin}{\gcguttermargin}  % outside
    \setlength{\gctopmargin}{0.4 in}        % top
    \setlength{\gcbottommargin}{\gctopmargin}  % bottom
    % Define environments for four panels.  The two outside ones (frontcover and
    % backcover) should be placed in reverse order (back ccover then front cover, from left to right) and do not need to be rotated. The two inside ones (insideleft and insideright) need to be rotated, and also placed in reverse order (insideleft then insideright, from left to right).
    % These environments place the user's material vertically centered in a minipage
    % of width \panelwidth and height \panelheight.
    \newenvironment{insideright}{%
        \iffalse
        \AtBeginShipout{
            \ifnewpage
                \newpage
                \global\newpagefalse
            \fi
        }
        \fi
        \newpage
        \begin{lrbox}{\paneltext}\begin{minipage}[t][\panelheight][c]{\panelwidth}
    }
    {%
        \end{minipage}\end{lrbox}
        \begin{textblock*}{\panelwidth}(0pt,0pt)
        \noindent
        \rotatebox[origin=c]{180}{\usebox{\paneltext}}
        \end{textblock*}
    }

    \newenvironment{insideleft}{%
        \iffalse
        \AtBeginShipout{
            \ifnewpage
                \newpage
                \global\newpagefalse
            \fi
        }
        \fi
        \begin{lrbox}{\paneltext}\begin{minipage}[t][\panelheight][c]{\panelwidth}
    }
    {%
        \end{minipage}\end{lrbox}
        \begin{textblock*}{\panelwidth}(\TPHorizModule,0pt)
        \noindent
        \rotatebox[origin=c]{180}{\usebox{\paneltext}}
        \end{textblock*}
    }

    \newenvironment{backcover}{%
    %\begin{textblock*}{\panelwidth}(0pt,\TPVertModule)
    \begin{textblock*}{\panelwidth}(0pt,0pt)
    \noindent
    \begin{minipage}[t][\panelheight][c]{\panelwidth}}
    {\end{minipage}\end{textblock*}}

    \newenvironment{frontcover}{%
    \begin{textblock*}{\panelwidth}(\TPHorizModule,0pt)
    \noindent
    \begin{minipage}[t][\panelheight][c]{\panelwidth}}
    {\end{minipage}\end{textblock*}}
\else 
    %Margins for one-sided
    \setlength{\gcguttermargin}{0.2 in} % inside of panel  
    \setlength{\gcedgemargin}{\gcguttermargin}  % outside
    \setlength{\gctopmargin}{0.2 in}        % top
    \setlength{\gcbottommargin}{\gctopmargin}  % bottom
    % Define environments for four panels.  The two outside ones (frontcover and
    % backcover) need to be rotated.
    % These environments place the user's material vertically centered in a minipage
    % of width \panelwidth and height \panelheight.
    \newenvironment{frontcover}{%
    \begin{lrbox}{\paneltext}\begin{minipage}[t][\panelheight][c]{\panelwidth}}
    {\end{minipage}\end{lrbox}
    \begin{textblock*}{\panelwidth}(0pt,0pt)
    \noindent
    \rotatebox[origin=c]{180}{\usebox{\paneltext}}
    \end{textblock*}}

    \newenvironment{backcover}{%
    \begin{lrbox}{\paneltext}\begin{minipage}[t][\panelheight][c]{\panelwidth}}
    {\end{minipage}\end{lrbox}
    \begin{textblock*}{\panelwidth}(\TPHorizModule,0pt)
    \noindent
    \rotatebox[origin=c]{180}{\usebox{\paneltext}}
    \end{textblock*}}

    \newenvironment{insideleft}{%
    \begin{textblock*}{\panelwidth}(0pt,\TPVertModule)
    \noindent
    \begin{minipage}[t][\panelheight][c]{\panelwidth}}
    {\end{minipage}\end{textblock*}}

    \newenvironment{insideright}{%
    \begin{textblock*}{\panelwidth}(\TPHorizModule,\TPVertModule)
    \noindent
    \begin{minipage}[t][\panelheight][c]{\panelwidth}}
    {\end{minipage}\end{textblock*}}
\fi

\AtBeginDocument{
% turn off page numbering
\pagestyle{empty}
% User should have chosen margins by now; compute panel sizes
% and ``step sizes'' for placing panels
\iftwosided
    \setlength{\panelwidth}{(\paperwidth-2\gcguttermargin-2\gcedgemargin)/2}
    \setlength{\panelheight}{(\paperheight-\gctopmargin-\gcbottommargin)}
    \setlength{\TPHorizModule}{\panelwidth+2\gcguttermargin}
    \setlength{\TPVertModule}{\panelheight}
    % Set position of upper left corner of upper left panel (front cover)
    % with command from textpos package.
    \textblockorigin{\gcedgemargin}{\gcbottommargin}
\else
    \setlength{\panelwidth}{(\paperwidth-2\gcguttermargin-2\gcedgemargin)/2}
    \setlength{\panelheight}{(\paperheight-2\gctopmargin-2\gcbottommargin)/2}
    \setlength{\TPHorizModule}{\panelwidth + 2\gcguttermargin}
    \setlength{\TPVertModule}{\panelheight + 2\gctopmargin}
    % Set position of upper left corner of upper left panel (front cover)
    % with command from textpos package.
    \textblockorigin{\gcedgemargin}{\gcbottommargin}
\fi
}
\iftwosided
    \AtEndDocument{
        %Can I somehow group the environments here like in faltblat.cls?
    }
\fi

gcard2-example.tex

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[twosided,showboxes]{gcard2}

\begin{document}

\begin{frontcover}
Front cover
\end{frontcover}
\begin{backcover}
Back cover
\end{backcover}

\newpage

\begin{insideleft}
Inside Left
\end{insideleft}
\begin{insideright}
Inside Right
\end{insideright}

\begin{frontcover}
Second time front cover
\end{frontcover}
\end{document}

输出: <code>gcard2-example.tex</code> 的输出

答案1

通过一些额外的思考和实验,我能够实现两个目标:

关于将特定环境放到第二页的第一个目标,我可以(\global稍微)将环境的内容保存在一个框中,然后放置一个\newpage和一个\vbox(因为我使用的是textpos*,这需要垂直模式),其中包含已保存的这些环境的框。完整示例:

\newsavebox{\insideleftbox}
\NewEnviron{insideleft}{%
    \begin{lrbox}{\paneltext}\begin{minipage}[t][\panelheight][c]{\panelwidth}
}
[
    \end{minipage}\end{lrbox}
    \global\sbox\insideleftbox{\usebox{\paneltext}}
]
\AtEndDocument{
    \newpage
    \vbox{%
        \begin{textblock*}{\panelwidth}(0pt,0pt)
            \usebox{\insideleftbox}
        \end{textblock*}
    }
}

关于“保护”每个环境以便只打印一次,使用这个帖子的答案https://tex.stackexchange.com/a/15521/132624我想到了一个办法,设置一个布尔标志\newif\iffrontcoverbool\frontcoverbooltrue,然后在环境定义的末尾将其设置为false,并在 and 代码周围放置一个 if ,\BODY这样它只会在标志为 时打印true,并\PackageWarning在标志为 时打印false。完整示例:

\newif\iffrontcoverbool\frontcoverbooltrue
\NewEnviron{frontcover}{}[
    \iffrontcoverbool
    {
        \BODY
    }
    \else
    {
        \PackageWarning{\packagename}{\duplicateenvironerrortext{frontcover}}
    }
    \fi
    \global\frontcoverboolfalse
]

(其中我已经适当地定义了宏\duplicateenvironerrortext来接受一个参数并输出我想要的任何文本,并且\paneltext已经在原始gcard包中定义了一个保存框)。

相关内容