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