%D \module
%D   [       file=page-sel, % moved from page-imp
%D        version=1998.01.15,
%D          title=\CONTEXT\ Page Macros,
%D       subtitle=Page Selection,
%D         author=Hans Hagen,
%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.

%D This code relates to old texexec features and one can wonder if it needs
%D to be in the core. So, this could become runtime loaded code. Some of
%D the alternatives need checking.

%D Todo: update to use luametatex features.

\writestatus{loading}{ConTeXt Page Macros / Page Selection}

\unprotect

\registerctxluafile{page-sel}{autosuffix}

\startcontextdefinitioncode

%D One can (mis)use this mechanism to (re)arrange pages of already produced files.
%D
%D \starttyping
%D \insertpages[file.pdf][1,3][n=30,width=18cm]
%D \stoptyping
%D
%D The pages are inserted in the text area, and even pages are repositioned
%D according to the width. In this example empty pages are added after page 1 and 3.
%D
%D Selecting pages can be accomplished by:
%D
%D \starttyping
%D \filterpages[file.pdf][1,3,5][n=30,width=18cm]
%D \stoptyping
%D
%D One may pass \type {odd} or \type {even} instead of a comma separated list. A
%D third alternative is:
%D
%D \starttyping
%D \copypages[file.pdf][n=30,scale=950]
%D \stoptyping
%D
%D This macros inserts the page, according to the settings provided.

%D Beware: width is not the width of the image, but height can be used to control
%D its dimensions.

\installcorenamespace{withpages}

\installsetuponlycommandhandler \??withpages {withpages}
%  \installdirectcommandhandler \??withpages {withpages}

\newinteger\c_page_selectors_n

\permanent\tolerant\protected\def\insertpages[#filename]#spacer[#emptylist]#spacer[#S#settings]%
  {\doifelseassignment{#emptylist}%
     {\page_selectors_insert_indeed[#filename][][#emptylist]}%
     {\page_selectors_insert_indeed[#filename][#emptylist][#settings]}}

\def\page_selectors_insert_indeed[#filename][#emptylist][#S#settings]%
  {\bgroup
   \dontcomplain
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!width=\zeropoint,
      \c!n=\noffigurepages,
      \c!category=,
      \c!alternative=\v!a,
      #settings]%
   \global\c_page_selectors_n{\directwithpagesparameter\c!n}%
   \scratchwidth{\directwithpagesparameter\c!width}%
   \ifinset{0}{#emptylist}%
     \emptyhbox
     \page
   \fi
   \dorecurse\c_page_selectors_n
     {\page_selectors_filter_alternative{#filename}{##1}
      \ifinset{\recurselevel}{#emptylist}%
        \emptyhbox
        \page
      \fi}%
   \egroup}

\let\page_selectors_filter_step_indeed\gobbleoneargument
\let\page_selectors_filter_step       \gobbleoneargument

\installcorenamespace{filterpagesalternative}

\protected\def\page_selectors_filter_alternative
  {\expandnamespaceparameter
     \??filterpagesalternative
     \directwithpagesparameter\c!alternative
     \v!a}

\permanent\tolerant\protected\def\filterpages[#filename]#spacer[#selection]#spacer[#S#settings]%
  {\doifelseassignment{#selection}%
     {\page_selectors_filter_indeed[#filename][][#selection]}%
     {\page_selectors_filter_indeed[#filename][#selection][#settings]}}

\def\page_selectors_filter_indeed[#filename][#selection][#S#settings]% % \noffigurepages not yet supported
  {\bgroup
   \dontcomplain
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!width=\zeropoint,
      \c!n=\noffigurepages,
      \c!category=,
      \c!alternative=\v!a,
      #settings]%
   \global\c_page_selectors_n{\directwithpagesparameter\c!n}%
   \scratchwidth{\directwithpagesparameter\c!width}%
   \edef\p_selection{#selection}%
   \ifempty\p_selection
     \let\p_selection\v!all
   \fi
   \ifx\p_selection\v!all
     \dorecurse\c_page_selectors_n
       {\page_selectors_filter_alternative{#filename}{##1}}%
   \orelse\ifx\p_selection\v!even
     \dorecurse\c_page_selectors_n
       {\ifodd##1\else
          \page_selectors_filter_alternative{#filename}{##1}%
        \fi}%
   \orelse\ifx\p_selection\v!odd
     \dorecurse\c_page_selectors_n
       {\ifodd##1\relax
          \page_selectors_filter_alternative{#filename}{##1}%
        \fi}%
   \else
     \def\page_selectors_filter_step_indeed#page%
       {\ifnum#page>\c_page_selectors_n\else
          \page_selectors_filter_alternative{#filename}{#page}%
        \fi}%
     % todo: use the context lua slicer
     \def\page_selectors_filter_step#step%
       {\dowithminmaxrangeslice
          {1}{\noffigurepages}% where we take from
          {1}{\noffigurepages}% what we want
          {#step}%              the set
          \page_selectors_filter_step_indeed}%
     \processcommacommand[\p_selection]\page_selectors_filter_step
   \fi
   \egroup}

\defcsname\??filterpagesalternative\v!a\endcsname#filename#page%
  {\hpack to \textwidth
     {\ifdim\scratchwidth>\zeropoint
        \rightorleftpageaction{\scratchwidth\zeropoint}{\hfill}%
      \fi
      \setbox\scratchbox\hpack
        {\hskip-\scratchwidth
         \edef\p_category{\directwithpagesparameter\c!category}% \useexternalfigure[foo][width=\textwidth]
         \ifx\p_category\empty
           \externalfigure[#filename][\c!page=#page,\c!height=\textheight]%
         \else
           \externalfigure[#filename][\p_category][\c!page=#page]%
         \fi
         \hss}%
      \wd\scratchbox\zeropoint
      \box\scratchbox}%
   \page}

\defcsname\??filterpagesalternative\v!b\endcsname#filename#page%
  {\startTEXpage
     \scratchcounter#page\relax
     \ifnum\scratchcounter<\zerocount
        \getfiguredimensions[#filename]%
        \scratchcounter{\noffigurepages-\scratchcounter+\plusone}%
     \fi
     \expanded{\externalfigure[#filename][\c!page=\the\scratchcounter]}%
   \stopTEXpage}

\letcsname\??filterpagesalternative\v!default\expandafter\endcsname\csname\??filterpagesalternative\v!a\endcsname
\letcsname\??filterpagesalternative\v!page   \expandafter\endcsname\csname\??filterpagesalternative\v!b\endcsname

\permanent\tolerant\protected\def\copypages[#filename]#spacer[#S#settings]#spacer[#S#figuresettings]%
  {\bgroup
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!marking=\v!off,
      \c!offset=\zeropoint,
      \c!n=\noffigurepages,
      \c!category=,
      #settings]%
   \global\c_page_selectors_n{\directwithpagesparameter\c!n}%
   \scratchoffset{\directwithpagesparameter\c!offset}%
   \dorecurse\c_page_selectors_n
     {\vbox to \textheight
        {\hsize\textwidth
         \centeredbox
           {\ifcstok{\directwithpagesparameter\c!marking}\v!on
              \expandafter\cuthbox
            \else
              \expandafter\hpack % only place where cuthbox is used
            \fi
              {\ifdim\scratchoffset>\zeropoint\relax
                 \advanceby\vsize -2\scratchoffset
                 \advanceby\hsize -2\scratchoffset
                 \externalfigure[#filename][\c!page=##1,#figuresettings,\c!scale=,\c!factor=\v!max,\c!offset=\v!overlay]%
               \else
                 \externalfigure[#filename][\c!page=##1,#figuresettings,\c!offset=\v!overlay]%
               \fi}}}%
      \page}%
   \egroup}

%D \macros
%D   {combinepages}
%D
%D Yet another way of postprocessing is handles by \type {\combinepages}. This macro
%D builds a matrix of pages from a file, for example:
%D
%D \starttyping
%D \setuppapersize
%D   [A4][A4] % or [A4,landscape][A4,landscape]
%D
%D \setuplayout
%D   [header=0pt,footer=1cm,
%D    backspace=1cm,topspace=1cm,
%D    width=middle,height=middle]
%D
%D \setupfootertexts
%D   [presentation---\currentdate\space---\space\pagenumber]
%D
%D \starttext
%D   \combinepages[slides][nx=2,ny=3,frame=on]
%D \stoptext
%D \stoptyping
%D
%D One can influence the way the pages are combined. (This will be explained some
%D time.)

\installcorenamespace{combinepagesalternative}

\permanent\tolerant\protected\def\combinepages[#filename]#spacer[#S#settings]% a=perpag b=free
  {\bgroup
   \dontcomplain
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!alternative=\v!a,
      \c!n=\noffigurepages,\c!nx=\plustwo,\c!ny=\plustwo,
      \c!start=\plusone,\c!stop=\maxcard,
      \c!distance=\bodyfontsize,
      \c!bottom=\vfill,\c!top=\vss,\c!left=\hss,\c!right=\hss,
      \c!before=\page,\c!after=\page,\c!inbetween=\blank,
      \c!frame=,\c!background=,\c!backgroundcolor=,
      \c!name={#filename},
      \c!category=,
      #settings]%
   \global\c_page_selectors_n\directwithpagesparameter\c!n\relax
   \directwithpagesparameter\c!before
   \scratchnx{\directwithpagesparameter\c!nx}%
   \scratchny{\directwithpagesparameter\c!ny}%
   \scratchdistance{\directwithpagesparameter\c!distance}%
   \scratchwidth{(\textwidth-\scratchnx\scratchdistance+\scratchdistance)/\scratchnx}%
   \scratchheight{(\textheight-\scratchny\scratchdistance+\scratchdistance)/\scratchny}%
   \expandnamespaceparameter\??combinepagesalternative\directwithpagesparameter\c!alternative\v!b
   \directwithpagesparameter\c!after
   \egroup}

\defcsname\??combinepagesalternative\v!a\endcsname % use hpacks
  {\global\combinedpagescounter\directwithpagesparameter\c!start\relax
   \doloop
     {\vbox to \textheight
        {\dorecurse\scratchny
           {\hbox to \textwidth
              {\dorecurse\scratchnx
                 {\vbox to \scratchheight
                    {\hsize\scratchwidth
                     \vsize\scratchheight
                     \directwithpagesparameter\c!top
                     \hbox to \hsize
                       {\directwithpagesparameter\c!left
                        \ifnum\combinedpagescounter>\directwithpagesparameter\c!stop\relax
                          \global\c_page_selectors_n\zerocount
                        \orelse\ifnum\combinedpagescounter>\c_page_selectors_n \else
                          \externalfigure
                            [\directwithpagesparameter\c!name]
                            [\c!object=\v!no,
                             \c!page=\number\combinedpagescounter,
                             \c!factor=\v!max,
                             \c!background=\directwithpagesparameter\c!background,
                             \c!backgroundcolor=\directwithpagesparameter\c!backgroundcolor,
                             \c!frame=\directwithpagesparameter\c!frame]%
                        \fi
                        \directwithpagesparameter\c!right}%
                     \directwithpagesparameter\c!bottom}%
                  \global\advanceby\combinedpagescounter\plusone
                  \hfil}%
               \hfilneg}
            \vfil}%
         \vfilneg}%
         \page
         \ifnum\combinedpagescounter>\c_page_selectors_n
           \exitloop
         \fi}}

\defcsname\??combinepagesalternative\v!c\endcsname
  {\global\combinedpagescounter\directwithpagesparameter\c!start\relax
   \doloop
     {\vbox to \textheight
        {\hbox to \textwidth
           {\dorecurse\scratchnx
              {\directwithpagesparameter\c!left
               \vbox to \textheight
                 {\hsize\scratchwidth
                  \dorecurse\scratchny
                    {\directwithpagesparameter\c!top
                     \hbox to \hsize
                       {\vbox to \scratchheight
                          {\hsize\scratchwidth
                           \vsize\scratchheight
                           \ifnum\combinedpagescounter>\directwithpagesparameter\c!stop\relax
                             \global\c_page_selectors_n\zerocount
                           \orunless\ifnum\combinedpagescounter>\c_page_selectors_n
                             \externalfigure
                               [\directwithpagesparameter\c!name]
                               [\c!object=\v!no,
                                \c!page=\number\combinedpagescounter,
                                \c!factor=\v!max,
                                \c!background=\directwithpagesparameter\c!background,
                                \c!backgroundcolor=\directwithpagesparameter\c!backgroundcolor,
                                \c!frame=\directwithpagesparameter\c!frame]%
                           \fi}}
                      \global\advanceby\combinedpagescounter\plusone
                      \directwithpagesparameter\c!bottom}}%
                \hfil}%
            \hfilneg}}%
      \page
      \ifnum\combinedpagescounter>\c_page_selectors_n
        \exitloop
      \fi}}

\letcsname\??combinepagesalternative\v!horizontal\expandafter\endcsname\csname\??combinepagesalternative\v!a\endcsname
\letcsname\??combinepagesalternative\v!vertical  \expandafter\endcsname\csname\??combinepagesalternative\v!c\endcsname

\defcsname\??combinepagesalternative\v!b\endcsname
  {\global\combinedpagescounter\directwithpagesparameter\c!start\relax
   \doloop
     {\startbaselinecorrection
        \hbox to \textwidth
          {\dorecurse\scratchnx
             {\global\advanceby\combinedpagescounter\plusone
              \ifnum\combinedpagescounter>\c_page_selectors_n \else
                 \expanded{\externalfigure
                   [\directwithpagesparameter\c!name]
                   [\c!page=\number\combinedpagescounter,
                    \c!width=\the\scratchwidth,
                    \c!background=\directwithpagesparameter\c!background,
                    \c!backgroundcolor=\directwithpagesparameter\c!backgroundcolor,
                    \c!frame=\directwithpagesparameter\c!frame]}%
                 \hfill
              \fi}%
              \hfillneg}%
      \stopbaselinecorrection
      \ifnum\combinedpagescounter<\c_page_selectors_n\relax
        \directwithpagesparameter\c!inbetween
      \else
        \exitloop
      \fi}}

% This macro cuts a page into n parts that can be pasted together.

\permanent\tolerant\protected\def\slicepages[#filename]#spacer[#S#oddsettings]#spacer[#S#evensettings]%
  {\ifparameter#evensettings\or
     \page_selectors_slice_indeed[#filename][#oddsettings][#evensettings]%
   \else
     \page_selectors_slice_indeed[#filename][#oddsettings][#oddsettings]%
   \fi}

\mutable\let\slicedpagenumber\!!zerocount
\mutable\let\slicedpagestepx \!!zerocount
\mutable\let\slicedpagestepy \!!zerocount

\def\page_selectors_slice_indeed[#filename][#S#oddsettings][#S#evensettings]%
  {\bgroup
   \dontcomplain
   \glet\slicedpagenumber\!!zerocount
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!offset=\zeropoint,
      \c!hoffset=\zeropoint,
      \c!voffset=\zeropoint,
      \c!width=\figurewidth,
      \c!height=\figureheight,
      \c!n=\noffigurepages,
      \c!category=,
      #oddsettings]%
   \global\c_page_selectors_n\directwithpagesparameter\c!n\relax
   \ifnum\c_page_selectors_n>\zerocount
     \definepapersize
       [\s!dummy]
       [\c!height=\directwithpagesparameter\c!height,
        \c!width=\directwithpagesparameter\c!width]%
     \setuppapersize
       [\s!dummy]
       [\s!dummy]%
     \setuplayout
       [\c!backspace=\zeropoint,\c!topspace=\zeropoint,
        \c!height=\v!middle,\c!width=\v!middle,
        \c!textdistance=\zeropoint,
        \c!header=\zeropoint,\c!footer=\zeropoint]%
   \fi
   \dorecurse\noffigurepages
     {\glet\slicedpagenumber\recurselevel
      \ifnum\c_page_selectors_n>\plusone
        \dorecurse\c_page_selectors_n
          {\let\slicedpagestepx\recurselevel
           \dorecurse\c_page_selectors_n
             {\let\slicedpagestepy\recurselevel
              \clip
                [\c!nx=\c_page_selectors_n,\c!ny=\c_page_selectors_n,\c!x=\slicedpagestepx,\c!y=\slicedpagestepy]%
                {\scale
                   [\c!scale=\the\c_page_selectors_n000]%
                   {\externalfigure[#filename][\c!page=\slicedpagenumber]}}%
              \page}}%
      \else
        \ifodd\slicedpagenumber\relax
          \setupcurrentwithpages[#oddsettings]%
        \else
          \setupcurrentwithpages[#evensettings]%
        \fi
        \hskip{\directwithpagesparameter\c!offset}%
        \clip
          [\c!hoffset=\directwithpagesparameter\c!hoffset,%
           \c!voffset=\directwithpagesparameter\c!voffset,
           \c!height=\directwithpagesparameter\c!height,%
           \c!width=\directwithpagesparameter\c!width]
          {\externalfigure[#filename][\c!page=\slicedpagenumber]}%
        \page
      \fi}
   \egroup}

% \starttext \slicepages[slice1.pdf][n=3] \stoptext

\permanent\protected\def\trimpages[#S#1]% was for a over decade in p-pdf-51.tex
  {\begingroup
   \getdummyparameters
     [\c!file=dummy,%
      \c!hoffset=\zeropoint,
      \c!voffset=\zeropoint,
      \c!width=17cm,
      \c!height=24cm,
      \c!x=\zeropoint,
      \c!y=\zeropoint,
      #1]%
   \getfiguredimensions
     [\dummyparameter\c!file]
     [\c!object=\v!no]%
   \dorecurse\noffigurepages
     {\scale
        [\c!width=\paperwidth,
         \c!height=\paperheight]%
        {\offset
           [\c!x=\dummyparameter\c!x,
            \c!y=\dummyparameter\c!y]
           {\clip
              [\c!hoffset=\dummyparameter\c!hoffset,
               \c!voffset=\dummyparameter\c!voffset,
               \c!width=\dummyparameter\c!width,
               \c!height=\dummyparameter\c!height]
              {% we correct by default, if not needed, introduce option
               \setbox\nextbox\hbox
                 {\externalfigure[\dummyparameter\c!file][\c!page=##1]}%
               \ifdim\wd\nextbox>\ht\nextbox
                 \rotate[\c!rotation=90]{\box\nextbox}%
               \else
                 \box\nextbox
               \fi}}}}%
   \endgroup}

\stopcontextdefinitioncode

%D Implemented in Lua:

% crap.tex:
%
% \starttext
%     \dorecurse{10}{
%         \startchapter[title=Chapter #1,reference=chapter:#1]
%             \dorecurse{10}{
%                 \startsubject[title=Subject #1]
%                     \dorecurse{2}{\samplefile{tufte}\par}
%                 \stopsubject
%                 \startsection[title=Section #1.##1,reference=#1.##1]
%                     \dorecurse{10}{\samplefile{tufte}\par}
%                 \stopsection
%             }
%         \stopchapter
%     }
% \stoptext
%
% load.tex:
%
% \starttext
%     \dostepwiserecurse {\firstsectionpage[crap][chapter:3]} {\lastsectionpage[crap][chapter:3]} {1} {
%         \startpagemakeup
%             \externalfigure[crap.pdf][page=#1]
%         \stoppagemakeup
%     }
%     \dostepwiserecurse {\firstsectionpage[crap][chapter:5]} {\lastsectionpage[crap][chapter:5]} {1} {
%         \dontleavehmode
%         \externalfigure[crap.pdf][page=#1,width=3cm,frame=on]%
%         \space\allowbreak
%     }
% \stoptext

\protect \endinput
