%D \module
%D   [       file=typo-col,
%D        version=2024.11.02,
%D          title=\CONTEXT\ Typesetting Macros,
%D       subtitle=Column Swapping,
%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.


\writestatus{loading}{ConTeXt Spacing Macros / Column Swapping}

\registerctxluafile{typo-swp}{autosuffix}

\unprotect

\installcorenamespace {rows}

\installcommandhandler \??rows {rows} \??rows

\definesystemattribute[swapping][global,public]

\setuprows
  [\c!n=2,%
  %\c!alternative=\v!tight,  % empty | tight
  %\c!height=\zeropoint,     % empty | fit | dimension | zeropoint
  %\c!depth=\zeropoint,      % empty | fit | dimension | zeropoint
  %\c!width=,                % empty | fit | dimension
   \c!before=,
   \c!after=,
   \c!order=\v!vertical,
   \c!distance=2\emwidth]    % kicks in when order when tight

\newinteger\c_swapping_index

\appendtoks
    \ifcstok{\rowsparameter\c!define}\v!yes
      \protected\frozen\instance\edefcsname\e!start\currentrows\endcsname{\startrows[\currentrows]}%
      \protected\frozen\instance\defcsname \e!stop \currentrows\endcsname{\stoprows}%
    \fi
\to \everydefinerows

\permanent\tolerant\protected\def\startrows[#1]#*[#2]%
  {\begingroup
   \clf_enableswapping
   \ifhastok={#1}%
     \setupcurrentrows[#1]%
   \orelse\ifparameter#1\or
     \cdef\currentrows{#1}%
     \ifparameter#2\or
       \setupcurrentrows[#2]%
     \fi
   \fi
   \scratchcountertwo{\rowsparameter\c!n}%
   \scratchdistance{\rowsparameter\c!distance}%
   \setbox\scratchboxone\vbox\bgroup
     \holdingmigrations\maxcount % nota bene, maybe we shuld registering how many inserts are holded
     \ifempty{\rowsparameter\c!width}%
       % nothing
     \orelse\ifcstok{\lastnamedcs}\v!fit
       \hsize\distributedhsize\hsize\scratchdistance\scratchcountertwo
       \usealignparameter\rowsparameter
     \orelse\ifchkdimexpr\lastnamedcs\or
       \hsize{\lastchkdimension}%
       \usealignparameter\rowsparameter
     \fi}

\permanent\protected\def\stoprows
  {\egroup
   \ifvoid\scratchboxone\else
     \rowsparameter\c!before
     \forgetall
     \scratchwidth{%
       \ifcstok{\rowsparameter\c!alternative}\v!tight
         \zeropoint
       \orelse\ifcstok{\rowsparameter\c!width}\v!fit
         \zeropoint
       \else
         \hsize/\scratchcountertwo
       \fi
     }%
     \scratchcounterone{%
       \ifcstok{\rowsparameter\c!order}\v!vertical
          \c_swapping_index * "10000
        + \scratchcountertwo
       \else
         \attributeunsetvalue
       \fi
     }%
     \global\advance\c_swapping_index\plusone
     \ifempty{\rowsparameter\c!height}%
       \scratchheight\zeropoint
     \orelse\ifcstok{\lastnamedcs}\v!max
       \scratchheight\boxlinemaxht\scratchboxone\relax
       \ifdim\scratchheight<\strutht
          \scratchheight\zeropoint
       \fi
     \orelse\ifchkdimexpr\lastnamedcs\or
       \scratchheight\lastchkdimension
     \else
       \scratchheight\zeropoint
     \fi
     \ifempty{\rowsparameter\c!depth}%
       \scratchheight\zeropoint
     \orelse\ifcstok{\lastnamedcs}\v!max % \iflastnamedcs
       \scratchdepth\boxlinemaxdp\scratchboxone\relax
       \ifdim\scratchdepth<\strutdp
          \scratchdepth\zeropoint
       \fi
     \orelse\ifchkdimexpr\lastnamedcs\or
       \scratchdepth\lastchkdimension
     \else
       \scratchdepth\zeropoint
     \fi
     \dorecurse {\boxlines \scratchboxone} {%
       \ifzero\scratchheight\else
         \boxlineht\scratchboxone ##1 \scratchheight
       \fi
       \ifzero\scratchdepth\else
         \boxlinedp\scratchboxone ##1 \scratchdepth
       \fi
       \ifnum##1=\plusone
         \dontleavehmode
         \hbox \bgroup
         \global\globalscratchcounterone\plustwo
       \orelse\ifnum\globalscratchcounterone>\scratchcountertwo
         \boundary\zerocount
         \egroup\par
         \dontleavehmode
         \hbox \bgroup
         \global\globalscratchcounterone\plustwo
       \else
         \global\advance\globalscratchcounterone\plusone
       \fi
       \ifzero\scratchwidth
         \ifnum\globalscratchcounterone>\plustwo
           \hskip\scratchdistance
         \fi
         % no need for box when not sorting
         \setbox\scratchbox\boxline \scratchboxone ##1\relax
         \boxmigrate\scratchbox\maxcount % nota bene
         \ifnum\scratchcounterone=\attributeunsetvalue
           \box\scratchbox
         \else
           \boxattribute \scratchbox \swappingattribute \scratchcounterone
           \boundary\zerocount
           \box\scratchbox
           \boundary\zerocount
        \fi
       \else
         % todo: use the box line helpers
         \setbox\scratchbox\hpack \s!to \scratchwidth \bgroup
           \boxline \scratchboxone ##1\relax
           \hss
         \egroup
         \boxmigrate\scratchbox\maxcount % nota bene
         \ifnum\scratchcounterone=\attributeunsetvalue
           \box\scratchbox
         \else
           \boxattribute \scratchbox \swappingattribute \scratchcounterone
           \boundary\zerocount
           \box\scratchbox
           \boundary\zerocount
         \fi
       \fi
     }%
     \ifnum\globalscratchcounterone>\plusone
       \ifnum\scratchcounterone=\attributeunsetvalue
          % nothing to do here
       \else
         % todo: use loop
         \dostepwiserecurse {\globalscratchcounterone} \scratchcountertwo {\plusone} {%
           \ifzero\scratchwidth
             \hskip{\rowsparameter\c!distance}%
           \fi
           \hpack \s!attr \swappingattribute \scratchcounterone \bgroup
             \null
           \egroup
           \boundary\zerocount}%
       \fi
       \hss
       \egroup\par
     \fi
     \rowsparameter\c!after
   \fi
   \endgroup}

\protect
