page-ffl.mkxl /size: 11 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=page-ffl,
3%D        version=2018.01.04,
4%D          title=\CONTEXT\ Page Macros,
5%D       subtitle=Facing floats,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Page Macros / Facing floats}
15
16%D The code below comes from a module made for Thomas Schmitz and is now part of the
17%D core. A simple example is given here:
18%D
19%D \starttyping
20%D \definefacingfloat
21%D   [whatever]
22%D
23%D \setupfacingfloat
24%D   [whatever]
25%D   [style=bold,
26%D    width=frame,
27%D    offset=10pt,
28%D    color=white]
29%D
30%D \setupfacingfloat
31%D   [whatever:left]
32%D   [background=color,
33%D    backgroundcolor=red]
34%D
35%D \setupfacingfloat
36%D   [whatever:right]
37%D   [background=color,
38%D    backgroundcolor=green]
39%D
40%D \startfacingfloat[whatever]
41%D     {\dorecurse{10}{\samplefile{tufte} }}
42%D     {\dorecurse{10}{\samplefile{ward}  }}
43%D     {\dorecurse{10}{\samplefile{tufte} }}
44%D     {\dorecurse{10}{\samplefile{ward}  }}
45%D \stopfacingfloat
46%D
47%D \startfacingfloat[whatever]
48%D     \startcontent \dorecurse{10}{\samplefile{tufte} } \stopcontent
49%D     \startcontent \dorecurse{10}{\samplefile{ward}  } \stopcontent
50%D     \startcontent \dorecurse{10}{\samplefile{tufte} } \stopcontent
51%D     \startcontent \dorecurse{10}{\samplefile{ward}  } \stopcontent
52%D \stopfacingfloat
53%D
54%D \flushfacingfloats[whatever]
55%D
56%D \dorecurse{10}{\samplefile{sapolsky} }
57%D
58%D \flushpendingtopcontent
59%D
60%D \stoptyping
61%D
62%D The idea is to flush related floats more or less in parallel.
63
64\unprotect
65
66%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67
68% \starttext
69%
70% \registertopcontent[3]\vbox{\framed[align=normal,width=\textwidth]{\samplefile{ward}}}
71% \registertopcontent[3]\vbox{\framed[align=normal,width=\textwidth]{\samplefile{davis}}}
72% \registertopcontent[5]\vbox{\framed[align=normal,width=\textwidth]{\samplefile{ward}}}
73%
74% \dorecurse{20}{\samplefile{tufte}\par}
75%
76% \stoptext
77
78\newdimension\d_page_adapts_preroll
79\newinteger  \c_page_adapts_pushed
80
81% this assumes a constant textheight and no adaptations otherwise so we
82% should block these for already set pages in adaptheight .. or we can
83% make these independent (so not use adaptheight)
84
85\def\page_adapts_layout_preroll#1%
86  {\begingroup
87   \global\d_page_adapts_preroll\zeropoint
88   \def\page_adapts_layout_indeed##1%
89     {\setupcurrentadaptlayout[\c!top=\zeropoint,##1]%
90      \global\d_page_adapts_preroll{\adaptlayoutparameter\c!top}}
91   \begincsname\??pageadaptations\number#1\endcsname
92   \endgroup}
93
94\permanent\protected\def\registertopcontent[#1]%
95  {\begingroup
96   \dowithnextbox
97     {\page_adapts_layout_preroll{#1}%
98      \scratchdimen{%
99        \htdp\nextbox+\d_page_adapts_preroll
100        \ifzeropt\d_page_adapts_preroll
101          +\lineheight
102        \fi
103      }%
104      \putboxincache{\v!page:\number#1}{+}\nextbox
105      \normalexpanded{\adaptlayout[\number#1][\c!top=\the\scratchdimen]}%
106      \global\advanceby\c_page_adapts_pushed\plusone
107      \endgroup}}
108
109\def\page_otr_flush_top_content
110  {\scratchcounter\getboxcountfromcache{\v!page:\the\realpageno}\relax
111   \ifcase\scratchcounter\else
112      \dorecurse\scratchcounter
113        {\directboxfromcache{\v!page:\the\realpageno}\recurselevel
114         \nointerlineskip
115         \par}%
116      \disposeboxesincache{\v!page:\the\realpageno}%
117      \global\advanceby\c_page_adapts_pushed\minusone
118      \nointerlineskip
119   \fi}
120\def\page_otr_flush_top_content{}
121
122\permanent\protected\def\flushpendingtopcontent
123  {\ifcase\c_page_adapts_pushed\else
124     \null
125     \page
126     \expandafter\flushpendingtopcontent
127  \fi}
128
129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130
131% \let\page_check_weird_page\relax
132
133\def\page_check_weird_page_indeed % for now only when facing floats
134  {\ifdim\vsize>\zeropoint\else
135      %\showmessage\m!layouts9{}%
136      \writestatus\m!layouts{forcing zero height page}%
137      \emptyhbox\page
138   \fi}
139
140%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141
142% width:
143%
144% -- fit       : do nothing
145% -- dimension : use that
146% -- frame     : use hsize minus frame offsets (based on preroll)
147
148\installcorenamespace {facingfloat}
149
150\installframedcommandhandler \??facingfloat {facingfloat} \??facingfloat
151
152\setupfacingfloat
153  [\c!spaceinbetween=\v!big,
154   \c!inbetween={\blank[\v!big]},
155  %\c!page=\v!left, % not used
156  %\c!style,
157  %\c!color,
158   \c!width=\v!fit]
159
160\newinteger\c_defining_facing_float
161
162\appendtoks
163  \advanceby\c_defining_facing_float\plusone
164  \ifcase\c_defining_facing_float\or
165      \normalexpanded{
166        \definefacingfloat[\currentfacingfloat:\v!left ][\currentfacingfloat]%
167        \definefacingfloat[\currentfacingfloat:\v!right][\currentfacingfloat]%
168      }%
169    \fi
170  \advanceby\c_defining_facing_float\minusone
171\to \everydefinefacingfloat
172
173\newinteger\c_strc_floats_facing_saved
174\newinteger\c_strc_floats_facing_flushed
175\newbox    \b_strc_floats_facing_l
176\newbox    \b_strc_floats_facing_r
177
178\let\m_strc_floats_state\relax
179
180\installcorenamespace {facingfloatflusher}
181
182\def\strc_floats_facing_flush_indeed_step#1#2#3%
183  {\ifnum#2<#3\relax
184     \advanceby#2\plusone
185     \donetrue
186     \writestatus
187       {facing}
188       {page: \the\scratchcounterone, location: #1, blob: \the#2, max: \the#3}%
189     \registertopcontent
190       [\scratchcounterone]
191       \hbox{\directboxfromcache{\currentfacingfloat:#1}{\the#2}}%
192   \fi}
193
194\def\strc_floats_facing_flush_indeed#1%
195  {\begingroup
196   \cdef\currentfacingfloat{#1}%
197   \glet\page_check_weird_page\page_check_weird_page_indeed % for now only when facing floats
198   \scratchcounterone  \realpageno
199   \scratchcounterthree\getboxcountfromcache{\currentfacingfloat:\v!left }\relax
200   \scratchcounterfour \getboxcountfromcache{\currentfacingfloat:\v!right}\relax
201   \scratchcounterfive \zerocount
202   \scratchcountersix  \zerocount
203   % find first empty spread i.e. odd (left) and even (right) empty
204   \ifdim\pagetotal>\zeropoint
205     \advanceby\scratchcounterone\plusone
206   \fi
207   \ifodd\scratchcounterone
208     \advanceby\scratchcounterone\plusone
209   \fi
210   \writestatus
211     {facing}
212     {page: \the\scratchcounterone, start checking}%
213   \doloop{%
214       \page_adapts_layout_preroll\scratchcounterone
215       \ifzeropt\d_page_adapts_preroll
216         % left empty
217         \advanceby\scratchcounterone\plusone
218         \page_adapts_layout_preroll\scratchcounterone
219         \ifzeropt\d_page_adapts_preroll
220           % right empty
221           \advanceby\scratchcounterone\minusone
222           \exitloop
223         \fi
224       \else
225         \advanceby\scratchcounterone\plustwo
226       \fi
227   }
228   \writestatus
229     {facing}
230     {page: \the\scratchcounterone, start flushing}%
231   \doloop{%
232     \ifodd\scratchcounterone
233       \strc_floats_facing_flush_indeed_step\v!right\scratchcountersix \scratchcounterfour
234     \else
235       \strc_floats_facing_flush_indeed_step\v!left \scratchcounterfive\scratchcounterthree
236     \fi
237     \ifnum\scratchcountersix<\scratchcounterfour
238        % more
239     \orelse\ifnum\scratchcounterfive<\scratchcounterthree
240        % more
241     \else
242       \exitloop
243     \fi
244     \advanceby\scratchcounterone\plusone
245   }
246   \disposeboxesincache{\currentfacingfloat:\v!right}%
247   \disposeboxesincache{\currentfacingfloat:\v!left}%
248   \page_check_weird_page_indeed
249   \endgroup}
250
251\permanent\protected\tolerant\def\flushfacingfloats[#1]%
252  {\processcommalist[#1]\strc_floats_facing_flush_indeed}
253
254\protected\def\strc_floats_facing_setup
255  {\cdef\currentfacingfloat{\currentfacingfloat:\m_strc_floats_state}%
256   \usefacingfloatstyleandcolor\c!style\v!color}
257
258\protected\def\strc_floats_facing_collect
259  {\ifx\m_strc_floats_state\v!left
260     \ifvoid\nextbox\orelse\ifzeropt\wd\nextbox\else
261       \ifvoid\b_strc_floats_facing_l
262         \setbox\b_strc_floats_facing_l\box\nextbox
263       \else
264         \setbox\b_strc_floats_facing_l\vbox\bgroup
265           \unvbox\b_strc_floats_facing_l
266           \facingfloatparameter\c!inbetween
267           \unvbox\nextbox
268         \egroup
269       \fi
270     \fi
271     \let\m_strc_floats_state\v!right
272   \orelse\ifx\m_strc_floats_state\v!right
273     \ifvoid\nextbox\orelse\ifzeropt\wd\nextbox\else
274       \ifvoid\b_strc_floats_facing_r
275         \setbox\b_strc_floats_facing_r\box\nextbox
276       \else
277         \setbox\b_strc_floats_facing_r\vbox\bgroup
278           \unvbox\b_strc_floats_facing_r
279           \facingfloatparameter\c!inbetween
280           \unvbox\nextbox
281         \egroup
282       \fi
283     \fi
284     \let\m_strc_floats_state\v!left
285   \else
286     \let\m_strc_floats_state\v!left
287   \fi}
288
289\protected\def\strc_floats_facing_handle
290  {\doifnextbgroupelse
291     \strc_floats_facing_handle_indeed
292     \strc_floats_facing_wrap_up}
293
294\protected\def\strc_floats_facing_handle_indeed
295  {\dowithnextboxcontent
296     \strc_floats_facing_setup
297     {\strc_floats_facing_collect\strc_floats_facing_handle}
298     \vbox}
299
300\permanent\protected\def\startfacingfloat[#1]%
301  {\begingroup
302   \cdef\currentfacingfloat{#1}%
303   \edef\p_width{\facingfloatparameter\c!width}%
304   \letfacingfloatparameter\c!width\v!fit
305   \ifx\p_width\v!frame
306      \setbox\scratchbox\hpack{\inheritedfacingfloatframed{}}%
307      \advanceby\hsize-\wd\scratchbox
308   \orelse\ifx\p_width\v!fit
309      % whatever
310   \else
311      \hsize\p_width
312   \fi
313   \enforced\let\startcontent\bgroup
314   \enforced\let\stopcontent\egroup
315   \let\m_strc_floats_state\v!left
316   \strc_floats_facing_handle}
317
318\permanent\protected\def\stopfacingfloat
319  {\endgroup}
320
321\protected\def\strc_floats_facing_wrap_up
322  {\edef\p_spaceinbetween{\facingfloatparameter\c!spaceinbetween}%
323   \ifempty\p_spaceinbetween
324     \scratchdimen\zeropoint
325   \else
326     \setbox\scratchbox\vbox{\directvspacing\p_spaceinbetween}%
327     \scratchdimen\htdp\scratchbox
328   \fi
329   \ifvoid\b_strc_floats_facing_l\else
330     \page_postprocessors_linenumbers_box\b_strc_floats_facing_l
331   \fi
332   \ifvoid\b_strc_floats_facing_r\else
333     \page_postprocessors_linenumbers_box\b_strc_floats_facing_r
334   \fi
335   \doloop{%
336     \strc_floats_facing_flush_wrap\b_strc_floats_facing_l\v!left
337     \strc_floats_facing_flush_wrap\b_strc_floats_facing_r\v!right
338     \global\advanceby\c_strc_floats_facing_saved\plusone
339     \ifvoid\b_strc_floats_facing_l\relax\ifvoid\b_strc_floats_facing_r\relax
340       \exitloop
341     \fi\fi}}
342
343\def\strc_floats_facing_flush_wrap#1#2%
344  {\ifvoid#1\relax
345     % todo
346   \else
347     \begingroup
348     \setbox\scratchboxone\hpack\bgroup
349       \cdef\currentfacingfloat{\currentfacingfloat:#2}%
350       \inheritedfacingfloatframed{\strut}%
351     \egroup
352     \scratchdimenone{\textheight-\htdp\scratchboxone+\lineheight}%
353     \dontcomplain
354     \splittopskip\zeroskip
355     \setbox\scratchbox\vsplit#1 upto \scratchdimenone
356     \setsplitlisthtdp\scratchbox\strutht\strutdp
357     \setbox\scratchbox\hpack\bgroup
358       \cdef\currentfacingfloat{\currentfacingfloat:#2}%
359       \inheritedfacingfloatframed{\box\scratchbox}%
360     \egroup
361     \setbox\scratchbox\vbox
362       \ifdim\ht\scratchbox<{\textheight-\scratchdimen}%
363         {\box\scratchbox\directvspacing\p_spaceinbetween}%
364       \else
365         to \textheight{\box\scratchbox\vss}%
366       \fi
367     \putboxincache{\currentfacingfloat:#2}{+}\scratchbox
368     \endgroup
369   \fi}
370
371\protect \endinput
372