%D \module
%D   [       file=page-sid,
%D        version=2000.10.20,
%D          title=\CONTEXT\ Page Macros,
%D       subtitle=Side Floats,
%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 Page Macros / Side Floats}

\unprotect

% These macro deal with side floats. We started with Daniel Comenetz macros as published
% in TUGBoat Volume 14 (1993), No.\ 1: Anchored Figures at Either Margin. I extended and
% patched the macros to suite our needs which results in a messy module. Therefore, this
% module badly needs an update because it's now a mixture of old and new macros.

% Interesting cases where it goes wrong:
%
% \placefigure[left]{}{} \dorecurse{3}{\input ward } {\par} \input ward
%
% Here we get an unwanted carried over hangindent and parindent. A solution is to associate
% it with the local par node instead. This is something to discuss with Taco as it could be
% a new luatex/mkiv feature: explicitly set par properties.

% Maybe I should just rewrite the lot.

\newdimen       \d_page_sides_height       % includes the topskip
\newdimen       \d_page_sides_width
\newdimen       \d_page_sides_hsize
\newdimen       \d_page_sides_vsize
\newdimen       \d_page_sides_vsize_reset  \d_page_sides_vsize_reset -\onepoint % could be a \let
\newdimen       \d_page_sides_progress
\newdimen       \d_page_sides_page_total
\newdimen       \d_page_sides_saved_depth

\newbox         \b_page_sides_bottom

\newcount       \c_page_sides_lines_done
\newcount       \c_page_sides_checks_done
\newcount       \c_page_sides_n_of_lines
\newcount       \c_page_sides_n_of_hang
\newconstant    \c_page_sides_float_type

\newconditional \c_page_sides_short        % needs checking .. best write this from scratch
\newconditional \c_page_sides_flag

\newconditional \c_page_sides_r_eq         % messy, needs checking anyway
\newconditional \c_page_sides_l_eq         % messy, needs checking anyway

\newdimen       \d_page_sides_shift
\newdimen       \d_page_sides_extrashift
\newdimen       \d_page_sides_leftshift
\newdimen       \d_page_sides_rightshift
\newdimen       \d_page_sides_leftskip
\newdimen       \d_page_sides_rightskip
\newdimen       \d_page_sides_maximum
\newdimen       \d_page_sides_topskip
\newdimen       \d_page_sides_bottomskip
\newdimen       \d_page_sides_downshift

\setnewconstant \c_page_sides_method \plusone   % 0=raw 1=safe (.99) 2=tight (-1pt)
\setnewconstant \c_page_sides_align  \zerocount

\def\page_sides_process_float_backspace  {\global\c_page_sides_float_type\plusone  \page_sides_handle_float}
\def\page_sides_process_float_leftedge   {\global\c_page_sides_float_type\plustwo  \page_sides_handle_float}
\def\page_sides_process_float_leftmargin {\global\c_page_sides_float_type\plusthree\page_sides_handle_float}
\def\page_sides_process_float_left       {\global\c_page_sides_float_type\plusfour \page_sides_handle_float}
\def\page_sides_process_float_right      {\global\c_page_sides_float_type\plusfive \page_sides_handle_float}
\def\page_sides_process_float_rightmargin{\global\c_page_sides_float_type\plussix  \page_sides_handle_float}
\def\page_sides_process_float_rightedge  {\global\c_page_sides_float_type\plusseven\page_sides_handle_float}
\def\page_sides_process_float_cutspace   {\global\c_page_sides_float_type\pluseight\page_sides_handle_float}
\def\page_sides_process_float_margin     {\global\c_page_sides_float_type\pluseight\page_sides_handle_float}

\let\logsidefloat\relax

\newif\iftracesidefloats % public (might change)

% end of public variables

\def\page_sides_insert_info
  {\page_floats_report_total}

\def\page_sides_apply_horizontal_shift
  {\ifdim\d_page_sides_maximum>\zeropoint
     \ifcase\c_page_sides_float_type
       % invalid
     \or
       % backspace
     \or
       \global\d_page_sides_shift\dimexpr
         -\d_page_sides_maximum
         -\rightorleftpageaction \leftedgedistance   \rightedgedistance
         -\rightorleftpageaction \leftmarginwidth    \rightmarginwidth
         -\rightorleftpageaction \leftmargindistance \rightmargindistance
         -\compensatedinnermakeupmargin
       \relax
     \or
       \global\d_page_sides_shift\dimexpr
         -\d_page_sides_maximum
         -\rightorleftpageaction \leftmargindistance \rightmargindistance
         -\compensatedinnermakeupmargin
       \relax
     \or
       % left
     \or
       % right
     \or
       \global\d_page_sides_shift\dimexpr
         -\d_page_sides_maximum
         -\rightorleftpageaction \leftmargindistance \rightmargindistance
         -\compensatedinnermakeupmargin
       \relax
     \or
       \global\d_page_sides_shift\dimexpr
         -\d_page_sides_maximum
         -\rightorleftpageaction \leftedgedistance   \rightedgedistance
         -\rightorleftpageaction \leftmarginwidth    \rightmarginwidth
         -\rightorleftpageaction \leftmargindistance \rightmargindistance
         -\compensatedinnermakeupmargin
       \relax
     \or
       % cutspace
     \fi
   \fi
   \ifdim\d_page_sides_shift=\zeropoint \relax
     \ifnum\c_page_sides_float_type=\plusfour
       \global\advance\d_page_sides_shift\d_page_sides_extrashift
       \global\d_page_sides_extrashift\zeropoint
     \else\ifnum\c_page_sides_float_type=\plusfive
       \global\advance\d_page_sides_shift\d_page_sides_extrashift
       \global\d_page_sides_extrashift\zeropoint
     \fi\fi
   \else
     \ifnum\c_page_sides_float_type<\plusfour
       \global\c_page_sides_float_type\plusfour
     \else\ifnum\c_page_sides_float_type>\plusfive
       \global\c_page_sides_float_type\plusfive
     \fi\fi
   \fi}

\def\page_sides_set_skips
  {\global\d_page_sides_rightskip\zeropoint
   \global\d_page_sides_leftskip \zeropoint
   \ifcase\c_page_sides_float_type
   \or % backspace
     \global\d_page_sides_leftskip\dimexpr
       +\rightorleftpageaction \backspace           \cutspace
       +\compensatedinnermakeupmargin
     \relax
   \or % leftedge
     \global\d_page_sides_leftskip\dimexpr
       +\rightorleftpageaction \leftmargindistance  \rightmargindistance
       +\rightorleftpageaction \leftmarginwidth     \rightmarginwidth
       +\rightorleftpageaction \leftedgedistance    \rightedgedistance
       +\compensatedinnermakeupmargin
     \relax
   \or % leftmargin
     \global\d_page_sides_leftskip\dimexpr
       +\rightorleftpageaction \leftmargindistance  \rightmargindistance
       +\compensatedinnermakeupmargin
     \relax
   \or % leftside
   \or % rightside
   \or % rightmargin
     \global\d_page_sides_rightskip\dimexpr
       +\rightorleftpageaction \rightmargindistance \leftmargindistance
       +\compensatedinnermakeupmargin
     \relax
   \or % rightedge
     \global\d_page_sides_rightskip\dimexpr
       +\rightorleftpageaction \rightmargindistance \leftmargindistance
       +\rightorleftpageaction \rightmarginwidth    \leftmarginwidth
       +\rightorleftpageaction \rightedgedistance   \leftedgedistance
       +\compensatedinnermakeupmargin
     \relax
   \or % cutspace
     \global\d_page_sides_rightskip\dimexpr
       +\rightorleftpageaction \cutspace            \backspace
       +\compensatedinnermakeupmargin
     \relax
   \fi
   \ifdim\d_page_sides_rightskip>\zeropoint \global\advance\d_page_sides_rightskip\rightskip \fi
   \ifdim\d_page_sides_leftskip >\zeropoint \global\advance\d_page_sides_leftskip \leftskip  \fi}

\def\page_sides_flush_floats
  {\par
   \ifnum\dimexpr\d_page_sides_vsize-\pagetotal\relax>\zeropoint
     \page_sides_flush_floats_indeed
   \fi
   % also here if used at all \global\holdinginserts\zerocount
   \global\d_page_sides_vsize\d_page_sides_vsize_reset
   \global\setfalse\c_page_sides_short
   \global\setfalse\c_page_sides_flag}

\unexpanded\def\doifelsesidefloat
  {\par
   \ifnum\dimexpr\d_page_sides_vsize-\pagetotal\relax>\zeropoint
     \expandafter\firstoftwoarguments
   \else
     \expandafter\secondoftwoarguments
   \fi}

\let\doifsidefloatelse\doifelsesidefloat

% \def\page_sides_flush_floats_indeed
%   {\global\advance\d_page_sides_vsize-\d_page_sides_bottomskip
%    \begingroup
%    \let\page_sides_flush_floats\relax
%    \forgetall
%    \doloop
%      {\strut
%       \iftracesidefloats
%         \color[darkgray]{\ruledhbox{\strut\kern\d_page_sides_width}}%
%       \fi
%       \par
%     % \ifdim\dimexpr\d_page_sides_vsize-\pagetotal\relax>\zeropoint
%       \ifdim\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax>\zeropoint
%         \ifnum\recurselevel>\plushundred % safeguard, sort of deadcycles
%           \exitloop
%         \fi
%       \else
%         \exitloop
%       \fi}%
%    \endgroup
%    \ifdim\parskip>\zeropoint % why this test ?
%      \ifdim\d_page_sides_bottomskip>\parskip
%      % \nowhitespace
%      % \vskip\d_page_sides_bottomskip
%        \blank[\v!nowhite,\the\dimexpr\d_page_sides_bottomskip]
%      \fi
%    \else
%       \blank[\the\d_page_sides_bottomskip]% new, so needs checking
%    \fi}

\installcorenamespace{sidefloatsteps}

\setvalue{\??sidefloatsteps\v!line  }{\strut}
\setvalue{\??sidefloatsteps\v!big   }{\strut}
\setvalue{\??sidefloatsteps\v!medium}{\halfstrut}
\setvalue{\??sidefloatsteps\v!small }{\quarterstrut}
\setvalue{\??sidefloatsteps\v!depth }{\depthstrut}

% we don't officially know what kind of float we flush

\def\page_sides_flush_floats_indeed
  {\global\advance\d_page_sides_vsize-\d_page_sides_bottomskip
   \begingroup
   \let\page_sides_flush_floats\relax
   \edef\m_pages_strut{\executeifdefined{\??sidefloatsteps\rootfloatparameter\c!step}\strut}%
   \forgetall
   \doloop
     {\iftracesidefloats
        \dontleavehmode
        \ruledhpack{\m_pages_strut\kern\d_page_sides_width}%
      \else
        \m_pages_strut
      \fi
      \par
      \nointerlineskip
    % \ifdim\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax>\zeropoint
      \ifdim\dimexpr\d_page_sides_vsize-\pagetotal\relax>\zeropoint
        \ifnum\recurselevel>\plushundred % safeguard, sort of deadcycles
          \exitloop
        \fi
      \else
        \exitloop
      \fi}%
   \endgroup
   \ifdim\parskip>\zeropoint % why this test ?
     \ifdim\d_page_sides_bottomskip>\parskip
     % \nowhitespace
     % \vskip\d_page_sides_bottomskip
%      \blank[\v!nowhite,\the\dimexpr\d_page_sides_bottomskip]
       \blank[\v!nowhite,\rootfloatparameter\c!sidespaceafter]
     \fi
   \else
%     \blank[\the\d_page_sides_bottomskip]% new, so needs checking
      \blank[\rootfloatparameter\c!sidespaceafter]% new, so needs checking
   \fi}

% alternative method (unsnapped)
%
% \def\page_sides_flush_floats_indeed
%   {\privatescratchdimen\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax
%    \ifdim\parskip>\zeropoint % why this test ?
%      \ifdim\privatescratchdimen>\parskip
%        \blank[\v!nowhite,\the\privatescratchdimen] % better in stages
%      \fi
%    \else
%        \blank[\the\privatescratchdimen]
%    \fi}

\def\page_sides_check_floats_after_par
  {\page_sides_check_floats_indeed
   \ifdim\oldpagetotal=\pagetotal \else
     \global\let\page_sides_check_floats\page_sides_check_floats_indeed
     \page_sides_flush_floats
     \global\c_page_sides_n_of_lines\zerocount % here !
   \fi}

\unexpanded\def\page_sides_flush_floats_after_par
  {\xdef\oldpagetotal{\the\pagetotal}%
   \global\let\page_sides_check_floats\page_sides_check_floats_after_par}

\unexpanded\def\page_sides_forget_floats
  {\global\d_page_sides_vsize\d_page_sides_vsize_reset
   \global\c_page_sides_n_of_lines\zerocount
   % also here if used at all \global\holdinginserts\zerocount
   \global\setfalse\c_page_sides_short
   \global\setfalse\c_page_sides_flag}

\let\page_otr_sides_pop_penalties \relax
\let\page_otr_sides_push_penalties\relax

% \def\page_otr_sides_push_penalties % needed ? and right
%   {\widowpenalty\plusone
%    \clubpenalty\plustwo
%    \brokenpenalty\plusone
%    \let\page_otr_sides_push_penalties\relax
%    \edef\page_otr_sides_pop_penalties
%      {\widowpenalty \the\widowpenalty
%       \clubpenalty  \the\clubpenalty
%       \brokenpenalty\the\brokenpenalty
%       \let\page_otr_sides_pop_penalties\relax}}
%
% shouldn't that be:
%
% \def\page_otr_sides_push_penalties % needed?
%   {\let\page_otr_sides_push_penalties\relax
%    \edef\page_otr_sides_pop_penalties
%      {\widowpenalty \the\widowpenalty
%       \clubpenalty  \the\clubpenalty
%       \brokenpenalty\the\brokenpenalty
%       \let\page_otr_sides_pop_penalties\relax}%
%    \widowpenalty\plusone
%    \clubpenalty\plustwo
%    \brokenpenalty\plusone}

\def\page_sides_restore_output_penalty
  {\ifnum\outputpenalty=\plustenthousand \else
     \penalty\outputpenalty
   \fi}

\def\page_sides_output_routine
  {\ifconditional\c_page_sides_short
     \page_sides_output_routine_yes
   \else
     \page_sides_output_routine_nop
   \fi}

\def\page_sides_output_routine_nop
  {\page_otr_command_side_float_output % otr specific
   \global\d_page_sides_vsize\d_page_sides_vsize_reset
   \global\c_page_sides_n_of_lines\zerocount
   % we can end up in fig lock, so \global\holdinginserts\zerocount here too ?
   \page_otr_sides_pop_penalties}

\def\page_sides_output_routine_yes % we need to rework this ... add pagediscards and such
  {\unvbox\normalpagebox % bah, and the discards?
% \pagediscards
   \setbox\b_page_sides_bottom\lastbox
   \ifdim\wd\b_page_sides_bottom>\d_page_sides_hsize
     \penalty-201 % hm, i really need to write this from scatch
     \box\b_page_sides_bottom
   \else\ifvoid\b_page_sides_bottom
   \else
     \page_sides_restore_left_indent
     \ifdim\wd\b_page_sides_bottom<\d_page_sides_hsize
       \parskip\zeropoint
       %\noindent
       \ifinner\else
         \vadjust{\penalty\minusone}%
       \fi
       \ifconditional\c_page_sides_l_eq
         \global\setfalse\c_page_sides_l_eq
       \else
         \global\advance\d_page_sides_hsize -\wd\b_page_sides_bottom
         \ifconditional\c_page_sides_r_eq
           \global\setfalse\c_page_sides_r_eq
         \else
           \global\divide\d_page_sides_hsize \plustwo
         \fi
         \hskip\d_page_sides_hsize % \kern
       \fi
     \fi
     \box\b_page_sides_bottom
     \page_sides_restore_output_penalty
   \fi\fi
   % why was this \global\holdinginserts\zerocount
   \global\setfalse\c_page_sides_short}

\def\page_sides_restore_left_indent
  {\relax
   \ifnum\c_page_sides_float_type>\plusfour \else
     \parskip\zeropoint % here ?
     \ifdim\d_page_sides_width>\zeropoint % new, see prikkels
       \noindent
       \ifinner \else
         \vadjust{\penalty\minusone}%
       \fi
       \hskip\d_page_sides_width\relax % \kern
    %\else
    %  we have a margin or edge float
     \fi
   \fi}

% The clean way:
%
% \global\setbox\floatbox\hbox
%   {\ifcase\c_page_sides_float_type
%      \vbox{#1}%
%    \or % 1
%      \kern\d_page_sides_leftshift
%      \kern\d_page_sides_shift
%      \vbox{#1}%
%      \kern-\d_page_sides_extrashift
%    \or % 2
%      \kern\d_page_sides_shift
%      \vbox{#1}%
%      \kern-\d_page_sides_extrashift
%    \or % 3
%      \kern\d_page_sides_shift
%      \vbox{#1}%
%      \kern-\d_page_sides_extrashift
%    \or % 4
%      \kern\d_page_sides_leftshift
%      \kern\d_page_sides_shift
%      \vbox{#1\removedepth}%
%      \kern-\d_page_sides_extrashift
%    \or % 5
%      \kern-\d_page_sides_extrashift
%      \vbox{#1}%
%      \kern\d_page_sides_shift
%      \kern\d_page_sides_rightshift
%    \or % 6
%      \kern-\d_page_sides_extrashift
%      \vbox{#1}%
%      \kern\d_page_sides_shift
%    \or % 7
%      \kern-\d_page_sides_extrashift
%      \vbox{#1}%
%      \kern\d_page_sides_shift
%    \or % 8
%      \kern-\d_page_sides_extrashift
%      \vbox{#1}%
%      \kern\d_page_sides_shift
%      \kern\d_page_sides_rightshift
%    \fi}
%
% The compact way:

\def\page_sides_relocate_float#1%
  {\global\setbox\floatbox\hpack
     {\ifnum\c_page_sides_float_type=\plusfour
        \kern\d_page_sides_leftshift
      \else\ifnum\c_page_sides_float_type=\plusone
        \kern\d_page_sides_leftshift
      \fi\fi
      \ifnum\c_page_sides_float_type>\plusfour
        \kern-\d_page_sides_extrashift
      \else
        \kern\d_page_sides_shift
      \fi
      \vbox{#1\ifnum\c_page_sides_align=\plusfour \removedepth \fi}%
      \ifnum\c_page_sides_float_type>\plusfour
        \kern\d_page_sides_shift
      \else
        \kern-\d_page_sides_extrashift
      \fi
      \ifnum\c_page_sides_float_type=\pluseight
        \kern\d_page_sides_rightshift
      \else\ifnum\c_page_sides_float_type=\plusfive
        \kern\d_page_sides_rightshift
      \fi\fi}}

\def\page_sides_apply_vertical_shift
  {\ifnum\c_page_sides_align=\plusfour
     \getnoflines{\ht\floatbox}%
     \privatescratchdimen\dimexpr\noflines\lineheight-\strutdepth\relax
     \getrawnoflines\d_page_sides_topskip
     \advance\privatescratchdimen\noflines\lineheight
     % todo: maybe rounding problem here
     % \global\setbox\floatbox\hbox{\lower\lineheight\box\floatbox}%
     \global\setbox\floatbox\hpack{\lower\strutdepth\box\floatbox}%
     \ht\floatbox\privatescratchdimen
     \dp\floatbox\zeropoint
   \fi
   \ifcase\c_page_sides_align \else
     \global\d_page_sides_topskip\zeropoint
   \fi
   \privatescratchdimen
     \ifnum\c_page_sides_float_type<\plusfour
       \d_page_sides_topskip
     \else\ifnum\c_page_sides_float_type>\plusfive
       \d_page_sides_topskip
     \else
       \zeropoint
     \fi\fi
   % the top of the box is at the previous baseline
   \ifcase\c_page_sides_align
       % 0 normal
     \advance\privatescratchdimen\strutdepth  % or \openstrutdepth
   \or % 1 height
     \advance\privatescratchdimen\strutdepth  % or \openstrutdepth
   \or % 2 line
   \or % 3 depth
     \advance\privatescratchdimen\lineheight  % or \openlineheight
     \advance\privatescratchdimen\strutdepth  % or \openstrutdepth
   \or % 4 grid
     \privatescratchdimen\zeropoint
   \or
     \advance\privatescratchdimen\strutheight % or \openstrutheight
   \fi
   % new
   \global\c_page_sides_lines_done\zerocount
   \ifnum\c_page_sides_n_of_lines>\zerocount
     \advance\privatescratchdimen\c_page_sides_n_of_lines\lineheight
   \fi
   \global\setbox\floatbox\hpack % why extra box
     {\vbox
        {\vskip\privatescratchdimen
         \nointerlineskip
         \box\floatbox
         \ifnum\c_page_sides_align=\plusfive \vskip-\lineheight \fi}}%
   \ifnum\c_page_sides_float_type<\plusfour
     \global\d_page_sides_topskip\zeropoint
   \else\ifnum\c_page_sides_float_type>\plusfive
     \global\d_page_sides_topskip\zeropoint
   \fi\fi
   \global\d_page_sides_downshift\zeropoint}

\def\page_sides_place_float
  {\ifnum\c_page_sides_float_type=\plusfour \kern\d_page_sides_topskip \fi
   \ifnum\c_page_sides_float_type=\plusfive \kern\d_page_sides_topskip \fi
   \d_page_sides_saved_depth\prevdepth
   \nointerlineskip
   \ifgridsnapping
     \page_sides_place_float_grid
   \else
     \page_sides_place_float_normal
   \fi
   \par
   \kern-\d_page_sides_height
   \penalty10001 % oeps, this will change
   \normalbaselines
   \prevdepth\d_page_sides_saved_depth}

\def\page_sides_place_float_normal
  {\page_sides_push_float_inline\firstofoneargument}

% The following needs some more work .. consider this a quick hack. We
% probably need an mkiv hanging grid option.

\def\page_sides_place_snap_to_grid#1%
  {\edef\p_grid{\floatparameter\c!grid}%
   \ifx\p_grid\empty\else
     \snaptogrid[\p_grid]%
   \fi
   \hbox{#1}}

\def\page_sides_place_float_grid
  {\getrawnoflines\d_page_sides_height % raw ?
   \d_page_sides_height\noflines\lineheight
   \page_sides_push_float_inline\page_sides_place_snap_to_grid}

\let\strc_floats_mark_par_as_free\relax

\def\page_sides_push_float_inline#1%
  {\begingroup
   \reseteverypar % needed !
   \parskip\zeropoint  % needed !
   \page_sides_set_skips
   \page_sides_insert_info
   \relax
   \lefttoright % \textdir TLT\relax  % or \ifconditional\displaylefttoright below (more work)
   \strc_floats_mark_par_as_free
   \ifcase\c_page_sides_float_type
     % invalid
   \or % backspace
     \noindent#1{\llap{\rlap{\box\floatbox}\kern\d_page_sides_leftskip}}\hfill
   \or % leftedge
     \noindent#1{\llap{\box\floatbox\kern\d_page_sides_leftskip}}\hfill
   \or % leftmargin
     \noindent#1{\llap{\box\floatbox\kern\d_page_sides_leftskip}}\hfill
   \or % leftside
     \noindent#1{\box\floatbox}\hfill
   \or % rightside
     \hfill#1{\box\floatbox}%
   \or % rightmargin
     \hfill#1{\rlap{\kern\d_page_sides_rightskip\box\floatbox}}%
   \or % rightedge
     \hfill#1{\rlap{\kern\d_page_sides_rightskip\box\floatbox}}%
   \or % cutspace
     \hfill#1{\rlap{\kern\d_page_sides_rightskip\llap{\box\floatbox}}}%
   \fi
   \endgroup}

\def\page_sides_analyse_progress
  {\d_page_sides_progress\d_page_sides_vsize
   \ifconditional\c_page_sides_flag
     \advance\d_page_sides_progress-\d_page_sides_page_total
     \global\setfalse\c_page_sides_flag
   \else
     \advance\d_page_sides_progress-\pagetotal
   \fi}

\def\page_sides_analyse_space
  {\global\settrue\c_page_sides_flag
   \global\d_page_sides_page_total \pagetotal % global
   \ifnum\c_page_sides_float_type<\plusfour
     \global\d_page_sides_width \zeropoint
   \else\ifnum\c_page_sides_float_type>\plusfive
     \global\d_page_sides_width\zeropoint
   \else
     \global\d_page_sides_width\dimexpr\wd\floatbox+\d_strc_floats_margin\relax
   \fi\fi
   \ifdim\d_page_sides_width<\zeropoint
     \global\d_page_sides_width\zeropoint
   \fi
   \global\d_page_sides_hsize \dimexpr\hsize-\d_page_sides_width\relax
   \global\d_page_sides_height\dimexpr\ht\floatbox+\dp\floatbox+\d_page_sides_topskip\relax
   \global\d_page_sides_vsize \dimexpr\d_page_sides_height+\d_page_sides_page_total\relax
   \dimen0\d_page_sides_vsize
   \dimen2\pagegoal
   \relax
   \ifcase\c_page_sides_method
     % method 0 : raw
   \or
     % method 1 : safe
     \dimen2 .99\pagegoal
   \or
     % method 2 : tight
     \advance\dimen0 -\onepoint
   \fi
   \relax % really needed ! ! ! !
   \ifdim\dimen0>\dimen2
     \global\setfalse\c_page_floats_room
   \else
     \ifdim\dimexpr\pagegoal-\d_page_sides_vsize\relax<\d_page_sides_bottomskip
      % just weird: \global\advance\d_page_sides_vsize \dimen0
       \global\settrue\c_page_sides_short
       \page_otr_sides_push_penalties
       % why was this \global\holdinginserts\plusone
     \else
       \global\advance\d_page_sides_vsize \d_page_sides_bottomskip
       \global\setfalse\c_page_sides_short
     \fi
     \global\settrue\c_page_floats_room
   \fi}

% \def\page_sides_prepare_space
%   {\par
%    % no longer needed  \whitespace
%    \begingroup
%    \forgetall
%    \reseteverypar
%    \verticalstrut
%    \vskip-\struttotal
%    \endgroup}

% \installtextracker
%   {sidefloats.anchor}
%   {\let\page_sides_anchor\page_sides_anchor_yes}
%   {\let\page_sides_anchor\page_sides_anchor_nop}
%
% \def\page_sides_anchor_yes
%   {\darkred
%    \hskip-5\emwidth
%    \vrule\s!height.05\exheight\s!depth.05\exheight\s!width10\emwidth}
%
% \def\page_sides_anchor_nop
%   {\strut}
%
% \let\page_sides_anchor\page_sides_anchor_nop
%
% \def\page_sides_prepare_space
%   {\par
%    \begingroup
%    \reseteverypar
%    \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}%
%    \vskip-\parskip
%    \vskip-\struttotal
%    \inhibitblank
%    \endgroup}

\def\page_sides_prepare_space
  {\fakenextstrutline
   \inhibitblank}

\def\page_sides_handle_float#1% grid (4) is rather experimental
  {\page_sides_prepare_space
   \page_sides_apply_horizontal_shift
   \page_sides_check_previous_float
   \page_sides_inject_dummy_lines
   \page_sides_relocate_float{#1}%
   \page_sides_apply_vertical_shift
   \page_sides_analyse_space
   \ifconditional\c_page_floats_room \else
     \page_otr_fill_and_eject_page
     \page_sides_analyse_space
     \page_sides_inject_dummy_lines
   \fi
   \page_sides_place_float
   \page_sides_check_floats_reset
   \ignorespaces} % not really needed

\def\page_sides_check_floats_indeed
  {\page_sides_analyse_progress
   \ifdim\d_page_sides_progress>\zeropoint
     \page_sides_check_floats_set
   \else
     \page_sides_check_floats_reset
   \fi
   \parskip\s_spac_whitespace_parskip}

\let\page_sides_check_floats\page_sides_check_floats_indeed

\unexpanded\def\page_sides_check_floats_set
  {\privatescratchdimen\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax
   \c_page_sides_n_of_hang\privatescratchdimen
   \divide\c_page_sides_n_of_hang \baselineskip\relax
   \ifnum\c_page_sides_n_of_hang>\zerocount
     % new from here (needs test case, old code)
     \ifcase\c_page_sides_n_of_lines
     \else
       \ifcase\c_page_sides_lines_done
         \global\c_page_sides_lines_done\c_page_sides_n_of_hang
       \else
         \privatescratchcounter\c_page_sides_lines_done
         \advance\privatescratchcounter-\c_page_sides_n_of_hang
         \global\advance\c_page_sides_n_of_lines-\privatescratchcounter
       \fi
     \fi
     % hm, when do we get the parshape branch? needs testing
     \ifnum\c_page_sides_n_of_lines>\zerocount
       \privatescratchtoks\emptytoks
       \privatescratchcounter\c_page_sides_n_of_lines
       \privatescratchdimen\dimexpr\hsize-\d_page_sides_width\relax
       \dorecurse\c_page_sides_n_of_lines
         {\appendtoks \zeropoint \hsize \to \privatescratchtoks}%
       \ifnum\c_page_sides_n_of_hang>\c_page_sides_n_of_lines
         \advance\c_page_sides_n_of_hang -\c_page_sides_n_of_lines\relax
         \advance\privatescratchcounter\c_page_sides_n_of_hang
         \dorecurse\c_page_sides_n_of_hang % weird, shouldn't that be scratchcounter
           {\ifnum\c_page_sides_float_type>\plusfour
              \appendtoks \zeropoint         \privatescratchdimen \to \privatescratchtoks
            \else
              \appendtoks \d_page_sides_width\privatescratchdimen \to \privatescratchtoks
            \fi}%
       \fi
       \parshape
         \numexpr\privatescratchcounter+\plusone\relax
         \the\privatescratchtoks  % \privatescratchcounter
         \zeropoint \hsize % \plusone
       \relax
     \else
       % new till here
       \hangindent \ifnum\c_page_sides_float_type>\plusfour -\fi\d_page_sides_width
       \hangafter-\c_page_sides_n_of_hang
     \fi
   \fi
   \global\advance\c_page_sides_checks_done \plusone
   \iftracesidefloats
     \hskip-\d_page_sides_width % kern
     \color[darkgray]%
       {\vrule\s!height.5\points\s!depth.5\points\s!width\d_page_sides_width
        \llap{\showstruts\strut\kern.25\bodyfontsize}}%
   \fi}

\unexpanded\def\page_sides_check_floats_reset
  {\global\c_page_sides_checks_done\zerocount}

\unexpanded\def\page_sides_synchronize_floats
  {\ifinner \else
     \page_sides_check_floats
   \fi}

\unexpanded\def\page_sides_check_previous_float
  {\page_sides_analyse_progress
   \ifdim\d_page_sides_progress>\zeropoint \relax
     \ifconditional\c_page_sides_short
       \global\setfalse\c_page_sides_short
       \page_otr_fill_and_eject_page
     \else
       \kern\d_page_sides_progress
     \fi
   \fi}

\def\page_sides_inject_dummy_lines
  {\begingroup
   \privatescratchcounter\pageshrink
   \divide\privatescratchcounter \baselineskip
   \advance\privatescratchcounter \plusone
   \parskip\zeropoint
   \dorecurse\privatescratchcounter{\hpack to \hsize{}}%
   \kern-\privatescratchcounter\baselineskip
   \penalty\zerocount
   \endgroup}

% Display math
%
% If we need this, it will be redone but redefining
% these macros does not really work out in the current
% situation.
%
% \ifx\normalleqno\undefined
%
%   \let\floatrighteqo=\eqno
%   \let\floatleftleqo=\leqno
%
% \else
%
%   \let\floatrighteqo=\normaleqno
%   \let\floatleftleqo=\normalleqno
%
% \fi
%
% \ifx\normaleqno\undefined
%
%   \def\normaleqno
%     {\ifconditional\c_page_sides_short
%        \global\settrue\c_page_sides_r_eq
%      \fi
%      \floatrighteqo}
%
% \else
%
%   \def\eqno
%     {\ifconditional\c_page_sides_short
%        \global\settrue\c_page_sides_r_eq
%      \fi
%      \floatrighteqo}
%
% \fi

\def\adjustsidefloatdisplaylines % public, will change
  {\aftergroup\page_sides_adjust_display_lines}

\def\page_sides_adjust_display_lines
  {\par
   \noindent
   \ignorespaces}

% We need to hook it into the other otr's. This code will be adapted
% once we rename the callers.

% \def as they can be redefined!

% some will become obsolete

\def\checksidefloat         {\page_sides_check_floats}
\def\flushsidefloats        {\page_sides_flush_floats}
\def\flushsidefloatsafterpar{\page_sides_flush_floats_after_par}
\def\forgetsidefloats       {\page_sides_forget_floats}
%def\synchronizesidefloats  {\page_sides_synchronize_floats}

\protect \endinput
