%D \module
%D   [       file=page-imp, % was: core-pag,
%D        version=1998.01.15,
%D          title=\CONTEXT\ Page Macros,
%D       subtitle=Pagebody Building (Imposition),
%D         author=Hans Hagen & Willi Egger,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% much of this can more to run time loading !

\writestatus{loading}{ConTeXt Page Macros / Pagebody Building}

\unprotect

%D \macros
%D   {starttextdata}
%D
%D This is a user macro (appending to every last shipout is not really user
%D friendly).

\newtoks\t_page_text_data

\permanent\protected\def\starttextdata#1\stoptextdata
  {\glet\page_shipouts_flush_text_data\page_shipouts_flush_text_data_indeed
   \globaladdtotoks\t_page_text_data{#1}}

\aliased\let\stoptextdata\relax

\def\page_shipouts_flush_text_data_indeed
  {\vsmashed{\expand\t_page_text_data}%
   \global\t_page_text_data\emptytoks
   \glet\page_shipouts_flush_text_data\relax}

\let\page_shipouts_flush_text_data\relax

\prependtoks
    \page_shipouts_flush_text_data
\to \everylastshipout

%D Problem: we need to apply the finalizers to a to be shipped out page (as we can
%D have positioning involved). However, we can also add stuff in the imposition,
%D like cropmarks. Fortunately we do that with metapost so colors etc are dealt with
%D at that end.

% \starttypen
% \def\pagestoshipout{1,3,5}
% \stoptypen

\installcorenamespace{shipoutmethod}
\installcorenamespace{layoutarranger}
\installcorenamespace{layoutarrangeoption}

\newinteger    \shippedoutpages
\newinteger    \combinedpagescounter
\newconstant   \whichpagetoshipout % 0=all 1=odd 2=even
\newbox        \shipoutscratchbox
\setnewconstant\shipoutfinalizemethod\plusone

\mutable\lettonothing\pagestoshipout % {1,3,6}

\permanent\protected\def\shipoutrange#1#2%
  {\begingroup
   \scratchtoks\emptytoks
   \dostepwiserecurse{#1}{\numexpr#2-\plusone\relax}\plusone{\etoksapp\scratchtoks{##1,}}%
   \xdef\pagestoshipout{\the\scratchtoks,\number#2}%
   \gtoksapp\everyaftershipout{\ifnum\realpageno>\numexpr#2+\plusone\relax\global\everypar{\normalend}\fi}%
   \endgroup}

\permanent\protected\def\installshipoutmethod#1#2%      % a handler takes one argument: something to be boxed
  {\gdefcsname\??shipoutmethod#1\endcsname##1{#2{##1}}} % and shipped out (don't depend on the exact package)

\aliased\let\installpagehandler\installshipoutmethod % will go

\permanent\protected\def\invokepagehandler#1%
  {\expandnamespacevalue\??shipoutmethod{#1}\v!normal}

\def\page_shipouts_handle
  {\ifcsname\??shipoutmethod\v_page_target_method\endcsname
     \expandafter\lastnamedcs
   \else
     \expandafter\page_shipouts_ignore
   \fi}

\installshipoutmethod \v!normal
  {\ifarrangingpages
     \expandafter\page_shipouts_arrange
   \else
     \expandafter\page_shipouts_normal
   \fi}

\installshipoutmethod \v!none
  {\page_shipouts_ignore}

% \setuppaper[method=rotate,rotation=15] \showframe
% \starttext \dorecurse{10}{\input knuth\endgraf} \stoptext

\installshipoutmethod\v!rotate
  {\page_shipouts_rotate}

\protected\def\page_shipouts_rotate#1%
  {\invokepagehandler\v!normal{\rotate[\c!rotation=\rootlayouttargetparameter\c!rotation]{#1}}}

% inject an empty page after each page

\def\page_shipouts_double#1%
  {\page_shipouts_normal{#1}%
   \page_shipouts_normal{\null}}

\installshipoutmethod \v!doublesided
  {\ifarrangingpages
     \expandafter\page_shipouts_arrange
   \else
     \expandafter\page_shipouts_double
   \fi}

% extension mechanism

\newinteger\c_page_boxes_flush_n % set at the lua end

\let\page_boxes_flush_before\relax
\let\page_boxes_flush_after \relax

% used here:

\def\page_boxes_shipout#1% or: \page_shipouts_apply
  {\dontcomplain         % redundant
   \ifcase\c_page_boxes_flush_n\else
     \page_boxes_flush_before
   \fi
   \expand\everybeforeshipout
   \ifcase\shipoutfinalizemethod % not nice ... needs thinking
     \page_shipouts_handle{#1}%
   \else
     \setbox\shipoutscratchbox\hpack
       {#1}% just in case there are objects there, hook for testing (will go away)
     \page_shipouts_handle
       {\finalizeshipoutbox\shipoutscratchbox
        \box\shipoutscratchbox}%
   \fi
   \setnextrealpageno       % so this comes before \everyaftershipout so in fact:
   \expand\everyaftershipout   % at this point we're already on the next realpage
   \ifcase\c_page_boxes_flush_n\else
     \page_boxes_flush_after
   \fi}

\def\page_shipouts_ignore#1%
  {\begingroup
   \writestatus\m!system
     {\ifarrangingpages arranged\normalspace\fi page\normalspace
      \ifarrangingpages\the\arrangeno\else\the\realpageno\fi\normalspace
       not\normalspace flushed}%
 % \setbox\scratchbox\hpack
 %   {#1}% no finalize
   \deadcycles\zerocount
   \endgroup}

\def\page_otr_flush_every_stuff
  {\begingroup
   \setbox\scratchbox\hpack
     {% before the main one !
      \ifcase\realfolio \or
        \expand\everyfirstshipout
        \global\everyfirstshipout\emptytoks
      \fi
      % the main one
      \expand\everyshipout\relax
      % always last (and after the main one)
      \ifnum\realpageno=\lastpage\relax
        \expand\everylastshipout
        \global\everylastshipout\emptytoks
      \fi}%
   \smashbox\scratchbox
   \box\scratchbox
   \endgroup}

%D We just ignore \type {\shipout}.

\pushoverloadmode

\permanent\protected\def\shipout
  {\begingroup\dowithnextboxcs\endgroup}

\popoverloadmode

%D Also in normal \MKIV\ we nos use the indirect way so that we benefit from timing
%D and tracing.

\def\page_shipout_show_box{\showbox diagnose}

\protected\def\page_shipout_box#1%
  {\ifcase\tracingoutput\else
     \page_shipout_show_box#1\relax
   \fi
   \clf_shipoutpage#1\relax
   \global\setbox#1\emptybox
   \global\deadcycles\zerocount
   \clf_cleanupattributes}

\def\page_shipouts_normal#1%
  {\global\advanceby\shippedoutpages\plusone
   % this is not resource safe!
   \ifempty\pagestoshipout
     \ifcase\whichpagetoshipout\relax
       \donetrue
     \or % 1
       \ifodd\shippedoutpages\relax\donetrue\else\donefalse\fi
     \or % 2
       \ifodd\shippedoutpages\relax\donefalse\else\donetrue\fi
     \else
       \donetrue
     \fi
   \orelse\ifinset{\the\shippedoutpages}{\pagestoshipout}%
     \donetrue
   \else
     \donefalse
   \fi
   \ifdone
     \setbox\shipoutscratchbox\hpack
       {#1}% finalizes
     \ifcase\shipoutfinalizemethod
       \finalizeshipoutbox\shipoutscratchbox
     \fi
     \setbox\shipoutscratchbox\vpack
       {\hpack
          {\page_otr_flush_every_stuff
           \page_otr_flush_special_content
           \box\shipoutscratchbox}}%
     \page_shipout_box\shipoutscratchbox % takes a box number!
   \else
     \page_shipouts_ignore{#1}%
   \fi}

\newconditional\c_page_shipouts_use_objects \c_page_shipouts_use_objects\conditionaltrue

\installcorenamespace {arrangedpage}

\def\page_shipouts_arrange#1%
  {\begingroup
   \setbox\shipoutscratchbox\hpack
     {#1}% finalizes
   \setbox\shipoutscratchbox\hpack
     {\page_otr_flush_every_stuff
      \page_otr_flush_special_content
      \box\shipoutscratchbox}%
   %
   \ifconditional\c_page_shipouts_use_objects
     \setobject\??arrangedpage{\the\realpageno}\hpack{\box\shipoutscratchbox}%
     \setbox\shipoutscratchbox\hpack{\getobject\??arrangedpage{\the\realpageno}}%
   \fi
   %
   \pusharrangedpage\shipoutscratchbox
   \deadcycles\zerocount
   \endgroup}

%D We need a couple of boxes for duplex printing \unknown

\newbox\arrangedpageA \newbox\arrangedpageB
\newbox\arrangedpageC \newbox\arrangedpageD
\newbox\arrangedpageE \newbox\arrangedpageF
\newbox\arrangedpageG \newbox\arrangedpageH

\newconditional\arrangedswapstate
\newconditional\arrangednegatestate
\newconditional\arrangedmirrorstate
\newconditional\arrangeddoublestate
\newconditional\arrangingdisabledstate
\newconditional\arrangedbackgroundstate

\mutable\def\arrangedrotationO{0}
\mutable\def\arrangedrotationE{0}

\newinteger\arrangedpageN
\newinteger\arrangedpageM

\newinteger\arrangedpageT \arrangedpageT\plusone
\newinteger\arrangedpageX \arrangedpageX\plusone
\newinteger\arrangedpageY \arrangedpageY\plusone

\def\page_paper_set_offsets
  {\global\paperoffset\v_page_target_offset
   \global\advanceby\paperwidth -2\dimexpr\paperoffset/\arrangedpageX\relax
   \global\advanceby\paperheight-2\dimexpr\paperoffset/\arrangedpageY\relax}

\permanent\protected\def\doinstallarrangedoption#1#2%
  {\gdefcsname\??layoutarrangeoption#1\endcsname{#2}}

\permanent\def\doinstalledarrangedoption#1%
  {\ifcsname\??layoutarrangeoption#1\endcsname
     \lastnamedcs
   \else
     \checkinstalledpagearrangement{#1}% this installs the arranger
   \fi}

\doinstallarrangedoption\empty
  {} % no default and check if empty, we can have ,,,

\doinstallarrangedoption\v!disable
  {\global\arrangingdisabledstate\conditionaltrue}

\doinstallarrangedoption\v!mirrored
  {\global\arrangedmirrorstate\conditionaltrue}

\doinstallarrangedoption\v!doublesided
  {\global\arrangeddoublestate\conditionaltrue}

\doinstallarrangedoption\v!negative
  {\global\arrangednegatestate\conditionaltrue}

\doinstallarrangedoption\v!rotated
  {\gdef\arrangedrotationO {90}%
   \gdef\arrangedrotationE{270}%
   \swapcounts\c_page_marks_nx\c_page_marks_ny}

\doinstallarrangedoption{90}
  {\gdef\arrangedrotationO {90}%
   \gdef\arrangedrotationE{270}%
   \swapcounts\c_page_marks_nx\c_page_marks_ny}

\doinstallarrangedoption{180}
  {\gdef\arrangedrotationO{180}%
   \gdef\arrangedrotationE  {0}}

\doinstallarrangedoption{270}
  {\gdef\arrangedrotationO{270}%
   \gdef\arrangedrotationE {90}%
   \swapcounts\c_page_marks_nx\c_page_marks_ny}

\doinstallarrangedoption\s!reset
  {\global\arrangingpagesfalse}

\doinstallarrangedoption\v!background
  {\global\arrangedbackgroundstate\conditionaltrue}

\aliased\let\poparrangedpages  \relax
\aliased\let\pusharrangedpage  \gobbleoneargument
\aliased\let\handlearrangedpage\relax

\permanent\protected\def\setuparranging[#1]%
  {\ifconditional\arrangingdisabledstate \else
     %global\arrangingdisabledstate\conditionalfalse
     \global\arrangingpagestrue % will be conditional
     \global\arrangednegatestate\conditionalfalse
     \global\arrangedmirrorstate\conditionalfalse
     \global\arrangeddoublestate\conditionalfalse
     \global\arrangedswapstate\conditionalfalse
     \gdef\arrangedrotationO{0}%
     \gdef\arrangedrotationE{180}%
     % if we use --arrange we have an initial "disable" here
     \processcommalist[#1]\doinstalledarrangedoption
     \ifrelax\poparrangedpages
       \global\arrangingpagesfalse % nothing set yet
     \fi
     \setuppapersize
     \ifarrangingpages
        \ifconditional\c_page_shipouts_use_objects\else
          \clf_disablejobsave
          \clf_synctexdisable
         %\disabledirective[job.save]%
        \fi
     \fi
   \fi}

\permanent\protected\def\installpagearrangement #1 % will change, no space
  {\gdefcsname\??layoutarranger#1\endcsname}

\permanent\def\checkinstalledpagearrangement#1% can be empty: aaa,,bbb
  {\begincsname\??layoutarranger#1\endcsname}

\permanent\protected\def\dosetuparrangement#1#2#3#4#5#6#7#8%
  {\global\arrangedpageX  #1%
   \global\arrangedpageY  #2%
   \global\arrangedpageT  #3%
   \global\c_page_marks_nx#4%
   \global\c_page_marks_ny#5%
   \enforced\glet\pusharrangedpage  #6%
   \enforced\glet\poparrangedpages  #7%
   \enforced\glet\handlearrangedpage#8}

\installpagearrangement {\v!normal}
  {\global\arrangingpagesfalse}

%D (WS:) Watch out with 2UP and A4/A5:
%D
%D \definepapersize [A4] [width=210mm,height=297mm]
%D \definepapersize [A5] [width=148mm,height=210mm]
%D
%D 297 mm - 2 * 148 mm = 1 mm
%D
%D This is only visible when we have a full background.

\installpagearrangement 2*16
  {\dosetuparrangement{4}{4}{16}{5}{5}%
     \pusharrangedpageTHIRTYTWO\poparrangedpagesAB\relax}

\installpagearrangement 2*8
  {\dosetuparrangement{4}{2}{8}{5}{3}%
     \pusharrangedpageSIXTEEN\poparrangedpagesAB\relax}

\installpagearrangement 2*4
  {\dosetuparrangement{2}{2}{4}{3}{3}%
     \pusharrangedpageEIGHT\poparrangedpagesAB\relax}

\installpagearrangement 2*2
  {\dosetuparrangement{2}{1}{2}{3}{2}%
     \pusharrangedpageFOURA\poparrangedpagesAB\relax}

\installpagearrangement 2**2
  {\dosetuparrangement{2}{1}{2}{3}{2}%
     \pusharrangedpageFOURB\poparrangedpagesAB\relax}

\installpagearrangement 2SIDE
  {\dosetuparrangement{2}{1}{2}{3}{2}%
     \pusharrangedpageSIDETOP\poparrangedpagesTWO\handlearrangedpageSIDE}

\installpagearrangement 2TOP
  {\dosetuparrangement{1}{2}{2}{2}{3}%
     \pusharrangedpageSIDETOP\poparrangedpagesTWO\handlearrangedpageTOP}

\installpagearrangement 2UP
  {\dosetuparrangement{2}{1}{4}{3}{2}%
     \pusharrangedpageTWO\poparrangedpagesTWO\handlearrangedpageTWOUP}

\installpagearrangement 2DOWN
  {\dosetuparrangement{1}{2}{4}{2}{3}%
     \pusharrangedpageTWO\poparrangedpagesTWO\handlearrangedpageTWODOWN}

\installpagearrangement 2*4*2 % one defined by Willy Egger:
  {\dosetuparrangement{2}{2}{4}{3}{3}%
     \pusharrangedpageSIXTEENTWO\poparrangedpagesAtoD\relax}

\installpagearrangement 2*2*4 % another one of Willy Egger
  {\dosetuparrangement{2}{1}{8}{3}{2}%
     \pusharrangedpageSIXTEENFOUR\poparrangedpagesAtoH\relax}

\installpagearrangement 2TOPSIDE
  {\dosetuparrangement{1}{2}{4}{2}{3}%
     \pusharrangedpageTWOTOPSIDE\poparrangedpagesTWOTOPSIDE\handlearrangedpageTOP}

\permanent\protected\def\filluparrangedpages % beware: \realpageno is 1 ahead
  {\ifarrangingpages
     \scratchcounter\numexpr\realpageno-\plusone\relax
     \dosetmodulo\scratchcounter\arrangedpageT\scratchcounter
     \ifcase\scratchcounter\else
       \advanceby\scratchcounter \plusone
       \dostepwiserecurse\scratchcounter\arrangedpageT\plusone
         {\noheaderandfooterlines\page_otr_insert_dummy_page}%
     \fi
   \fi}

\permanent\protected\def\handlearrangedpageXandY#1#2#3#4#5%
  {\global\setbox#5\hpack to \arrangedpageX\paperwidth
     {\setbox\scratchbox\vpack to \arrangedpageY\paperheight
        {\offinterlineskip
         \vskip#4\paperheight
         \hkern#3\paperwidth
         \dorotatebox{\ifcase#2 0\else180\fi}\hpack{\box#1}%
         \vfill}%
      \wd\scratchbox\zeropoint
      \box\scratchbox\box#5\hss}}

\permanent\protected\def\gotonextarrangepage
  {\global\advanceby\arrangeno\plusone}

\permanent\protected\def\outputarrangedbox#1%
  {\begingroup
   \forgetall % somehow we're back and need to redo this
   \dontcomplain
   \gotonextarrangepage
   \ifnum\arrangedrotationO\arrangedrotationE>\zerocount
     \setbox#1\vpack
       {\ifconditional\arrangeddoublestate
          \ifodd\arrangeno
            \dorotatebox\arrangedrotationO\hpack{\box#1}%
          \else
            \dorotatebox\arrangedrotationE\hpack{\box#1}%
          \fi
        \else
          \dorotatebox\arrangedrotationO\hpack{\box#1}%
        \fi}%
   \fi
   \ifconditional\arrangedmirrorstate
     \page_boxes_apply_mirror{#1}%
   \fi
   \ifconditional\arrangednegatestate
     \page_boxes_apply_negate{#1}%
   \fi
   \page_marks_add_more             #1%
   \page_boxes_apply_center         #1%
   \page_boxes_apply_mirror_print   #1%
   \page_boxes_apply_orientate_print#1%
   \page_boxes_apply_offset         #1%
   \page_boxes_apply_negate_print   #1%
   %
   \ifconditional\arrangedbackgroundstate
     \page_backgrounds_add_to_print#1%
   \fi
   %
   \page_shipouts_normal{\box#1}%
   \endgroup}

%D The format file can be 16K smaller when we postpone the
%D real arrangments. Some day ...

\permanent\protected\def\reportarrangedpage#1%
  {\showmessage\m!system{23}{\the\realpageno.\the\pageno\ifnum\subpageno>0 .\the\subpageno\fi,\number#1}}

\permanent\protected\def\advancearrangedpageN
  {\global\advanceby\arrangedpageN\plusone}

% TOP

% 32/16/8/4/SIDE

\permanent\protected\def\poparrangedpagesAB
  {\ifnum\arrangedpageN>\zerocount
     \paperwidth\arrangedpageX\paperwidth
     \paperheight\arrangedpageY\paperheight
     \outputarrangedbox\arrangedpageA
     \outputarrangedbox\arrangedpageB
     \global\arrangedpageN\zerocount
   \fi}

\permanent\protected\def\pusharrangedpageTHIRTYTWO#1% taco's challenge
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}033\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}003\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}100\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}130\arrangedpageA %  4
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}130\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}033\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}003\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}102\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}132\arrangedpageB % 10
   \or \handlearrangedpageXandY{#1}031\arrangedpageB % 11
   \or \handlearrangedpageXandY{#1}001\arrangedpageA % 12
   \or \handlearrangedpageXandY{#1}031\arrangedpageA % 13
   \or \handlearrangedpageXandY{#1}001\arrangedpageB % 14
   \or \handlearrangedpageXandY{#1}102\arrangedpageB % 15
   \or \handlearrangedpageXandY{#1}132\arrangedpageA % 16
   \or \handlearrangedpageXandY{#1}122\arrangedpageA % 17
   \or \handlearrangedpageXandY{#1}112\arrangedpageB % 18
   \or \handlearrangedpageXandY{#1}011\arrangedpageB % 19
   \or \handlearrangedpageXandY{#1}021\arrangedpageA % 20
   \or \handlearrangedpageXandY{#1}011\arrangedpageA % 21
   \or \handlearrangedpageXandY{#1}021\arrangedpageB % 22
   \or \handlearrangedpageXandY{#1}122\arrangedpageB % 23
   \or \handlearrangedpageXandY{#1}112\arrangedpageA % 24
   \or \handlearrangedpageXandY{#1}013\arrangedpageA % 25
   \or \handlearrangedpageXandY{#1}023\arrangedpageB % 26
   \or \handlearrangedpageXandY{#1}120\arrangedpageB % 27
   \or \handlearrangedpageXandY{#1}110\arrangedpageA % 28
   \or \handlearrangedpageXandY{#1}120\arrangedpageA % 29
   \or \handlearrangedpageXandY{#1}110\arrangedpageB % 30
   \or \handlearrangedpageXandY{#1}013\arrangedpageB % 31
   \or \handlearrangedpageXandY{#1}023\arrangedpageA % 32
     \poparrangedpages
   \fi}

\permanent\protected\def\pusharrangedpageSIXTEEN#1% changed to match the official way of doing
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}031\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}001\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}031\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}001\arrangedpageA %  4
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}130\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}100\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}130\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}120\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}110\arrangedpageB % 10
   \or \handlearrangedpageXandY{#1}120\arrangedpageB % 11
   \or \handlearrangedpageXandY{#1}110\arrangedpageA % 12
   \or \handlearrangedpageXandY{#1}011\arrangedpageA % 13
   \or \handlearrangedpageXandY{#1}021\arrangedpageB % 14
   \or \handlearrangedpageXandY{#1}011\arrangedpageB % 15
   \or \handlearrangedpageXandY{#1}021\arrangedpageA % 16
     \poparrangedpages
   \fi}

\permanent\protected\def\pusharrangedpageEIGHT#1% changed to match the official way of doing
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}011\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}001\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}100\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}110\arrangedpageA %  4
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}110\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}011\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}001\arrangedpageA %  8
     \poparrangedpages
   \fi}

\permanent\protected\def\pusharrangedpageFOURA{\pusharrangedpageFOURdo01}
\permanent\protected\def\pusharrangedpageFOURB{\pusharrangedpageFOURdo10}

\permanent\protected\def\pusharrangedpageFOURdo#1#2#3%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#3}010\arrangedpageA    %  1
   \or \handlearrangedpageXandY{#3}0{#1}0\arrangedpageB %  2/3 not {1}
   \or \handlearrangedpageXandY{#3}0{#2}0\arrangedpageB %  3/2 not {1}
   \or \handlearrangedpageXandY{#3}000\arrangedpageA    %  4
     \poparrangedpages
   \fi}

\permanent\protected\def\pusharrangedpageSIDETOP#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
     \poparrangedpages
   \fi}

\permanent\protected\def\handlearrangedpageSIDE
  {\wd\arrangedpageA\paperwidth
   \wd\arrangedpageB\paperwidth
   \global\setbox\arrangedpageA\hpack
     {\box\arrangedpageA\box\arrangedpageB}%
   \ht\arrangedpageA\paperheight}

\permanent\protected\def\handlearrangedpageTOP
  {\ht\arrangedpageA\paperheight
   \ht\arrangedpageB\paperheight
   \global\setbox\arrangedpageA\vpack
     {\offinterlineskip\vskip\paperheight
      \box\arrangedpageA\box\arrangedpageB}%
   \global\setbox\arrangedpageB\box\scratchbox} % ?

% 2UP/2DOWN / 1pt prevents overflow

\permanent\protected\def\splitoffarrangedpagesTWO
  {\splittopskip\zeroskip
   \global\setbox\arrangedpageA\vsplit\arrangedpageB to \onepoint
   \scratchdimen\dimexpr\ht\arrangedpageB-\onepoint\relax
   \ifdim\scratchdimen>\onepoint
     \setbox\scratchbox\vsplit\arrangedpageB to \scratchdimen
   \fi}

\permanent\protected\def\handlearrangedpageTWOUP
  {\splitoffarrangedpagesTWO
   \ht\arrangedpageA\paperheight
   \ht\arrangedpageB\paperheight
   \ifconditional\arrangedswapstate
     \global\setbox\arrangedpageA\hpack
       {\page_boxes_apply_clip_print_left \arrangedpageA
        \box\arrangedpageA
        \page_boxes_apply_clip_print_right\arrangedpageB
        \box\arrangedpageB}%
     \arrangedswapstate\conditionalfalse
   \else
     \global\setbox\arrangedpageA\hpack
       {\page_boxes_apply_clip_print_left \arrangedpageB
        \box\arrangedpageB
        \page_boxes_apply_clip_print_right\arrangedpageA
        \box\arrangedpageA}%
     \arrangedswapstate\conditionaltrue
   \fi
   \global\setbox\arrangedpageB\box\scratchbox}

\permanent\protected\def\handlearrangedpageTWODOWN
  {\splitoffarrangedpagesTWO
   \ht\arrangedpageA\paperheight
   \ht\arrangedpageB\paperheight
   \ifconditional\arrangedswapstate
     \global\setbox\arrangedpageA\vpack
       {\offinterlineskip
        \vskip\paperheight
        \box\arrangedpageA
        \box\arrangedpageB}%
     \arrangedswapstate\conditionalfalse
   \else
     \global\setbox\arrangedpageA\vpack
       {\offinterlineskip
        \vskip\paperheight
        \box\arrangedpageB
        \box\arrangedpageA}%
     \arrangedswapstate\conditionaltrue
   \fi
   \global\setbox\arrangedpageB\box\scratchbox}

\permanent\protected\def\poparrangedpagesTWO
  {\ifnum\arrangedpageN>\zerocount
     \arrangedswapstate\conditionalfalse
     \doloop
       {\handlearrangedpage
        \bgroup
        \paperwidth \arrangedpageX\paperwidth
        \paperheight\arrangedpageY\paperheight
        \ht\arrangedpageA\paperheight
        \wd\arrangedpageA\paperwidth
        \outputarrangedbox\arrangedpageA
        \egroup
        \ifzeropt\ht\arrangedpageB
          \exitloop
        \fi}%
     \global\arrangedpageN\zerocount
   \fi}

\permanent\protected\def\pusharrangedpageTWO#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \global\setbox\arrangedpageB\vpack
     {\offinterlineskip
      \unvbox\arrangedpageB
      \allowbreak
      \setbox#1\vpack{\box#1}% really needed in order to keep real dimensions
      \ht#1\onepoint
      \dp#1\zeropoint
      \vpack{\box#1}}}

\permanent\protected\def\poparrangedpagesTWOTOPSIDE
  {\ifnum\arrangedpageN>\zerocount
     \bgroup
     \global\arrangedpageN\plustwo
     \poparrangedpagesTWO
     \let\arrangedpageA\arrangedpageC
     \let\arrangedpageB\arrangedpageD
     \global\arrangedpageN\plustwo
     \poparrangedpagesTWO
     \global\arrangedpageN\zerocount
     \egroup
  \fi}

\permanent\protected\def\pusharrangedpageTWOTOPSIDE#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}000\arrangedpageC %  2
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  1
   \or \handlearrangedpageXandY{#1}000\arrangedpageD %  2
     \poparrangedpages
   \fi}

%D Willy Egger's sheet simulations:

\permanent\protected\def\poparrangedpagesAtoH
  {\ifnum\arrangedpageN>\zerocount
     \paperwidth \arrangedpageX\paperwidth
     \paperheight\arrangedpageY\paperheight
     \outputarrangedbox\arrangedpageA
     \outputarrangedbox\arrangedpageB
     \outputarrangedbox\arrangedpageC
     \outputarrangedbox\arrangedpageD
     \outputarrangedbox\arrangedpageE
     \outputarrangedbox\arrangedpageF
     \outputarrangedbox\arrangedpageG
     \outputarrangedbox\arrangedpageH
     \global\arrangedpageN\zerocount
   \fi}

% to arrange 16 pages on 2 sheets to form one booklet

\permanent\protected\def\poparrangedpagesAtoD
  {\ifnum\arrangedpageN>\zerocount
     \paperwidth\arrangedpageX\paperwidth
     \paperheight\arrangedpageY\paperheight
     \outputarrangedbox\arrangedpageA
     \outputarrangedbox\arrangedpageB
     \outputarrangedbox\arrangedpageC
     \outputarrangedbox\arrangedpageD
     \global\arrangedpageN\zerocount
   \fi}

% to arrange 16 pages on 4 sheets to form one booklet

\permanent\protected\def\pusharrangedpageSIXTEENFOUR#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageC %  3
   \or \handlearrangedpageXandY{#1}000\arrangedpageD %  4
   \or \handlearrangedpageXandY{#1}010\arrangedpageE %  5
   \or \handlearrangedpageXandY{#1}000\arrangedpageF %  6
   \or \handlearrangedpageXandY{#1}010\arrangedpageG %  7
   \or \handlearrangedpageXandY{#1}000\arrangedpageH %  8
   \or \handlearrangedpageXandY{#1}010\arrangedpageH %  9
   \or \handlearrangedpageXandY{#1}000\arrangedpageG % 10
   \or \handlearrangedpageXandY{#1}010\arrangedpageF % 11
   \or \handlearrangedpageXandY{#1}000\arrangedpageE % 12
   \or \handlearrangedpageXandY{#1}010\arrangedpageD % 13
   \or \handlearrangedpageXandY{#1}000\arrangedpageC % 14
   \or \handlearrangedpageXandY{#1}010\arrangedpageB % 15
   \or \handlearrangedpageXandY{#1}000\arrangedpageA % 16
     \poparrangedpages
   \fi}

% to arrange 16 pages on 2 sheets to form one booklet

\permanent\protected\def\pusharrangedpageSIXTEENTWO#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}011\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}001\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}011\arrangedpageC %  3
   \or \handlearrangedpageXandY{#1}001\arrangedpageD %  4
   \or \handlearrangedpageXandY{#1}100\arrangedpageD %  5
   \or \handlearrangedpageXandY{#1}110\arrangedpageC %  6
   \or \handlearrangedpageXandY{#1}100\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}110\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}110\arrangedpageB % 10
   \or \handlearrangedpageXandY{#1}100\arrangedpageC % 11
   \or \handlearrangedpageXandY{#1}110\arrangedpageD % 12
   \or \handlearrangedpageXandY{#1}011\arrangedpageD % 13
   \or \handlearrangedpageXandY{#1}001\arrangedpageC % 14
   \or \handlearrangedpageXandY{#1}011\arrangedpageB % 15
   \or \handlearrangedpageXandY{#1}001\arrangedpageA % 16
     \poparrangedpages
   \fi}

%D Might be used if a printer is printing from a roll or creating mini-books from A4:
%D This section has 16 pages. The folding scheme is first a Z-fold and at the end
%D a final fold in the spine.
%D Coding: [2*8*Z]

\installpagearrangement 2*8*Z
   {\dosetuparrangement{2}{4}{8}{3}{5}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageSIXTEENZ\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageSIXTEENZ#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  1
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}101\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}111\arrangedpageA %  4
   \or \handlearrangedpageXandY{#1}012\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}002\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}103\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}113\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}103\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}113\arrangedpageB % 10
   \or \handlearrangedpageXandY{#1}012\arrangedpageB % 11
   \or \handlearrangedpageXandY{#1}002\arrangedpageA % 12
   \or \handlearrangedpageXandY{#1}101\arrangedpageA % 13
   \or \handlearrangedpageXandY{#1}111\arrangedpageB % 14
   \or \handlearrangedpageXandY{#1}010\arrangedpageB % 15
   \or \handlearrangedpageXandY{#1}000\arrangedpageA % 16
     \poparrangedpages
   \fi}

%D Another Z-folded section with 12 pages
%D Coding: [2*6*Z]

\installpagearrangement 2*6*Z
   {\dosetuparrangement{2}{3}{6}{3}{4}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageTWELVEZ\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageTWELVEZ#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  1: rotation (0=upright),x (0=first column),y (0=first row)
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}101\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}111\arrangedpageA %  4
   \or \handlearrangedpageXandY{#1}012\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}002\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}012\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}002\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}101\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}111\arrangedpageB % 10
   \or \handlearrangedpageXandY{#1}010\arrangedpageB % 11
   \or \handlearrangedpageXandY{#1}000\arrangedpageA % 12
     \poparrangedpages
   \fi}

%D For Heinz' special greeting cards folding. This scheme is also used for the PocketDiary (module):
%D Coding: [1*8]

\installpagearrangement 1*8
   {\dosetuparrangement{4}{2}{8}{5}{3}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageEIGHTSINGLESIDEDFOLDED\poparrangedpagesTWO\relax}

\permanent\protected\def\pusharrangedpageEIGHTSINGLESIDEDFOLDED#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  1 rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  2
   \or \handlearrangedpageXandY{#1}030\arrangedpageA %  3
   \or \handlearrangedpageXandY{#1}131\arrangedpageA %  4
   \or \handlearrangedpageXandY{#1}121\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}111\arrangedpageA %  6
   \or \handlearrangedpageXandY{#1}101\arrangedpageA %  7
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  8
     \poparrangedpages
   \fi}

%D This is not a section. \CONTEXT\ places 4 pages on a sheet of paper, singlesided
%D Coding: [1*4]

\installpagearrangement 1*4
   {\dosetuparrangement{2}{2}{4}{3}{3}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageFOURSINGLESIDEDFOLDED\poparrangedpagesTWO\relax}

\permanent\protected\def\pusharrangedpageFOURSINGLESIDEDFOLDED#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  1 rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}001\arrangedpageA %  2
   \or \handlearrangedpageXandY{#1}011\arrangedpageA %  3
   \or \handlearrangedpageXandY{#1}110\arrangedpageA %  4
     \poparrangedpages
   \fi}

%D This imposition scheme was requested by Hraban Ramm, by Willi Egger 21-07-2003
%D Coding: [3SIDE]

\installpagearrangement 3SIDE
   {\dosetuparrangement{3}{1}{3}{4}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageTHREESIDE\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageTHREESIDE#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  2
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  3
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  5
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  6
       \poparrangedpages
   \fi}

%D FLYER in three parts and 6 pages 22-10-2010
%D Coding: [TRYPTICHON]

\installpagearrangement TRYPTICHON
   {\dosetuparrangement{3}{1}{3}{4}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageFLYERSIX\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageFLYERSIX#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  5
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  6
       \poparrangedpages
   \fi}

%D FLYER in Z-fold with 8 pages 22-01-2010
%D Coding: [ZFLYER-8]

\installpagearrangement ZFLYER-8
   {\dosetuparrangement{4}{1}{4}{5}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageZFLYEREIGHT\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageZFLYEREIGHT#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}030\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}030\arrangedpageB %  5
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  6
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  7
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  8
       \poparrangedpages
   \fi}

%D FLYER in Z-fold with 10 pages 04-08-2010
%D Coding: [ZFLYER-10]

\installpagearrangement ZFLYER-10
   {\dosetuparrangement{5}{1}{5}{6}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageZFLYERTEN\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageZFLYERTEN#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}040\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}030\arrangedpageB %  5
   \or \handlearrangedpageXandY{#1}040\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  7
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}030\arrangedpageA %  10
       \poparrangedpages
   \fi}

%D FLYER in Z-fold with 12 pages 04-08-2010
%D Coding: [ZFLYER-12]

\installpagearrangement ZFLYER-12
   {\dosetuparrangement{6}{1}{6}{7}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageZFLYERTWELVE\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageZFLYERTWELVE#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}050\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}030\arrangedpageB %  5
   \or \handlearrangedpageXandY{#1}040\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}050\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  10
   \or \handlearrangedpageXandY{#1}030\arrangedpageA %  11
   \or \handlearrangedpageXandY{#1}040\arrangedpageA %  12
       \poparrangedpages
   \fi}

%D FLYER folded as a map with 6 pages per side.
%D Coding: [MAPFLYER-12]

\installpagearrangement MAPFLYER-12
   {\dosetuparrangement{3}{2}{6}{4}{3}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageMFLYERTWELVE\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageMFLYERTWELVE#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}001\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}011\arrangedpageB %  5
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}021\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  8
   \or \handlearrangedpageXandY{#1}001\arrangedpageA %  9
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  10
   \or \handlearrangedpageXandY{#1}011\arrangedpageA %  11
   \or \handlearrangedpageXandY{#1}021\arrangedpageA %  12
       \poparrangedpages
   \fi}

%D FLYER folded as double window with 4 pages per side.
%D Coding: [DOUBLEWINDOW]

\installpagearrangement DOUBLEWINDOW
   {\dosetuparrangement{4}{1}{4}{5}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageDOUBLEWINDOWEIGHT\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageDOUBLEWINDOWEIGHT#1% Willi's approach
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}020\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}030\arrangedpageA %  2
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  4
   \or \handlearrangedpageXandY{#1}020\arrangedpageB %  5
   \or \handlearrangedpageXandY{#1}030\arrangedpageB %  6
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  7
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  8
       \poparrangedpages
   \fi}

%D Imposition as requested by Jan Pohanka 26-08-2010, 4 pages, two verso, two recto,
%D uneven pages upright and down, even pages top and rotated 180.
%D Implementation with 2 pages for conference-name-display
%D Coding: [1*2-Conference]

\installpagearrangement 1*2-Conference
   {\dosetuparrangement{1}{2}{4}{3}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageCONFERENCETWO\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageCONFERENCETWO#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}001\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  2
       \poparrangedpages
   \fi}

%D Implementation with 4 pages for conference-name-display
%D Coding: [1*4-Conference]

\installpagearrangement 1*4-Conference
   {\dosetuparrangement{1}{2}{4}{3}{2}% X,Y,Total,hcutmarks,vcutmarks
        \pusharrangedpageCONFERENCEFOUR\poparrangedpagesAB\relax}

\permanent\protected\def\pusharrangedpageCONFERENCEFOUR#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}001\arrangedpageA %  1  rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}100\arrangedpageA %  2
   \or \handlearrangedpageXandY{#1}011\arrangedpageB %  3
   \or \handlearrangedpageXandY{#1}110\arrangedpageB %  4
       \poparrangedpages
   \fi}

%D There should be arrangements for sections made of heavy and thick paper. i.e. the heavier the paper
%D the fewer pages per section:
%D Section with 8 pages put on two sheets of paper. Each sheet carries recto 2 and verso 2 pages.
%D Coding: [2*2*2]

\installpagearrangement 2*2*2
  {\dosetuparrangement{2}{1}{2}{3}{2}% X,Y,Total,hcutmarks,vcutmarks
     \pusharrangedpageEIGHTTWO\poparrangedpagesAtoD\relax}

\permanent\protected\def\pusharrangedpageEIGHTTWO#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  1 rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageC %  3
   \or \handlearrangedpageXandY{#1}000\arrangedpageD %  4
   \or \handlearrangedpageXandY{#1}010\arrangedpageD %  5
   \or \handlearrangedpageXandY{#1}000\arrangedpageC %  6
   \or \handlearrangedpageXandY{#1}010\arrangedpageB %  7
   \or \handlearrangedpageXandY{#1}000\arrangedpageA %  8
       \poparrangedpages
   \fi}

%D Section with 12 pages, built from three sheets of paper.
%D Each sheet carries 2 pages recto and verso.
%D Coding: [2*2*3]

\permanent\protected\def\poparrangedpagesAtoF
  {\ifnum\arrangedpageN>\zerocount
     \paperwidth \arrangedpageX\paperwidth
     \paperheight\arrangedpageY\paperheight
     \outputarrangedbox\arrangedpageA
     \outputarrangedbox\arrangedpageB
     \outputarrangedbox\arrangedpageC
     \outputarrangedbox\arrangedpageD
     \outputarrangedbox\arrangedpageE
     \outputarrangedbox\arrangedpageF
     \global\arrangedpageN\zerocount
   \fi}

\installpagearrangement 2*2*3
  {\dosetuparrangement{2}{1}{2}{3}{2}% X,Y,Total,hcutmarks,vcutmarks
     \pusharrangedpageTWELVETWO\poparrangedpagesAtoF\relax}

\permanent\protected\def\pusharrangedpageTWELVETWO#1%
  {\advancearrangedpageN
   \reportarrangedpage\arrangedpageN
   \ifcase\arrangedpageN
   \or \handlearrangedpageXandY{#1}010\arrangedpageA %  1 rot,hskip,vskip
   \or \handlearrangedpageXandY{#1}000\arrangedpageB %  2
   \or \handlearrangedpageXandY{#1}010\arrangedpageC %  3
   \or \handlearrangedpageXandY{#1}000\arrangedpageD %  4
   \or \handlearrangedpageXandY{#1}010\arrangedpageE %  5
   \or \handlearrangedpageXandY{#1}000\arrangedpageF %  6
   \or \handlearrangedpageXandY{#1}010\arrangedpageF %  7
   \or \handlearrangedpageXandY{#1}000\arrangedpageE %  8
   \or \handlearrangedpageXandY{#1}010\arrangedpageD %  9
   \or \handlearrangedpageXandY{#1}000\arrangedpageC % 10
   \or \handlearrangedpageXandY{#1}010\arrangedpageB % 11
   \or \handlearrangedpageXandY{#1}000\arrangedpageA % 12
       \poparrangedpages
   \fi}

% % From Wolfgang for Mari (mail on list) ... yes or no in core .. time for
% % delayed loading ...
% %
% % http://stamphenge.wordpress.com/minibooks/meander-accordion-folded-book/
%
% \installpagearrangement MEANDER16
%   {\dosetuparrangement{4}{4}{16}{5}{5}%
%      \pusharrangedpageMEANDERSIXTEEN\poparrangedpagesXY\relax}
%
% \permanent\protected\def\pusharrangedpageMEANDERSIXTEEN#1%
%   {\advancearrangedpageN
%    \reportarrangedpage\arrangedpageN
%    \ifcase\arrangedpageN
%    \or \handlearrangedpageXandY{#1}000\arrangedpageA
%    \or \handlearrangedpageXandY{#1}010\arrangedpageA
%    \or \handlearrangedpageXandY{#1}020\arrangedpageA
%    \or \handlearrangedpageXandY{#1}030\arrangedpageA
%    \or \handlearrangedpageXandY{#1}131\arrangedpageA
%    \or \handlearrangedpageXandY{#1}121\arrangedpageA
%    \or \handlearrangedpageXandY{#1}111\arrangedpageA
%    \or \handlearrangedpageXandY{#1}101\arrangedpageA
%    \or \handlearrangedpageXandY{#1}002\arrangedpageA
%    \or \handlearrangedpageXandY{#1}012\arrangedpageA
%    \or \handlearrangedpageXandY{#1}022\arrangedpageA
%    \or \handlearrangedpageXandY{#1}032\arrangedpageA
%    \or \handlearrangedpageXandY{#1}133\arrangedpageA
%    \or \handlearrangedpageXandY{#1}123\arrangedpageA
%    \or \handlearrangedpageXandY{#1}113\arrangedpageA
%    \or \handlearrangedpageXandY{#1}103\arrangedpageA
%      \poparrangedpages
%    \fi}
%
% % \definepapersize[small][width=6cm,height=6cm]
% % \definepapersize[big][width=30cm,height=30cm]
% % \setuppapersize[small][big]
% % \setuppagenumbering[location=]
% % \setuparranging[MEANDER16]
% % \setuplayout
% %   [location=middle,
% %    marking=on]
% % \starttext
% % \dorecurse{32}{\centerbox{\ssd\recurselevel}}
% % \stoptext
%
% % By Willi:
%
% \installpagearrangement MEANDER9
%   {\dosetuparrangement{3}{3}{9}{4}{4}%
%      \pusharrangedpageMEANDERNINE\poparrangedpagesXY\relax}
%
% \permanent\protected\def\pusharrangedpageMEANDERNINE#1%
%   {\advancearrangedpageN
%    \reportarrangedpage\arrangedpageN
%    \ifcase\arrangedpageN
%    \or \handlearrangedpageXandY{#1}000\arrangedpageA
%    \or \handlearrangedpageXandY{#1}010\arrangedpageA
%    \or \handlearrangedpageXandY{#1}020\arrangedpageA
%    \or \handlearrangedpageXandY{#1}121\arrangedpageA
%    \or \handlearrangedpageXandY{#1}111\arrangedpageA
%    \or \handlearrangedpageXandY{#1}101\arrangedpageA
%    \or \handlearrangedpageXandY{#1}002\arrangedpageA
%    \or \handlearrangedpageXandY{#1}012\arrangedpageA
%    \or \handlearrangedpageXandY{#1}022\arrangedpageA
%    \poparrangedpages
%    \fi}

% % handy for stickers etc, this way we can treat them as page
%
% \setuppapersize [XY][A4]
% \setuppaper     [topspace=5mm,backspace=5mm,dx=1mm,dy=1mm,nx=2,ny=6]
% \setuplayout    [page] [topspace=5mm,backspace=5mm]
% \setuplayout    [page]
% \setuplayout    [location=middle]
% \setuparranging [XY]
% \showframe
%
% \starttext \dorecurse{30}{test \recurselevel \page} \stoptext

\permanent\protected\def\pusharrangedpageXY#1%
  {\advancearrangedpageN
   \global\advanceby\arrangedpageM\plusone
   \reportarrangedpage\arrangedpageN
   \global\setbox\arrangedpageB\hpack \ifdim\v_page_target_width>\zeropoint to \v_page_target_width \fi
      {\ifvoid\arrangedpageB\else
         \unhbox\arrangedpageB
         \ifdim\v_page_target_dx>\zeropoint
           \hkern\v_page_target_dx
         \else
           \hss
           \hkern\v_page_target_dx
           \hss
         \fi
       \fi
       \box#1}%
    \ifnum\arrangedpageM<\arrangedpageX\else
      \global\setbox\arrangedpageA\vpack \ifdim\v_page_target_height>\zeropoint to \v_page_target_height \fi
        {\offinterlineskip
         \ifvoid\arrangedpageA\else
           \unvbox\arrangedpageA
           \ifdim\v_page_target_dy>\zeropoint
             \vskip\v_page_target_dy
           \else
             \vss
             \vskip\v_page_target_dy
             \vss
           \fi
         \fi
         \box\arrangedpageB}%
      \global\arrangedpageM\zerocount
    \fi
    \ifnum\arrangedpageN<\arrangedpageT\else
      \poparrangedpages
    \fi}

\permanent\protected\def\poparrangedpagesXY
  {\ifnum\arrangedpageN>\zerocount
     \paperwidth \arrangedpageX\paperwidth
     \paperheight\arrangedpageY\paperheight
     \outputarrangedbox\arrangedpageA
     \global\arrangedpageN\zerocount
     \global\arrangedpageM\zerocount
   \fi}

\installpagearrangement XY
  {\dosetuparrangement
     \v_page_target_nx
     \v_page_target_ny
     \v_page_target_xy
     \zerocount
     \zerocount
     \pusharrangedpageXY\poparrangedpagesXY\relax}

%D A crazy definition, don't guess who pushed me for the landscape option.

\def\page_imposition_xy_height
  {\dimexpr
     \dimexpr
       \v_page_target_height
      -\numexpr\v_page_target_ny-1\relax\v_page_target_dy
     \relax
    /\v_page_target_ny
   \relax}

\def\page_imposition_xy_width
  {\dimexpr
     \dimexpr
       \v_page_target_width
      -\numexpr\v_page_target_nx-1\relax\v_page_target_dx
     \relax
    /\v_page_target_nx
   \relax}

\definepapersize
  [XY]
  [\c!height=\page_imposition_xy_height,
   \c!width =\page_imposition_xy_width]

\setuppaper
  [\c!width =\dimexpr\printpaperwidth -2\v_page_target_backspace\relax,
   \c!height=\dimexpr\printpaperheight-2\v_page_target_topspace \relax]

% \definepageshift[test][horizontal][10pt,20pt,30pt,40pt,50pt]
% \definepageshift[test][vertical]  [10pt,20pt,30pt,40pt,50pt]
%
% \setuppageshift[test]
% \setuppageshift[test][test]
% \setuppageshift[test][none]
% \setuppageshift[none][test]
% \setuppageshift[paper][test][test] % arrange only
% \setuppageshift[paper][test]       % arrange only
% \setuppageshift[print][test][test]
%
% \showframe \dorecurse{100}{\input tufte \par}

% #1=name #2=horizontal|vertical #3=shiftlist

% this will move to lua

\installcorenamespace {pageshift}

\permanent\protected\tolerant\def\definepageshift[#1]#*[#2]#*[#3]%
  {\defcsname\??pageshift#2:#1\endcsname{#3}}

\lettonothing\page_boxes_h_shifts
\lettonothing\page_boxes_v_shifts

\newinteger  \c_page_boxes_h_shifts
\newinteger  \c_page_boxes_v_shifts
\newdimension\d_page_boxes_h_shifts
\newdimension\d_page_boxes_v_shifts

\let\page_boxes_apply_shift_print\gobbleoneargument
\let\page_boxes_apply_shift_paper\gobbleoneargument

\def\page_boxes_filter_shift#1#2#3% #1=\dimenx #2=\xpageshifts #3=\nofxpageshifts
  {#1\zeropoint
   \ifempty#2\else
     \global\advanceby#3\plusone
     \getfromcommacommand[#2][#3]%
     \ifempty\commalistelement
       \global#3\plusone % we cycle
       \getfromcommacommand[#2][#3]%
     \fi
     \ifempty\commalistelement \else
       #1\commalistelement\relax % the relax is really needed as there is an \if later on
     \fi
   \fi}

\def\page_boxes_apply_shift#1%
  {\page_boxes_filter_shift\d_page_boxes_h_shifts\page_boxes_h_shifts\c_page_boxes_h_shifts
   \page_boxes_filter_shift\d_page_boxes_v_shifts\page_boxes_v_shifts\c_page_boxes_v_shifts
   \ifzeropt\d_page_boxes_h_shifts
     \ifzeropt\d_page_boxes_v_shifts
       % nothing to shift
     \else
       \page_boxes_apply_shift_indeed#1%
     \fi
   \else
     \page_boxes_apply_shift_indeed#1%
   \fi}

\def\page_boxes_apply_shift_indeed#1%
  {\edef\next{\wd#1\the\wd#1\ht#1\the\ht#1\dp#1\the\dp#1}%
   \setbox#1\vpack
     {\offinterlineskip
      \vskip\d_page_boxes_v_shifts
      \hkern\d_page_boxes_h_shifts
      \box#1}%
   \next}

\permanent\tolerant\protected\def\setuppageshift[#1]#*[#2]#*[#3]% page|paper horizontal vertical
  {\ifarguments\or
     \setuppageshift[\v!page][#1][#1]%
   \or
     \ifcommon{#1}{\v!page,\v!paper}%
       \setuppageshift[#1][#2][#2]%
     \else
       \setuppageshift[\v!page][#1][#2]%
     \fi
   \or
     %edef\page_boxes_h_shifts{\ifcsname\??pageshift\v!horizontal:#2\endcsname\csname\??pageshift\v!horizontal:#2\endcsname\fi}%
     %edef\page_boxes_v_shifts{\ifcsname\??pageshift\v!vertical  :#3\endcsname\csname\??pageshift\v!vertical  :#3\endcsname\fi}%
     \edef\page_boxes_h_shifts{\begincsname\??pageshift\v!horizontal:#2\endcsname}%
     \edef\page_boxes_v_shifts{\begincsname\??pageshift\v!vertical  :#3\endcsname}%
     \ifcstok{#1}\v!page \let\page_boxes_apply_shift_print\page_boxes_apply_shift\else\let\page_boxes_apply_shift_print\gobbleoneargument\fi
     \ifcstok{#1}\v!paper\let\page_boxes_apply_shift_paper\page_boxes_apply_shift\else\let\page_boxes_apply_shift_paper\gobbleoneargument\fi
   \fi}

\protect \endinput

