page-pcl.mkxl /size: 32 Kb    last modification: 2024-01-16 09:03
1%D \module
2%D   [       file=page-pcl,
3%D        version=2017.11.08,
4%D          title=\CONTEXT\ Page Macros,
5%D       subtitle=Page Columns,
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 / Page Columns}
15
16%D This is very experimental code! We took a bit from the mixed columns and single
17%D column page code. This one works acceptable with floats and is for whole double
18%D column documents. We don't balance (yet). Footnotes are per column. One can have
19%D side floats too. No balancing and other fancy features.
20%D
21%D Don't use this in production! Although the main approach will stay there might be
22%D changes in the way floats are dealt with. Not much testing has been done but as
23%D we stay close to the single column mode we expect most to just work. Only floats
24%D are the (usual) pain. Backgrounds, line numbering, etc.\ not tested either.
25
26\unprotect
27
28\definemeasure[onecolumn]   [\columnwidth]
29\definemeasure[twocolumns]  [\dimexpr\plustwo  \columnwidth+          \columndistance\relax]
30\definemeasure[threecolumns][\dimexpr\plusthree\columnwidth+\plustwo  \columndistance\relax]
31\definemeasure[fourcolumns] [\dimexpr\plusfour \columnwidth+\plusthree\columndistance\relax]
32
33\newinteger    \c_page_col_n_of_columns \c_page_col_n_of_columns\plusone
34\newinteger    \c_page_col_current      \c_page_col_current     \plusone
35\newdimension  \d_page_col_distance
36\newdimension  \d_page_col_max_height
37\newdimension  \d_page_col_max_width
38%newdimension  \d_page_col_balance_step
39\newdimension  \d_page_col_column_width
40\newdimension  \d_page_col_top_height
41\newdimension  \d_page_col_top_width
42\newdimension  \d_page_col_available
43\newdimension  \d_page_col_sofar
44\newconditional\c_page_col_page
45
46%D We need to step over empty columns.
47
48\protected\def\page_col_command_next_page
49  {\page_col_eject_page}
50
51\permanent\protected\def\page_col_column
52  {\page_otr_eject_page}
53
54\protected\def\page_col_eject_page
55  {\begingroup
56   \scratchcountertwo  \realpageno
57   \page_otr_eject_page
58   \scratchcounterone  \c_page_col_current
59   \scratchcounterthree\zerocount
60   \doloop{%
61     \ifnum\scratchcounterthree>\plushundred
62       % too many attempts
63       \exitloop
64     \orelse\ifnum\realpageno>\scratchcountertwo
65       % we advanced at least one page so we're done
66       \exitloop
67     \else
68       \ifnum\scratchcounterone=\c_page_col_current
69          \dontleavehmode\null
70       \fi
71       \page_otr_eject_page
72       \scratchcounterone\c_page_col_current
73       \advanceby\scratchcounterthree\plusone
74     \fi
75   }%
76   \endgroup}
77
78%D \unknown
79
80\protected\def\page_col_command_next_page_and_inserts
81  {\page_otr_eject_page_and_flush_inserts}
82
83%D \unknown
84
85\protected\def\page_col_command_set_hsize
86  {\global\hsize\d_page_col_column_width\relax
87   \global\d_page_col_available\dimexpr
88      \numexpr\c_page_col_n_of_columns-\c_page_col_current+\plusone\relax\d_page_col_column_width
89    + \numexpr\c_page_col_n_of_columns-\c_page_col_current         \relax\d_page_col_distance
90   \relax
91   \global\d_page_col_sofar
92   \ifnum\c_page_col_n_of_columns=\plusone
93     \zeropoint
94   \else
95     \numexpr\c_page_col_n_of_columns-\plusone\relax
96     \dimexpr\d_page_col_column_width+\d_page_col_distance\relax
97   \fi
98   % consistent with mixed:
99   \textwidth\d_page_col_column_width}
100
101%D \unknown
102
103\def\page_col_registered_text_area_b#1%
104  {\begingroup
105   \makeupwidth\d_page_col_column_width
106   \page_one_registered_text_area_b{#1}%
107   \endgroup}
108
109\protected\def\page_col_command_package_contents#1#2% \box<n> \unvbox<n> % this one will be redone (checked)
110  {\bgroup
111   \setbox\b_page_one_contents\vbox to \textheight
112     {\page_one_registered_text_area_a#1#2}%
113   \page_one_command_package_show_state
114   \ht\b_page_one_contents\textheight
115   \page_col_registered_text_area_b
116     {\box\b_page_one_contents}%
117   \egroup}
118
119\protected\def\page_col_command_package_contents_one#1#2% \box<n> \unvbox<n> % this one will be redone (checked)
120  {\bgroup
121     \forgetall
122     % see one for comments as it is similar
123     \strc_notes_check_if_bottom_present
124     \d_page_one_natural_depth\dp#2\relax
125%      \page_layouts_check_stretch#2%
126     \setbox\b_page_one_contents\vbox to \textheight
127       {\page_col_command_flush_top_insertions
128        \page_one_registered_text_area_a#1#2%
129        \hsize\d_page_col_column_width
130        \ifgridsnapping
131          \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax
132          \prevdepth\openstrutdepth
133          \page_col_command_flush_bottom_insertions
134          \vfil
135        \orelse\ifcase\bottomraggednessmode
136          % ragged (default)
137          \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax
138          \prevdepth\openstrutdepth
139          \page_col_command_flush_bottom_insertions
140          \vfil
141        \or
142          % align (normal)
143          \page_col_command_flush_bottom_insertions
144        \or
145          % baseline
146          \vkern\dimexpr\maxdepth-\d_page_one_natural_depth\relax
147          \page_col_command_flush_bottom_insertions
148        \or
149          % depth
150          \vskip-\d_page_one_natural_depth
151          \page_col_command_flush_bottom_insertions
152        \fi
153        \fakepagenotes}%
154     \page_layouts_check_stretch\b_page_one_contents
155     \page_one_command_package_show_state
156     \ifconditional\c_notes_bottom_present
157       \ifgridsnapping
158         \ifcase\layoutlines
159           \getrawnoflines\textheight
160         \else
161           \noflines\layoutlines
162         \fi
163         \scratchoffset\dimexpr\numexpr\noflines-\plusone\relax\lineheight+\topskip\relax
164       \else
165         \scratchoffset\ht\b_page_one_contents
166       \fi
167       \setbox\b_page_one_bottom_notes\hpack
168         {\hsize\d_page_col_column_width
169          \setupnotes[\c!width=\textwidth]%
170          \lower\dimexpr\scratchoffset-\initialpageskip\relax % watch the initialpageskip
171          \vbox{\placebottomnotes\par\kern\zeropoint}}%
172       \ht\b_page_one_contents    \zeropoint
173       \wd\b_page_one_contents    \zeropoint
174       \ht\b_page_one_bottom_notes\zeropoint
175       \wd\b_page_one_bottom_notes\d_page_col_column_width
176       \page_col_registered_text_area_b
177         {\vpack to \textheight
178            {\hpack{\box\b_page_one_contents\box\b_page_one_bottom_notes}}}%
179     \else
180       \ifcase\c_page_scale_lines
181         % nothing to do: vz not enabled
182       \orelse\ifdim\d_page_box_stretch_delta>\zeropoint
183         \page_scale_text_box_register_box\b_page_one_contents
184         \page_scale_text_box\b_page_one_contents
185       \else
186         \page_scale_text_box_register_page
187         \page_scale_text_box\b_page_one_contents
188       \fi
189       \ht\b_page_one_contents\textheight
190       \wd\b_page_one_contents\d_page_col_column_width
191       \page_col_registered_text_area_b
192         {\box\b_page_one_contents}%
193     \fi
194   \egroup}
195
196%D \unknown
197
198\protected\def\page_col_command_side_float_output
199  {% % %
200   \ifzeropt\page_inserts_get_height\namedinsertionnumber\s!topfloat\else
201     \scratchwidth\page_inserts_get_width\namedinsertionnumber\s!topfloat\relax
202     \ifdim\scratchwidth>\d_page_col_top_width
203       \global\d_page_col_top_width \scratchwidth
204     \fi
205     \global\d_page_col_top_height\page_inserts_get_height\namedinsertionnumber\s!topfloat\relax
206   \fi
207   % % %
208   \setbox\scratchbox\vbox\bgroup
209      \page_col_command_package_contents_one\unvbox\normalpagebox
210   \egroup
211   \putboxincache\s!pagecolumn{\the\c_page_col_current}\scratchbox
212   \ifnum\c_page_col_current=\c_page_col_n_of_columns
213     \page_col_routine_package
214     \page_otr_construct_and_shipout\box\normalpagebox\plusone
215     \global\c_page_col_current\plusone
216     \global\d_page_col_top_height\zeropoint
217     \global\d_page_col_top_width\zeropoint
218   % \page_col_command_flush_top_insertions
219   % \page_col_command_flush_floats
220   \else
221     \ifdim\d_page_col_top_width>\zeropoint
222       \ifdim\dimexpr\d_page_col_top_width>\d_page_col_sofar\relax
223         \begingroup
224         \floatingpenalty\zerocount
225         \page_inserts_inject\namedinsertionnumber\s!topfloat\bgroup
226           \vbox to \d_page_col_top_height{\vss}%
227             % can be an option
228             \page_col_command_flush_top_insertions
229             \page_col_command_flush_floats
230             % so far till option
231           \egroup
232         \endgroup
233       \fi
234     \fi
235     \global\advanceby\c_page_col_current\plusone
236   \fi
237   %
238   \page_col_notes_synchronize
239   %
240   \page_col_command_set_vsize
241   \page_col_command_set_hsize}
242
243% use \currentmixedcolumns instead of \recurselevel
244
245\def\page_col_routine_package
246  {\global\setbox\normalpagebox\hbox to \makeupwidth\bgroup
247     \edef\p_separator{\pagecolumnsparameter\c!separator}%
248     \pagecolumnseparatorwidth\d_page_col_distance
249     \ifcstok{\pagecolumnsparameter\c!direction}\v!reverse
250       \localcontrolledloop\c_page_col_n_of_columns\plusone\minusone
251         {\mofcolumns\currentloopiterator
252          \page_col_routine_package_step
253          \ifnum\mofcolumns>\plusone
254            \page_col_routine_package_separate
255          \fi}%
256     \else
257       \localcontrolledloop\plusone\c_page_col_n_of_columns\plusone
258         {\mofcolumns\currentloopiterator
259          \page_col_routine_package_step
260          \ifnum\mofcolumns<\c_page_col_n_of_columns
261            \page_col_routine_package_separate
262          \fi}%
263     \fi
264   \egroup
265   \resetboxesincache{\s!pagecolumn\s!pagecolumn}%
266   \resetboxesincache{\s!pagecolumn}%
267   \global\initialpageskip\zeroskip
268   \global\initialtopskip \zeroskip}
269
270\def\page_col_routine_package_step
271  {% needs packaging anyway
272    \getboxfromcache{\s!pagecolumn\s!pagecolumn}{\number\mofcolumns}\scratchboxone
273    \getboxfromcache{\s!pagecolumn}{\number\mofcolumns}\scratchboxtwo
274   %\ht\scratchbox\dimexpr\ht\scratchboxtwo-\initialpageskip\relax
275    \ht\scratchboxtwo\dimexpr\ht\scratchboxtwo-\ht\scratchboxone\relax
276    \page_lines_add_numbers_to_box\scratchbox\mofcolumns\c_page_col_n_of_columns\plusone % new
277    \page_marks_synchronize_column\plusone\c_page_col_n_of_columns\mofcolumns\scratchboxtwo
278    % backgrounds
279    \anch_mark_column_box\scratchboxtwo\mofcolumns
280    \pagecolumnseparatorheight\ht\scratchboxtwo
281    \pagecolumnseparatordepth \dp\scratchboxtwo
282    \vpack\bgroup
283      \box\scratchboxone
284      \nointerlineskip\par
285      \inheritedpagecolumnsframedbox\mofcolumns\scratchboxtwo
286   \egroup}
287
288%D \unknown
289
290\protected\def\page_col_command_check_if_float_fits
291  {\ifconditional\c_page_floats_not_permitted
292     % forget about it anyway
293     \global\c_page_floats_room\conditionalfalse
294   \else
295     % first we check the current column
296%      \ifdim\dimexpr\d_page_col_width-\naturalfloatwd\relax>-\onepoint
297     \ifdim\dimexpr\hsize-\naturalfloatwd\relax>-\onepoint
298       \global\c_page_floats_room\conditionaltrue
299     \else
300       \global\c_page_floats_room\conditionalfalse
301     \fi
302     \ifconditional\c_page_floats_room
303       % we fit in the column but do we have room
304       \ifdim\dimexpr\pagetotal+\lineheight\relax>\pagegoal
305         % try again later
306         \goodbreak
307       \fi
308       \ifdim\pagetotal>\zeropoint
309         \scratchdimenone\dimexpr\pagetotal+\floatheight+\d_strc_floats_top-\pageshrink\relax
310         \scratchdimentwo\pagegoal
311         \relax % needed
312         \ifcase\c_page_one_float_method
313           % method 0 : raw
314         \or
315           % method 1 : safe
316           \advanceby\scratchdimentwo -\strutdp
317         \or
318           % method 2 : tight
319           \advanceby\scratchdimenone -\onepoint
320         \fi
321         \relax % really needed ! ! ! !
322         \ifdim\scratchdimenone>\scratchdimentwo
323           % there is no room, give up
324           \global\c_page_floats_room\conditionalfalse
325           % now we can decide on a top float
326%          \fi
327         \else
328%            \ifconditional\c_page_floats_room
329%              \global\setbox\floatbox\hpack to \d_page_col_float_available{\hss\box\floatbox\hss}%
330%            \fi
331         \fi
332       \fi
333     \fi
334   \fi}
335
336%D \unknown
337
338\def\page_col_set_float_pack_hsize
339  {\ifnum\c_page_col_current=\c_page_col_n_of_columns
340     \c_page_col_current\plusone
341   \else
342     \advanceby\c_page_col_current\plusone
343   \fi
344   \page_col_command_set_hsize
345   \hsize\d_page_col_available}
346
347\protected\def\page_col_command_flush_floats
348  {\global\c_page_floats_flushing\conditionaltrue
349   \ifconditional\c_page_floats_some_waiting
350     \par
351     \page_col_set_float_pack_hsize
352     \page_col_command_flush_floats_indeed
353   \fi
354   \global\savednoffloats\zerocount
355   \global\c_page_floats_some_waiting\conditionalfalse
356   \global\c_page_floats_flushing\conditionalfalse}
357
358\def\page_floats_show_pack_state_indeed#1%
359  {\llap{\smash{\backgroundline[black]{\strut\smallinfofont\white#1\space\the\nofcollectedfloats\space of\space\the\savednoffloats:\the\hsize}}\hkern.25\emwidth}}
360
361\installtextracker
362  {floats.collecting}
363  {\let\page_floats_show_pack_state\page_floats_show_pack_state_indeed}
364  {\let\page_floats_show_pack_state\gobbleoneargument}
365
366\let\page_floats_show_pack_state\gobbleoneargument
367
368\def\page_col_command_flush_floats_indeed % much in common with OTRSET
369  {\ifconditional\c_page_floats_some_waiting
370     \ifconditional\c_page_floats_compress_flushed
371       \c_page_floats_center_box\conditionalfalse % not needed as we do call directly
372       \page_floats_collect\s!text\hsize\d_page_floats_compress_distance
373       %
374       \ifnum\nofcollectedfloats=\plusone
375         \ifdim\naturalfloatwd>\hsize
376           \nofcollectedfloats\zerocount
377         \fi
378       \fi
379       \ifnum\nofcollectedfloats>\zerocount
380         \global\setbox\floatbox\hpack to \hsize
381           {\page_floats_show_pack_state F%
382            \hfil
383            \dorecurse\nofcollectedfloats
384              {\ifcase\columndirection % nog document wide
385                 \page_floats_flush\s!text\plusone
386               \else
387                 \page_floats_flush\s!text{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}%
388               \fi
389               % this could happen at the lua end instead
390               \scratchdimen\dimexpr\wd\floatbox-\naturalfloatwd\relax
391               \ifdim\scratchdimen<\zeropoint
392                 \global\setbox\floatbox\hpack spread -\scratchdimen{\hss\box\floatbox\hss}%
393               \fi
394               %
395               \ifdim\wd\floatbox>\textwidth % \hsize
396                 \hpack to \textwidth{\hss\box\floatbox\hss}% \textwidth
397               \else
398                 \box\floatbox
399               \fi
400               \ifnum\recurselevel<\nofcollectedfloats
401                 \hfil
402               \fi}%
403            \hfil}%
404           \doplacefloatbox
405         % \page_one_insert_top_float
406           \doubleexpandafter\page_col_command_flush_floats_indeed
407       \else
408         % todo
409       \fi
410     \else
411       \page_floats_get
412     % \page_one_insert_top_float
413       \doplacefloatbox
414       \doubleexpandafter\page_col_command_flush_floats_indeed
415     \fi
416   \fi}
417
418\protected\def\page_col_command_flush_saved_floats % like one
419  {\global\d_page_floats_inserted_top\zeropoint
420   \global\d_page_floats_inserted_bottom\zeropoint
421   \ifconditional\c_page_floats_flushing \else
422     \page_col_command_set_top_insertions
423     \page_col_command_set_bottom_insertions
424     \ifconditional\c_page_floats_some_waiting
425        \ifcstok{\rootfloatparameter\c!cache}\v!no
426          \page_col_command_flush_floats % could be _otr_
427        \fi
428     \orelse\ifconditional\c_page_margin_blocks_present
429       \page_col_command_flush_floats
430     \fi
431   \fi}
432
433\protected\def\page_col_command_set_top_insertions
434  {\bgroup
435   \ifconditional\c_page_floats_some_waiting
436     \noffloatinserts\zerocount
437     \let\totaltopinserted\!!zeropoint
438     \page_col_set_float_pack_hsize
439     \page_col_command_set_top_insertions_indeed
440     \ifnum\rootfloatparameter\c!nbottom=\zerocount
441       \ifnum\rootfloatparameter\c!nlines>\zerocount
442         \ifdim\totaltopinserted>\zeropoint\relax
443           \ifdim\dimexpr\rootfloatparameter\c!nlines\lineheight+\totaltopinserted\relax>\textheight
444             \showmessage\m!floatblocks8{\rootfloatparameter\c!nlines}%
445             \page_otr_fill_and_eject_page % was tripple: vfilll
446           \fi
447         \fi
448       \fi
449     \fi
450   \fi
451   \egroup}
452
453\permanent\def\d_page_col_collected_top_float_height % pseudo
454  {\dimexpr
455     \d_page_floats_inserted_top +
456     \maxcollectedfloatstotal +
457     \ifdim\d_strc_floats_top>\d_strc_floats_bottom
458       \d_strc_floats_top
459     \else
460       \d_strc_floats_bottom
461     \fi
462   \relax}
463
464\def\page_col_command_set_top_insertions_indeed
465  {\ifnum\noffloatinserts<\c_page_floats_n_of_top
466     \ifcase\savednoffloats
467       \let\page_col_command_set_top_insertions_indeed\relax
468     \else
469       \page_floats_collect\s!text\hsize\emwidth
470       \ifdim\d_page_col_collected_top_float_height<\textheight
471         \global\setbox\floatbox\hpack to \hsize
472           {\page_floats_show_pack_state T%
473            \hfil
474            \dorecurse\nofcollectedfloats
475              {\ifcase\columndirection % nog document wide
476                 \page_floats_flush\s!text\plusone
477               \else
478                 \page_floats_flush\s!text{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}%
479               \fi
480               % this could happen at the lua end instead
481               \scratchdimen\dimexpr\wd\floatbox-\naturalfloatwd\relax
482               \ifdim\scratchdimen<\zeropoint
483                   \global\setbox\floatbox\hpack spread -\scratchdimen{\hss\box\floatbox\hss}%
484               \fi
485               %
486               \ifdim\wd\floatbox>\makeupwidth % \hsize
487                 \hpack to \makeupwidth{\hss\box\floatbox\hss}%
488               \else
489                 \box\floatbox
490               \fi
491               \ifnum\recurselevel<\nofcollectedfloats
492                 \hfil
493               \fi}%
494            \hfil}%
495         \page_one_prepare_top_float
496         \xdef\totaltopinserted{\the\d_page_floats_inserted_top}%
497         \page_one_insert_top_float
498         \ifconditional\c_page_floats_some_waiting
499           \advanceby\noffloatinserts \plusone
500         \else
501           \noffloatinserts\c_page_floats_n_of_top\relax
502         \fi
503         \page_floats_report_flushed
504      \else
505         \let\page_col_command_set_top_insertions_indeed\relax
506       \fi
507     \fi
508   \else
509     \ifconditional\c_page_floats_some_waiting
510       \showmessage\m!floatblocks6{\the\c_page_floats_n_of_top}%
511     \fi
512     \let\page_col_command_set_top_insertions_indeed\relax
513   \fi
514   \page_col_command_set_top_insertions_indeed}
515
516\let\page_col_command_flush_top_insertions   \page_one_command_flush_top_insertions
517\let\page_col_command_flush_bottom_insertions\page_one_command_flush_bottom_insertions
518
519\let\page_col_command_set_bottom_insertions  \page_one_command_set_bottom_insertions
520
521\let\page_col_command_flush_float_box        \page_one_command_flush_float_box
522\let\page_col_command_synchronize_side_floats\page_one_command_synchronize_side_floats
523\let\page_col_command_flush_side_floats      \page_one_command_flush_side_floats
524\let\page_col_command_flush_margin_blocks    \page_one_command_flush_margin_blocks
525\let\page_col_command_test_page              \page_one_command_test_page
526
527%D The separator code is more or less the same as mixed columns but we need
528%D to compensate for the top floats so we comment a bit for now.
529
530\newdimension\pagecolumnseparatorheight
531\newdimension\pagecolumnseparatordepth
532\newdimension\pagecolumnseparatorwidth
533
534% \installcorenamespace{pagecolumnsseparator}
535%
536% \protected\def\installpagecolumnseparator#1#2%
537%   {\setvalue{\??pagecolumnsseparator#1}{#2}}
538%
539% \installpagecolumnseparator\v!rule
540%   {\vrule
541%      \s!width \pagecolumnsparameter\c!rulethickness
542%      \s!height\pagecolumnseparatorheight
543%      \s!depth \pagecolumnseparatordepth
544%    \relax}
545%
546% \def\page_col_routine_package_separate
547%   {\ifcsname\??pagecolumnsseparator\p_separator\endcsname
548%      \page_col_command_inject_separator
549%    \else
550%      \hss
551%    \fi}
552%
553% \protected\def\page_col_command_inject_separator
554%   {\begingroup
555%    \setbox\scratchbox\hbox to \zeropoint \bgroup
556%      \hss
557%      \starttextproperties
558%      \usepagecolumnscolorparameter\c!rulecolor
559%      \begincsname\??pagecolumnsseparator\p_separator\endcsname % was \c!rule
560%      \stoptextproperties
561%      \hss
562%    \egroup
563%    \ht\scratchbox\zeropoint
564%    \dp\scratchbox\zeropoint
565%    \hss
566%    \box\scratchbox
567%    \hss
568%    \endgroup}
569
570\def\page_col_routine_package_separate
571  {\hss}
572
573%D \unknown
574
575\protected\def\page_col_command_routine
576  {\page_sides_output_routine}
577
578% % not:
579%
580% \protected\def\page_col_command_routine
581%   {\ifconditional\c_page_sides_short
582%      \page_sides_output_routine_yes_column
583%    \else
584%      \page_sides_output_routine_nop_column
585%    \fi}
586%
587% \let\page_sides_output_routine_nop_column\page_sides_output_routine
588%
589% \def\page_sides_output_routine_yes_column % this might become the main one too
590%   {\unvbox\normalpagebox % bah, and the discards?
591%   %\page_col_column
592%    \column % \page
593%    % why was this \global\holdinginserts\zerocount
594%    \global\c_page_sides_short\conditionalfalse}
595
596\let\page_col_command_flush_all_floats\relax
597
598%D \unknown
599
600\defineoutputroutine
601  [\s!pagecolumn]
602  [\s!page_otr_command_routine                =\page_col_command_routine,
603   \s!page_otr_command_package_contents       =\page_col_command_package_contents,
604   \s!page_otr_command_set_vsize              =\page_col_command_set_vsize,
605   \s!page_otr_command_set_hsize              =\page_col_command_set_hsize,
606 % \s!page_otr_command_synchronize_hsize      =\page_col_command_synchronize_hsize, % not done
607   \s!page_otr_command_next_page              =\page_col_command_next_page,
608   \s!page_otr_command_next_page_and_inserts  =\page_col_command_next_page_and_inserts,
609   \s!page_otr_command_set_top_insertions     =\page_col_command_set_top_insertions,
610   \s!page_otr_command_set_bottom_insertions  =\page_col_command_set_bottom_insertions,
611   \s!page_otr_command_flush_top_insertions   =\page_col_command_flush_top_insertions,
612   \s!page_otr_command_flush_bottom_insertions=\page_col_command_flush_bottom_insertions,
613   \s!page_otr_command_check_if_float_fits    =\page_col_command_check_if_float_fits,
614 % \s!page_otr_command_set_float_hsize        =\page_col_command_set_float_hsize,   % not done
615   \s!page_otr_command_flush_float_box        =\page_col_command_flush_float_box,
616   \s!page_otr_command_side_float_output      =\page_col_command_side_float_output,
617   \s!page_otr_command_synchronize_side_floats=\page_col_command_synchronize_side_floats,
618   \s!page_otr_command_flush_floats           =\page_col_command_flush_floats,
619   \s!page_otr_command_flush_side_floats      =\page_col_command_flush_side_floats,
620   \s!page_otr_command_flush_saved_floats     =\page_col_command_flush_saved_floats,
621   \s!page_otr_command_flush_all_floats       =\page_col_command_flush_all_floats,
622   \s!page_otr_command_flush_margin_blocks    =\page_col_command_flush_margin_blocks,
623   \s!page_otr_command_test_column            =\page_col_command_test_page
624  ]
625
626%D \unknown
627
628\installfloatmethod \s!pagecolumn \v!here        \page_one_place_float_here
629\installfloatmethod \s!pagecolumn \v!force       \page_one_place_float_force
630\installfloatmethod \s!pagecolumn \v!left        \page_one_place_float_left
631\installfloatmethod \s!pagecolumn \v!right       \page_one_place_float_right
632\installfloatmethod \s!pagecolumn \v!text        \page_one_place_float_text
633\installfloatmethod \s!pagecolumn \v!top         \page_one_place_float_top
634\installfloatmethod \s!pagecolumn \v!bottom      \page_one_place_float_bottom
635\installfloatmethod \s!pagecolumn \v!auto        \page_one_place_float_auto
636\installfloatmethod \s!pagecolumn \v!margin      \page_one_place_float_margin
637\installfloatmethod \s!pagecolumn \v!opposite    \page_one_place_float_face
638\installfloatmethod \s!pagecolumn \v!page        \page_one_place_float_page
639\installfloatmethod \s!pagecolumn \v!leftpage    \page_one_place_float_leftpage
640\installfloatmethod \s!pagecolumn \v!rightpage   \page_one_place_float_rightpage
641\installfloatmethod \s!pagecolumn \v!inmargin    \page_one_place_float_inmargin
642\installfloatmethod \s!pagecolumn \v!inleft      \page_one_place_float_leftmargin
643\installfloatmethod \s!pagecolumn \v!inright     \page_one_place_float_rightmargin
644\installfloatmethod \s!pagecolumn \v!leftmargin  \page_one_place_float_leftmargin
645\installfloatmethod \s!pagecolumn \v!rightmargin \page_one_place_float_rightmargin
646\installfloatmethod \s!pagecolumn \v!leftedge    \page_one_place_float_leftedge
647\installfloatmethod \s!pagecolumn \v!rightedge   \page_one_place_float_rightedge
648\installfloatmethod \s!pagecolumn \v!somewhere   \page_one_place_float_somewhere
649\installfloatmethod \s!pagecolumn \v!backspace   \page_one_place_float_backspace
650\installfloatmethod \s!pagecolumn \v!cutspace    \page_one_place_float_cutspace
651%installfloatmethod \s!pagecolumn \s!tblr        \page_one_place_float_top
652%installfloatmethod \s!pagecolumn \s!lrtb        \page_one_place_float_top
653%installfloatmethod \s!pagecolumn \s!tbrl        \page_one_place_float_top
654%installfloatmethod \s!pagecolumn \s!fxtb        \page_one_place_float_top
655%installfloatmethod \s!pagecolumn \s!rltb        \page_one_place_float_top
656%installfloatmethod \s!pagecolumn \s!btlr        \page_one_place_float_bottom
657%installfloatmethod \s!pagecolumn \s!lrbt        \page_one_place_float_bottom
658%installfloatmethod \s!pagecolumn \s!btrl        \page_one_place_float_bottom
659%installfloatmethod \s!pagecolumn \s!rlbt        \page_one_place_float_bottom
660%installfloatmethod \s!pagecolumn \s!fxbt        \page_one_place_float_bottom
661%installfloatmethod \s!pagecolumn \s!fixd        \page_one_place_float_force
662
663\installfloatmethod \s!pagecolumn \v!local       \somelocalfloat
664
665%D The main interface:
666
667\installcorenamespace{pagecolumns}
668
669\installframedcommandhandler \??pagecolumns {pagecolumns} \??pagecolumns
670
671\setuppagecolumns
672  [\c!distance=1.5\bodyfontsize,
673   \c!n=\plustwo,
674   \c!page=\v!yes,
675  %\c!align=, % inherit (also replaces tolerance)
676  %\c!before=,
677  %\c!after=,
678  %\c!separator=\v!none,
679  %\c!setups=,
680  %\c!balance=\v!no,
681  %\c!blank={\v!line,\v!fixed}, yes or no
682   \c!frame=\v!off,
683   \c!strut=\v!no,
684   \c!offset=\v!overlay,
685  %\c!maxheight=\textheight,
686   \c!maxwidth=\makeupwidth,
687  %\c!grid=\v!tolerant,
688  %\c!internalgrid=\v!line,
689   \c!direction=\v!normal]
690
691\appendtoks % could become an option
692    \frozen\instance\protected\edefcsname\e!start\currentpagecolumns\endcsname{\startpagecolumns[\currentpagecolumns]}%
693    \frozen\instance\protected\edefcsname\e!stop \currentpagecolumns\endcsname{\stoppagecolumns}%
694\to \everydefinepagecolumns
695
696\def\page_col_pickup_preceding
697  {\begingroup
698   \setupoutputroutine[\s!mixedcolumn]%
699   \c_page_mix_routine\c_page_mix_routine_intercept
700   \page_otr_trigger_output_routine
701   \ifvoid\b_page_mix_preceding \else
702     % moved here, before the packaging
703     \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding
704     % we need to avoid unvboxing with successive balanced on one page
705     \global\setbox\b_page_mix_preceding\vbox\bgroup
706       % yes or no: \forcestrutdepth
707       \unvbox\b_page_mix_preceding
708       \forcestrutdepth
709     \egroup
710     \wd\b_page_mix_preceding\makeupwidth
711     \global\d_page_mix_preceding_height\ht\b_page_mix_preceding
712   \fi
713   \endgroup}
714
715% Keep this one as original:
716%
717% \def\page_col_flush_preceding
718%   {\ifvoid\b_page_mix_preceding \else
719%      % this is just one method but ok for now
720%      \begingroup
721%      % we might need more but for now this is ok
722%      \setupfloat[\c!spacebefore=,\c!spaceafter=]%
723%      \startplacefigure[\c!location={\v!top,\v!none}]%
724%        \box\b_page_mix_preceding
725%      \stopplacefigure
726%      \endgroup
727%    \fi}
728
729\def\page_col_flush_preceding
730  {\ifvoid\b_page_mix_preceding \else
731     \scratchwidth \emwidth
732     \scratchheight\ht\b_page_mix_preceding
733     \scratchdepth \dp\b_page_mix_preceding
734     \global\initialpageskip\htdp\b_page_mix_preceding
735     \global\initialtopskip \strutht
736     % for the moment
737     \setbox\scratchbox\vbox\bgroup
738        \pagediscards
739     \egroup
740     \global\advanceby\initialtopskip \ht\scratchbox
741     % till here
742     \setbox\scratchbox\hbox to \zeropoint
743       \bgroup
744         \box\b_page_mix_preceding
745       \egroup
746     \putboxincache{\s!pagecolumn\s!pagecolumn}{\number\plusone}\scratchbox
747     \dostepwiserecurse\plustwo\c_page_col_n_of_columns\plusone
748       {\setbox\scratchbox\hbox to \zeropoint
749          \bgroup
750            \novrule
751              \s!width \scratchwidth
752              \s!height\scratchheight
753              \s!depth \scratchdepth
754            \hss
755          \egroup
756        \putboxincache{\s!pagecolumn\s!pagecolumn}{\recurselevel}\scratchbox}%
757   \fi}
758
759% \let\page_col_notes_initialize \relax
760% \let\page_col_notes_synchronize\relax
761% \let\page_col_notes_reset      \relax
762%
763% \protected\def\page_col_command_set_vsize % \page_one_command_set_vsize minus the pagegoal setting
764%   {\ifgridsnapping
765%      \ifcase\layoutlines
766%        \getrawnoflines\textheight
767%      \else
768%        \noflines\layoutlines
769%      \fi
770%      \global\vsize\noflines\openlineheight
771%    \else
772%      \global\vsize\textheight
773%    \fi}
774
775\newconditional\c_page_col_notes_lastcolumn
776
777\def\page_col_notes_synchronize
778  {\insertstoring\zerocount
779   \ifnum\c_page_col_current=\c_page_col_n_of_columns\relax
780     \strc_notes_process\page_col_notes_inject
781     \ifconditional\c_page_col_notes_lastcolumn
782       \insertstoring\plusone
783     \fi
784   \else
785     \strc_notes_process\page_col_notes_delay
786     \ifconditional\c_page_col_notes_lastcolumn
787       \insertstoring\plustwo
788     \fi
789   \fi}
790
791\def\page_col_notes_delay {\c_page_col_notes_lastcolumn\conditionalfalse\ifcstok{\noteparameter\c!location}\v!lastcolumn\c_page_col_notes_lastcolumn\conditionaltrue\insertstorage\currentnoteinsertionnumber\plusone  \fi}
792\def\page_col_notes_inject{\c_page_col_notes_lastcolumn\conditionalfalse\ifcstok{\noteparameter\c!location}\v!lastcolumn\c_page_col_notes_lastcolumn\conditionaltrue\insertstorage\currentnoteinsertionnumber\zerocount\fi}
793
794\def\page_col_notes_initialize {\insertstoring\zerocount\strc_notes_process\page_col_notes_delay}
795\def\page_col_notes_reset      {\insertstoring\zerocount\strc_notes_process\page_col_notes_inject}
796
797\protected\def\page_col_command_set_vsize % different !
798  {\page_one_command_set_vsize}
799
800\permanent\tolerant\protected\def\startpagecolumns[#S#1]%
801  {\begingroup
802   \begingroup
803   \ifhastok={#1}%
804     \lettonothing\currentpagecolumns
805     \setuppagecolumns[#1]%
806   \else
807     \cdef\currentpagecolumns{#1}%
808   \fi
809   \edef\p_page{\pagecolumnsparameter\c!page}%
810   \ifempty\p_page
811     \c_page_col_page\conditionalfalse
812   \orelse\ifx\p_page\v!no
813     \c_page_col_page\conditionalfalse
814   \else
815     \c_page_col_page\conditionaltrue
816     \page[\p_page]%
817   \fi
818   \c_page_col_n_of_columns\pagecolumnsparameter\c!n\relax
819   \ifnum\c_page_col_n_of_columns>\plusone
820     \expandafter\page_col_start_yes
821   \else
822     \expandafter\page_col_start_nop
823   \fi} % public
824
825\aliased\let\stoppagecolumns\relax
826
827\protected\def\page_col_start_yes
828  {\d_page_col_distance     \pagecolumnsparameter\c!distance\relax
829 % \d_page_col_max_height   \pagecolumnsparameter\c!maxheight
830   \d_page_col_max_width    \pagecolumnsparameter\c!maxwidth
831 % \d_page_col_balance_step \pagecolumnsparameter\c!step
832   \c_page_col_current  \plusone
833   %
834   \d_page_col_column_width\dimexpr(\d_page_col_max_width-\d_page_col_distance*\numexpr(\c_page_col_n_of_columns-\plusone)\relax)/\c_page_col_n_of_columns\relax
835   %
836   \columnwidth    \d_page_col_column_width
837   \columndistance \d_page_col_distance
838   \nofcolumns     \c_page_col_n_of_columns
839   \textwidth      \columnwidth % kind of redundant
840   %
841   \nopenalties
842   %
843   \global\initialpageskip\zeroskip
844   \global\initialtopskip \zeroskip
845   %
846   % \insidecolumnstrue % NO!
847   %
848   \enforced\let\column\page_col_column
849   %
850   \def\page_floats_get_used_hsize{\makeupwidth} % a bit of a hack
851   %
852   \usealignparameter  \pagecolumnsparameter
853   \useblankparameter  \pagecolumnsparameter
854 % \useprofileparameter\pagecolumnsparameter
855   %
856   \usepagecolumnscolorparameter\c!color
857   %
858   \setupnotes[\c!width=\textwidth]%
859   %
860   \usesetupsparameter\pagecolumnsparameter
861   %
862   % This will become a method but for now it's good enough
863   %
864   \ifconditional\c_page_col_page\else
865     \page_col_pickup_preceding
866   \fi
867   \setupoutputroutine[\s!pagecolumn]%
868   \ifconditional\c_page_col_page\else
869     \page_col_flush_preceding
870   \fi
871   %
872   \setupfloats[\c!ntop=\plusthousand]%
873 % \setupfloats[\c!nbottom=\plusthousand]%
874   %
875   \page_col_notes_initialize
876   %
877   \page_col_command_set_vsize
878   \page_col_command_set_hsize
879   %
880   \enforced\permanent\protected\def\startpagecolumns[##1]{\page_col_start_nop}%
881   %
882   \enforced\let\stoppagecolumns\page_col_stop_yes}
883
884\protected\def\page_col_start_nop
885  {\nofcolumns\c_page_mix_n_of_columns
886   \enforced\let\stoppagecolumns\page_col_stop_nop}
887
888\protected\def\page_col_stop_yes
889  {%\column % \page_otr_eject_page
890   \page    % beware for empty pages
891   \endgroup
892 % \setupoutputroutine[\s!singlecolumn]%
893   \global\initialpageskip\zeroskip
894   \global\initialtopskip \zeroskip
895   \page_otr_command_set_vsize
896   \page_otr_command_set_hsize
897   \page
898   \page_col_notes_reset
899   \endgroup}
900
901\protected\def\page_col_stop_nop
902  {\page
903   \endgroup
904   \endgroup}
905
906\protect \endinput
907