summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/page-sid.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/page-sid.mkiv')
-rw-r--r--tex/context/base/mkiv/page-sid.mkiv933
1 files changed, 468 insertions, 465 deletions
diff --git a/tex/context/base/mkiv/page-sid.mkiv b/tex/context/base/mkiv/page-sid.mkiv
index f32a443be..5742ce8c4 100644
--- a/tex/context/base/mkiv/page-sid.mkiv
+++ b/tex/context/base/mkiv/page-sid.mkiv
@@ -15,31 +15,32 @@
\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.
+%D These macro deal with side floats. We started with Daniel Comenetz macros as
+%D published in TUGBoat Volume 14 (1993), No.\ 1: Anchored Figures at Either Margin.
+%D I extended and patched the macros to suite our needs which results in a messy
+%D module.
+%D
+%D A complication is that we need to deal with spacing differently before and after
+%D the float. Also, whitespace can interfere as does the prevdepth. There is no real
+%D universal solution. So, by now not much is left of that code, if only because we
+%D need to match \CONTEXT\ spacing module, because we have more placement options
+%D and control and because the math hackery is not suitable for \CONTEXT\ anyway.
+%D
+%D This code had been redone many times because we kept running into spacing issues
+%D and it's not that much fun (or rewarding). It's probably the module that made
+%D me go into distraciton mode most often (like watching amusing Walk of The
+%D Earth, sophisticated Massive Attack video clips, impressive Davie504 movies
+%D and so on).
\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_vsize_reset
\newdimen \d_page_sides_progress
\newdimen \d_page_sides_page_total
-\newdimen \d_page_sides_saved_depth
-\newbox \b_page_sides_bottom
+%newbox \b_page_sides_bottom
\newcount \c_page_sides_lines_done
\newcount \c_page_sides_checks_done
@@ -47,12 +48,9 @@
\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_short
\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
@@ -62,10 +60,43 @@
\newdimen \d_page_sides_maximum
\newdimen \d_page_sides_topskip
\newdimen \d_page_sides_bottomskip
+\newdimen \d_page_sides_midskip
\newdimen \d_page_sides_downshift
+\newdimen \d_page_sides_pagetotal
+\newdimen \d_page_sides_topoffset
+\newdimen \d_page_sides_bottomoffset
+\newdimen \d_page_sides_toptotal
+\newdimen \d_page_sides_bottomtotal
+
+\newconstant \c_page_sides_align
+\newconstant \c_page_sides_skipmode
+\newconstant \c_page_sides_tolerance
+
+\newconstant \c_page_sides_method % sort of obsolete
+
+\newdimen \d_page_sides_progression
-\setnewconstant \c_page_sides_method \plusone % 0=raw 1=safe (.99) 2=tight (-1pt)
-\setnewconstant \c_page_sides_align \zerocount
+\newif \iftracesidefloats % public (might change)
+
+%D Defaults:
+
+\d_page_sides_vsize_reset -\onepoint
+%d_page_sides_vsize_reset \zeropoint % could be an option, needs testing
+
+%D We have some basic (and colorful) tracing:
+
+\def\page_sides_floats_legend
+ {\showmessage\m!floatblocks{16}\empty
+ \glet\page_sides_floats_legend\relax}
+
+\installtextracker{floats.anchoring}
+ {\page_sides_floats_legend
+ \tracesidefloatstrue}
+ {\tracesidefloatsfalse}
+
+%D The horizontal shifts depend on the location: left or right in the text, margin
+%D or edge. These shifts are rather stable and don't interfere with the page flow
+%D as much as the vertical ones do.
\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}
@@ -77,14 +108,13 @@
\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_check_horizontal_skips
+ {\ifcase\c_page_sides_skipmode
+ \or % high
+ \or % low
+ \or % fit
+ \global\d_strc_floats_margin\zeropoint
+ \fi}
\def\page_sides_apply_horizontal_shift
{\ifdim\d_page_sides_maximum>\zeropoint
@@ -185,275 +215,14 @@
+\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
+ \ifdim\d_page_sides_rightskip>\zeropoint
+ \global\advance\d_page_sides_rightskip\rightskip
\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 !
+ \ifdim\d_page_sides_leftskip >\zeropoint
+ \global\advance\d_page_sides_leftskip \leftskip
\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:
+%D Shifts get applied to the float box:
\def\page_sides_relocate_float#1%
{\global\setbox\floatbox\hpack
@@ -479,67 +248,347 @@
\kern\d_page_sides_rightshift
\fi\fi}}
+%D The vertical skips are a nightmare and this mechanism is about as complex
+%D as one can get it.
+
+\def\page_sides_check_vertical_skips
+ {\ifdim\d_page_sides_topskip <\zeropoint\d_page_sides_topskip \zeropoint\fi
+ \ifdim\d_page_sides_bottomskip<\zeropoint\d_page_sides_bottomskip\zeropoint\fi
+ \ifdim\d_page_sides_midskip <\zeropoint\d_page_sides_midskip \zeropoint\fi
+ %
+ \global\d_page_sides_toptotal \dimexpr\d_page_sides_topskip +\d_page_sides_topoffset \relax
+ \global\d_page_sides_bottomtotal\dimexpr\d_page_sides_bottomskip+\d_page_sides_bottomoffset\relax
+ \ifcase\c_page_sides_skipmode
+ \or % high
+ \global\d_page_sides_toptotal \d_page_sides_topoffset
+ \or % low
+ \global\d_page_sides_bottomtotal\d_page_sides_bottomoffset
+ \or % fit
+ \global\d_page_sides_toptotal \d_page_sides_topoffset
+ \global\d_page_sides_bottomtotal\d_page_sides_bottomoffset
+ \fi}
+
+%D These shifts get (selectively) applied with a bit of optional tracing.
+
+\def\page_sides_apply_vertical_shift_normal
+ {\global\setbox\floatbox\hpack % why extra box
+ {\vpack
+ {\forgetall
+ \hsize\wd\floatbox
+ \vskip\privatescratchdimen
+ \offinterlineskip
+ \box\floatbox
+ % somehow we need this \scratchbox magic, but at least it's the same as the
+ % tracer now
+ \setbox\scratchbox\emptybox
+ \wd\scratchbox\hsize
+ \ht\scratchbox\d_page_sides_bottomtotal
+ \box\scratchbox
+ \vskip-\d_page_sides_bottomtotal
+ \ifnum\c_page_sides_align=\plusfive
+ \vskip-\lineheight
+ \fi}}}
+
+\def\page_sides_apply_vertical_shift_traced
+ {\global\setbox\floatbox\hpack % why extra box
+ {\backgroundline[trace:r]{\ruledhpack{\vpack
+ {\forgetall
+ \hsize\wd\floatbox
+ \vskip\privatescratchdimen
+ \offinterlineskip
+ \backgroundline
+ [trace:g]%
+ {\ruledhpack{\box\floatbox}}%
+ \par
+ \blackrule
+ [\c!color=trace:s,%
+ \c!height=\d_page_sides_bottomtotal,%
+ \c!depth=\zeropoint,%
+ \c!width=\hsize]%
+ \vskip-\d_page_sides_bottomtotal
+ \ifnum\c_page_sides_align=\plusfive
+ \vskip-\lineheight
+ \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
+ \privatescratchdimen\dimexpr\noflines\lineheight-\strutdp\relax
+ \getrawnoflines\d_page_sides_toptotal
\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}%
+ \page_sides_force_depth
\ht\floatbox\privatescratchdimen
\dp\floatbox\zeropoint
\fi
\ifcase\c_page_sides_align \else
- \global\d_page_sides_topskip\zeropoint
+ \global\d_page_sides_toptotal\zeropoint
\fi
\privatescratchdimen
\ifnum\c_page_sides_float_type<\plusfour
- \d_page_sides_topskip
+ \d_page_sides_toptotal
\else\ifnum\c_page_sides_float_type>\plusfive
- \d_page_sides_topskip
+ \d_page_sides_toptotal
\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
+ \advance\privatescratchdimen\strutdp % or \openstrutdepth
\or % 1 height
- \advance\privatescratchdimen\strutdepth % or \openstrutdepth
+ \advance\privatescratchdimen\strutdp % or \openstrutdepth
\or % 2 line
\or % 3 depth
- \advance\privatescratchdimen\lineheight % or \openlineheight
- \advance\privatescratchdimen\strutdepth % or \openstrutdepth
+ \advance\privatescratchdimen\lineheight % or \openlineheight
+ \advance\privatescratchdimen\strutdp % or \openstrutdepth
\or % 4 grid
\privatescratchdimen\zeropoint
\or
- \advance\privatescratchdimen\strutheight % or \openstrutheight
+ \advance\privatescratchdimen\strutht % 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}}%
+ \iftracesidefloats
+ \page_sides_apply_vertical_shift_traced % uses \privatescratchdimen
+ \else
+ \page_sides_apply_vertical_shift_normal % uses \privatescratchdimen
+ \fi
\ifnum\c_page_sides_float_type<\plusfour
- \global\d_page_sides_topskip\zeropoint
+ \global\d_page_sides_toptotal\zeropoint
\else\ifnum\c_page_sides_float_type>\plusfive
- \global\d_page_sides_topskip\zeropoint
+ \global\d_page_sides_toptotal\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
+%D We have a few virtual dimensions. I'm not sure what to do with \type
+%D {\pagedepth} and \type {\pageshrink} in the next two. If we ever need
+%D that it will become options.
+
+\def\e_page_sides_flush_criterium
+ {\dimexpr
+ \d_page_sides_vsize
+ -\d_page_sides_bottomtotal
+ -\pagetotal
+ \relax}
+
+\def\e_page_sides_room_criterium
+ {\dimexpr
+ \d_page_sides_vsize
+ -\d_page_sides_bottomtotal % added here too
+ -\pagetotal
+ \relax}
+
+%D In order to get a consistent spacing we force a strutdepth unless the
+%D preceding material has more depth than that already. This way anchoring
+%D becomes predictable.
+
+\unexpanded\def\page_sides_force_depth
+ {\iftracesidefloats
+ \begingroup
+ \c_page_force_strut_depth_trace_mode\plusone
+ \forcestrutdepth
+ \endgroup
+ \else
+ \forcestrutdepth
+ \fi}
+
+\def\page_sides_flush_floats
+ {\par
+ \ifdim\e_page_sides_flush_criterium>\zeropoint
+ \page_sides_flush_floats_progress
+ \page_sides_flush_floats_after_next
+ \fi
+ \page_sides_flush_floats_reset}
+
+\def\page_sides_flush_floats_text
+ {\par
+ % what with \c_anch_backgrounds_text_level>\plusone
+ \ifdim\e_page_sides_flush_criterium>\zeropoint
+ \page_sides_flush_floats_progress
+ \page_sides_flush_floats_after_none
+ \fi
+ \page_sides_flush_floats_reset}
+
+\def\page_sides_flush_floats_reset
+ {\global\d_page_sides_vsize\d_page_sides_vsize_reset
+ % also here if used at all \global\holdinginserts\zerocount
+ \global\setfalse\c_page_sides_short
+ \global\setfalse\c_page_sides_flag
+ \global\c_page_sides_checks_done\zerocount}
+
+\def\page_sides_flush_floats_after_none % we force a flush
+ {\ifdim\d_page_sides_midskip>\zeropoint
+ \blank[\the\d_page_sides_midskip]
+ \fi
+ \ignoreparskip
+ \blank[\v!disable]}
+
+\def\page_sides_flush_floats_after_next % we have two successive ones
+ {\ifdim\d_page_sides_bottomskip>\zeropoint
+ \blank[\the\d_page_sides_bottomskip]
+ \fi
+ \ignoreparskip
+ \blank[\v!disable]}
+
+%D A rudimentary checker:
+
+\unexpanded\def\doifelsesidefloat
+ {\par
+ \ifdim\e_page_sides_room_criterium>\zeropoint % -\pagedepth
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\let\doifsidefloatelse\doifelsesidefloat
+
+%D Sometimes we need to fill up the space alongside a side float and this
+%D is where we define the helpers. A user can enforce a smaller step. We use
+%D large steps when possible.
+
+\installcorenamespace{sidefloatsteps}
+
+\setvalue{\??sidefloatsteps\v!line }{\strut}
+\setvalue{\??sidefloatsteps\v!big }{\strut}
+\setvalue{\??sidefloatsteps\v!medium}{\halflinestrut} % was \halfstrut
+\setvalue{\??sidefloatsteps\v!small }{\noheightstrut} % was \quarterstrut
+
+\def\page_sides_flush_floats_tracer
+ {\dontleavehmode
+ \ruledhpack\bgroup\backgroundline[trace:b]{%
+ \llap{\smash{\vrule\s!width4\points\s!height.4\points\s!depth.4\points}}%
+ \ifnum\recurselevel=\plusone
+ \llap{\smash{\smallinfofont\the\scratchdimen}\hskip.5\leftmargindistance}%
+ \else\ifodd\recurselevel
+ \llap{\smash{\smallinfofont\recurselevel}\hskip.5\leftmargindistance}%
+ \fi\fi
+ \page_sides_flush_floats_normal
+ \kern\hsize
+ \egroup}}
+
+\def\page_sides_flush_floats_normal
+ {\ifdim\scratchdimen>\htdp\strutbox
+ \strut
+ \else
+ \m_pages_strut
+ \fi}
+
+\def\page_sides_flush_floats_progress
+ {\begingroup
+ \page_sides_force_depth
+ \parskip\zeropoint
+ \let\page_sides_flush_floats\relax
+ \edef\m_pages_strut
+ {\ifcsname\??sidefloatsteps\rootfloatparameter\c!step\endcsname
+ \lastnamedcs
+ \else
+ \noheightstrut
+ \fi}%
+ \forgetall
+ \offinterlineskip
+ \doloop
+ {\scratchdimen\e_page_sides_flush_criterium
+ \ifdim\scratchdimen>\onepoint % good enough, can become configurable
+ \ifnum\recurselevel>\plushundred % safeguard, sort of deadcycles
+ \exitloop
+ \else\iftracesidefloats
+ \page_sides_flush_floats_tracer\par
+ \else
+ \page_sides_flush_floats_normal\par
+ \fi\fi
+ \else
+ \page_sides_force_depth
+ \exitloop
+ \fi}%
+ \endgroup}
+
+%D We force a parskip and ignore it afterwards. We can nil it by setting the
+%D \type {spacebeforeside} parameter. We can have a leading blank so we need
+%D to make sure that we use blank to inject the parskip and then ignore
+%D the one injected by the engine.
+
+\def\page_sides_inject_before
+ {\page_sides_force_depth
+ \ifdim\parskip>\zeropoint
+ \ifdim\parskip>\d_strc_floats_top
+ \ifdim\d_strc_floats_top>\zeropoint
+ \ignoreparskip
+ \blank[\v!white]%
+ \else
+ \checkedblank[\rootfloatparameter\c!spacebeforeside]%
+ \fi
+ \else
+ \checkedblank[\rootfloatparameter\c!spacebeforeside]%
+ \fi
+ \else
+ \checkedblank[\rootfloatparameter\c!spacebeforeside]%
+ \fi}
+
+%D We are now done with \type {spacebefore} and the parskip is already
+%D injected. The dummy line makes sure that we anchor properly and it
+%D also can serve as tracer.
+
+\def\page_sides_inject_dummy_line_normal
+ {\hpack to \availablehsize{\strut\hss}}
+
+\def\page_sides_inject_dummy_line_traced
+ {\ruledhpack to \availablehsize{\backgroundline[trace:c]{\page_sides_inject_dummy_line_normal}}}
+
+\def\page_sides_inject_dummy_lines
+ {\par
\nointerlineskip
+ \dontleavehmode
+ \iftracesidefloats
+ \page_sides_inject_dummy_line_traced
+ \else
+ \page_sides_inject_dummy_line_normal
+ \fi
+ \vskip-\dimexpr\lineheight+\strutdp\relax
+ \ignoreparskip
+ \blank[\v!samepage]
+ \blank[\v!disable]}
+
+%D Checkers:
+
+\def\page_sides_check_floats_after_par
+ {\page_sides_check_floats_indeed
+ \ifdim\d_page_sides_pagetotal=\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
+ {\global\d_page_sides_pagetotal\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}
+
+%D Here comes the output routine. We either go the fast route or we use the
+%D normal one (stored in \type {\page_otr_command_side_float_output}. We no
+%D longer have this fuzzy code around with penalties and indentation and
+%D such.
+
+\def\page_sides_output_routine
+ {\page_otr_command_side_float_output
+ \ifconditional\c_page_sides_short
+ \global\setfalse\c_page_sides_short
+ \else
+ \global\d_page_sides_vsize\d_page_sides_vsize_reset
+ \global\c_page_sides_n_of_lines\zerocount
+ \fi}
+
+\def\page_sides_place_float
+ {\ifnum\c_page_sides_float_type=\plusfour \kern\d_page_sides_toptotal \fi
+ \ifnum\c_page_sides_float_type=\plusfive \kern\d_page_sides_toptotal \fi
\ifgridsnapping
\page_sides_place_float_grid
\else
@@ -548,21 +597,20 @@
\par
\kern-\d_page_sides_height
\penalty10001 % oeps, this will change
- \normalbaselines
- \prevdepth\d_page_sides_saved_depth}
+ \normalbaselines}
\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.
+%D The following needs some more work .. consider this a quick hack. We probably
+%D 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}}
+ \hpack{#1}}
\def\page_sides_place_float_grid
{\getrawnoflines\d_page_sides_height % raw ?
@@ -575,10 +623,11 @@
{\begingroup
\reseteverypar % needed !
\parskip\zeropoint % needed !
+ \nointerlineskip
\page_sides_set_skips
- \page_sides_insert_info
+ \page_floats_report_total
\relax
- \lefttoright % \textdir TLT\relax % or \ifconditional\displaylefttoright below (more work)
+ \lefttoright
\strc_floats_mark_par_as_free
\ifcase\c_page_sides_float_type
% invalid
@@ -612,6 +661,7 @@
\def\page_sides_analyse_space
{\global\settrue\c_page_sides_flag
+ \page_sides_force_depth
\global\d_page_sides_page_total \pagetotal % global
\ifnum\c_page_sides_float_type<\plusfour
\global\d_page_sides_width \zeropoint
@@ -624,79 +674,53 @@
\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_height\dimexpr\ht\floatbox+\dp\floatbox+\d_page_sides_toptotal\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
+ \scratchdimenone\d_page_sides_vsize
+ \scratchdimentwo\pagegoal
+ \ifcase\c_page_sides_tolerance
+ \ifcase\c_page_sides_method
+ % method 0 : raw
+ \or
+ % method 1 : safe (default)
+ \advance\scratchdimentwo -\strutdp
+ \or
+ % method 2 : tight (grid default)
+ \advance\scratchdimenone -\onepoint
+ \fi
\or
- % method 1 : safe
- \dimen2 .99\pagegoal
+ % tolerant
+ \advance\scratchdimentwo -.5\strutdp
\or
- % method 2 : tight
- \advance\dimen0 -\onepoint
+ % verytolerant
+ % \advance\scratchdimenone -\onepoint (maybe)
+ \else
+ \advance\scratchdimentwo -\strutdp
\fi
- \relax % really needed ! ! ! !
- \ifdim\dimen0>\dimen2
+ % how about \pagedepth
+ \ifdim\scratchdimenone>\scratchdimentwo
\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
+ \ifdim\dimexpr\pagegoal-\d_page_sides_vsize\relax<\d_page_sides_bottomtotal
+ % just weird: \global\advance\d_page_sides_vsize \scratchdimenone
\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\advance\d_page_sides_vsize \d_page_sides_bottomtotal % wins over inbetween
\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}
+%D As we have no clear end of one or more paragraphs we only have pre float
+%D skips.
\def\page_sides_handle_float#1% grid (4) is rather experimental
- {\page_sides_prepare_space
+ {\page_sides_check_horizontal_skips
+ \page_sides_check_vertical_skips
\page_sides_apply_horizontal_shift
\page_sides_check_previous_float
+ \page_sides_inject_before
\page_sides_inject_dummy_lines
\page_sides_relocate_float{#1}%
\page_sides_apply_vertical_shift
@@ -704,11 +728,18 @@
\ifconditional\c_page_floats_room \else
\page_otr_fill_and_eject_page
\page_sides_analyse_space
+ %\page_sides_inject_before
\page_sides_inject_dummy_lines
\fi
\page_sides_place_float
\page_sides_check_floats_reset
- \ignorespaces} % not really needed
+ \page_sides_wrapup}
+
+\def\page_sides_wrapup
+ {% we need to do this aftergroup
+ \ignoreparskip \aftergroup\ignoreparskip
+ \ignorespaces \aftergroup\ignorespaces
+ }
\def\page_sides_check_floats_indeed
{\page_sides_analyse_progress
@@ -717,16 +748,44 @@
\else
\page_sides_check_floats_reset
\fi
- \parskip\s_spac_whitespace_parskip}
+ \parskip\s_spac_whitespace_parskip} % not needed
\let\page_sides_check_floats\page_sides_check_floats_indeed
+\unexpanded\def\page_sides_check_floats_tracer
+ {\begingroup
+ \dontleavehmode
+ \ifnum\c_page_sides_float_type>\plusfour
+ \rlap
+ {\hskip\availablehsize % d_page_sides_width % kern
+ \color[trace:o]%
+ {\rlap{\kern.25\bodyfontsize\showstruts\strut}%
+ \vrule\s!height.5\points\s!depth.5\points\s!width\d_page_sides_width}}%
+ \else
+ \hskip-\d_page_sides_width % kern
+ \color[trace:o]%
+ {\vrule\s!height.5\points\s!depth.5\points\s!width\d_page_sides_width
+ \llap{\showstruts\strut\kern.25\bodyfontsize}}%
+ \fi
+ \endgroup}
+
\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
+ {\edef\p_sidethreshold{\floatparameter\c!sidethreshold}%
+ \ifx\p_sidethreshold\v!old
+ \d_page_sides_progression\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax
+ \c_page_sides_n_of_hang\d_page_sides_progression
+ \divide\c_page_sides_n_of_hang \baselineskip\relax
+ \else
+ \d_page_sides_progression
+ \ifx\p_sidethreshold\empty
+ \d_page_sides_progress
+ \else
+ \dimexpr\d_page_sides_progress-\p_sidethreshold\relax
+ \fi
+ \getnoflines\d_page_sides_progression
+ \c_page_sides_n_of_hang\noflines
+ \fi
\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
@@ -737,40 +796,35 @@
\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}%
+ {\toksapp\privatescratchtoks{\zeropoint\hsize}}%
\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
+ \toksapp\privatescratchtoks{\zeropoint\privatescratchdimen}%
\else
- \appendtoks \d_page_sides_width\privatescratchdimen \to \privatescratchtoks
+ \toksapp\privatescratchtoks{\d_page_sides_width\privatescratchdimen}%
\fi}%
\fi
\parshape
\numexpr\privatescratchcounter+\plusone\relax
- \the\privatescratchtoks % \privatescratchcounter
- \zeropoint \hsize % \plusone
+ \the\privatescratchtoks
+ \zeropoint \hsize
\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}}%
+ \page_sides_check_floats_tracer
\fi}
\unexpanded\def\page_sides_check_floats_reset
@@ -792,72 +846,21 @@
\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.
+% \def\adjustsidefloatdisplaylines % public, will change
+% {\aftergroup\page_sides_adjust_display_lines}
%
-% \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!
+% \def\page_sides_adjust_display_lines
+% {\par
+% \noindent
+% \ignorespaces}
-% some will become obsolete
+%D We need to hook it into the other otr's. This code will be adapted once we rename
+%D the callers. We use \type {\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}
+\unexpanded\def\checksidefloat {\page_sides_check_floats}
+\unexpanded\def\flushsidefloats {\page_sides_flush_floats_text}
+\unexpanded\def\flushsidefloatsafterpar{\page_sides_flush_floats_after_par}
+\unexpanded\def\forgetsidefloats {\page_sides_forget_floats}
+%unexpanded\def\synchronizesidefloats {\page_sides_synchronize_floats}
\protect \endinput