page-sel.mkvi / last modification: 2020-01-30 14:16
%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.

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

\unprotect

%D One can (mis)use this mechanism to (re)arrange pages of already produced
%D 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
%D 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}

\newcount\c_page_selectors_n

\unexpanded\def\insertpages
  {\dotripleempty\page_selectors_insert}

\def\page_selectors_insert[#filename][#emptylist][#settings]%
  {\doifelseassignment{#emptylist}
     {\page_selectors_insert_indeed[#filename][][#emptylist]}
     {\page_selectors_insert_indeed[#filename][#emptylist][#settings]}}

\def\page_selectors_insert_indeed[#filename][#emptylist][#settings]%
  {\bgroup
   \dontcomplain
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!width=\zeropoint,%
      \c!n=\noffigurepages,%
      \c!category=,%
      #settings]%
   \global\c_page_selectors_n\directwithpagesparameter\c!n\relax
   \scratchwidth\directwithpagesparameter\c!width\relax
   \doifinset0{#emptylist}
     {\emptyhbox\page}%
   \dorecurse\c_page_selectors_n
     {\page_selectors_filter_a_page{#filename}\recurselevel
      \doifinset\recurselevel{#emptylist}
        {\emptyhbox\page}}%
   \egroup}

\unexpanded\def\filterpages
  {\dotripleempty\page_selectors_filter}

\def\page_selectors_filter[#filename][#selection][#settings]% % \noffigurepages not yet supported
  {\bgroup
   \dontcomplain
   \getfiguredimensions[#filename]%
   \setupcurrentwithpages
     [\c!width=\zeropoint,%
      \c!n=\noffigurepages,%
      \c!category=,%
      #settings]%
   \global\c_page_selectors_n\directwithpagesparameter\c!n\relax
   \scratchwidth\directwithpagesparameter\c!width\relax
   \edef\p_selection{#selection}%
   \ifx\p_selection\v!even
     \dorecurse\c_page_selectors_n
       {\ifodd\recurselevel\else
          \page_selectors_filter_a_page{#filename}\recurselevel
        \fi}%
   \else\ifx\p_selection\v!odd
     \dorecurse\c_page_selectors_n
       {\ifodd\recurselevel\relax
          \page_selectors_filter_a_page{#filename}\recurselevel
        \fi}%
   \else
     \def\page_selectors_filter_step_indeed#page%
       {\ifnum#page>\c_page_selectors_n\else
          \page_selectors_filter_a_page{#filename}{#page}%
        \fi}%
     \def\page_selectors_filter_step#step%
       {\dowithrange{#step}\page_selectors_filter_step_indeed}%
     \processcommacommand[\p_selection]\page_selectors_filter_step
   \fi\fi
   \egroup}

\def\page_selectors_filter_a_page#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}

\unexpanded\def\copypages
  {\dotripleempty\page_selectors_copy}

\def\page_selectors_copy[#filename][#settings][#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\relax
   \scratchoffset\directwithpagesparameter\c!offset\relax
   \dorecurse\c_page_selectors_n
     {\vbox to \textheight
        {\hsize\textwidth
         \centeredbox
           {\doifelse{\directwithpagesparameter\c!marking}\v!on\cuthbox\hpack % only place where cuthbox is used
              {\ifdim\scratchoffset>\zeropoint\relax
                 \advance\vsize -2\scratchoffset
                 \advance\hsize -2\scratchoffset
                 \externalfigure[#filename][\c!page=\recurselevel,#figuresettings,\c!scale=,\c!factor=\v!max,\c!offset=\v!overlay]%
               \else
                 \externalfigure[#filename][\c!page=\recurselevel,#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}

\unexpanded\def\combinepages
  {\dodoubleempty\page_selectors_combine}

\def\page_selectors_combine[#filename][#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\relax
   \scratchwidth\dimexpr(\textwidth-\scratchnx\scratchdistance+\scratchdistance)/\scratchnx\relax
   \scratchheight\dimexpr(\textheight-\scratchny\scratchdistance+\scratchdistance)/\scratchny\relax
   \expandnamespaceparameter\??combinepagesalternative\directwithpagesparameter\c!alternative\v!b
   \directwithpagesparameter\c!after
   \egroup}

\setvalue{\??combinepagesalternative\v!a}% 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
                        \else\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\fi
                        \directwithpagesparameter\c!right}
                     \directwithpagesparameter\c!bottom}%
                  \global\advance\combinedpagescounter\plusone
                  \hfil}%
               \hfilneg}
            \vfil}%
         \vfilneg}%
         \page
         \ifnum\combinedpagescounter>\c_page_selectors_n
           \exitloop
         \fi}}

\setvalue{\??combinepagesalternative\v!c}%
  {\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
                           \else\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\fi}}
                      \global\advance\combinedpagescounter\plusone
                      \directwithpagesparameter\c!bottom}}%
                \hfil}%
            \hfilneg}}%
      \page
      \ifnum\combinedpagescounter>\c_page_selectors_n
        \exitloop
      \fi}}

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

\setvalue{\??combinepagesalternative\v!b}%
  {\global\combinedpagescounter\directwithpagesparameter\c!start\relax
   \doloop
     {\startbaselinecorrection
        \hbox to \textwidth
          {\dorecurse\scratchnx
             {\global\advance\combinedpagescounter\plusone
              \ifnum\combinedpagescounter>\c_page_selectors_n \else
                 \normalexpanded{\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.

\unexpanded\def\slicepages
  {\dotripleempty\page_selectors_slice}

\def\page_selectors_slice[#filename][#oddsettings][#evensettings]%
  {\ifthirdargument
     \page_selectors_slice_indeed[#filename][#oddsettings][#evensettings]%
   \else
     \page_selectors_slice_indeed[#filename][#oddsettings][#oddsettings]%
   \fi}

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

\def\page_selectors_slice_indeed[#filename][#oddsettings][#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=\number\c_page_selectors_n000]
                   {\externalfigure[#filename][\c!page=\slicedpagenumber]}}%
              \page}}%
      \else
        \ifodd\slicedpagenumber\relax
          \setupcurrentwithpages[#oddsettings]%
        \else
          \setupcurrentwithpages[#evensettings]%
        \fi
        \hskip\directwithpagesparameter\c!offset\relax
        \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

\unexpanded\def\trimpages[#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}

\protect \endinput