0

I am trying to create a package (based on gcard) that also gives the option to allow the four environments to be printed on the front and back of the page (translation: on two pages, with the second page upside down), in addition to the existing option to make all four environments on the same page with the top two environments upside down. The gcard package gives the four environments frontcover, backcover, insideleft, and insideright, and places them at specific positions and orientations (no matter the order in which the environments are invoked in the .tex file) on the single page using the textpos and graphicx packages. I was able to make a modified package file gcard2.sty that appropriately sizes the four environments and places thepairs in the correct positions with respect to the other in the pair (i.e., backcover and frontcover right-side-up from left to right, and insideright and insideleft upside-down from left to right), but I am stuck on getting the inside pair to appear on a second page.

I have attempted to add a \newpage to the begin argument in the environment definition through the use of \AtBeginShipout and \if flags to determine the current page, as in the question How to track a page change within an environment?, but my attempt was unsuccessful (see the \iffalse \fi pairs in the posted MWE). I also thought about trying to put something in \AtEndDocument with grouped boxes, as done in the class faltblat.cls (available from CTAN, here for example), but I was not able to figure out how to put the environments in the specific boxes from the package definitions (and I was unable to understand the comments in that class file since I do not speak that language). I even tried to just add the command \newpage to the begin argument, but that did not seem to work either.

I also would like to enforce the rule that each environment can only be called once, since at the moment if you call an environment twice then it will overlay both arguments on the same position, but this is more of a bonus.

Can someone please assist me in getting the environments on the appropriate pages? Can someone also help me ensure that at most only one call to each environment is printed?

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}

Output: Output of <code>gcard2-example.tex</code>

1
0

With some additional thought and experimentation, I was able to achieve both goals:

With regards to the first goal of getting specific environments onto the second page, I could (\globally) save the contents of the environments in a box and then place a \newpage and a \vbox (since I am using textpos*, which requires vertical mode) with the saved boxes for those environments in it. Full example:

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

With regard to "protecting" each environment so that it is only printed once, using the answer to this post https://tex.stackexchange.com/a/15521/132624 I was able to come up with an idea to set a boolean flag \newif\iffrontcoverbool\frontcoverbooltrue and then at the end of the environment definition set it to false and put an if around the \BODY and code so that it would only print if the flag was true, and print a \PackageWarning if the flag was false. Full example:

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

(where I have suitably defined the macro \duplicateenvironerrortext to take one argument and output whatever text I desire, and \paneltext was already a savebox defined in the original gcard package).

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.