%D \module %D [ file=page-pcl, %D version=2017.11.08, %D title=\CONTEXT\ Page Macros, %D subtitle=Page Columns, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Page Macros / Page Columns} %D This is very experimental code! We took a bit from the mixed columns and single %D column page code. This one works acceptable with floats and is for whole double %D column documents. We don't balance (yet). Footnotes are per column. One can have %D side floats too. No balancing and other fancy features. %D %D Don't use this in production! Although the main approach will stay there might be %D changes in the way floats are dealt with. Not much testing has been done but as %D we stay close to the single column mode we expect most to just work. Only floats %D are the (usual) pain. Backgrounds, line numbering, etc.\ not tested either. \unprotect \definemeasure[onecolumn] [\columnwidth] \definemeasure[twocolumns] [\dimexpr\plustwo \columnwidth+ \columndistance\relax] \definemeasure[threecolumns][\dimexpr\plusthree\columnwidth+\plustwo \columndistance\relax] \definemeasure[fourcolumns] [\dimexpr\plusfour \columnwidth+\plusthree\columndistance\relax] \newcount \c_page_col_n_of_columns \c_page_col_n_of_columns\plusone \newcount \c_page_col_current \c_page_col_current \plusone \newdimen \d_page_col_distance \newdimen \d_page_col_max_height \newdimen \d_page_col_max_width %newdimen \d_page_col_balance_step \newdimen \d_page_col_column_width \newdimen \d_page_col_top_height \newdimen \d_page_col_top_width \newdimen \d_page_col_available \newdimen \d_page_col_sofar \newconditional\c_page_col_page %D We need to step over empty columns. \unexpanded\def\page_col_command_next_page {\page_col_eject_page} \unexpanded\def\page_col_column {\page_otr_eject_page} \unexpanded\def\page_col_eject_page {\begingroup \scratchcountertwo \realpageno \page_otr_eject_page \scratchcounterone \c_page_col_current \scratchcounterthree\zerocount \doloop{% \ifnum\scratchcounterthree>\plushundred % too many attempts \exitloop \else\ifnum\realpageno>\scratchcountertwo % we advanced at least one page so we're done \exitloop \else \ifnum\scratchcounterone=\c_page_col_current \dontleavehmode\null \fi \page_otr_eject_page \scratchcounterone\c_page_col_current \advance\scratchcounterthree\plusone \fi\fi }% \endgroup} %D \unknown \unexpanded\def\page_col_command_next_page_and_inserts {\page_otr_eject_page_and_flush_inserts} %D \unknown \unexpanded\def\page_col_command_set_hsize {\global\hsize\d_page_col_column_width\relax \global\d_page_col_available\dimexpr \numexpr\c_page_col_n_of_columns-\c_page_col_current+\plusone\relax\d_page_col_column_width + \numexpr\c_page_col_n_of_columns-\c_page_col_current \relax\d_page_col_distance \relax \global\d_page_col_sofar \ifnum\c_page_col_n_of_columns=\plusone \zeropoint \else \numexpr\c_page_col_n_of_columns-\plusone\relax \dimexpr\d_page_col_column_width+\d_page_col_distance\relax \fi} %D \unknown \unexpanded\def\page_col_command_set_vsize % \page_one_command_set_vsize minus the pagegoal setting {\ifgridsnapping \ifcase\layoutlines \getrawnoflines\textheight \else \noflines\layoutlines \fi \global\vsize\noflines\openlineheight \else \global\vsize\textheight \fi} %D \unknown \def\page_col_registered_text_area_b#1% {\begingroup \makeupwidth\d_page_col_column_width \page_one_registered_text_area_b{#1}% \endgroup} \unexpanded\def\page_col_command_package_contents#1#2% \box \unvbox % this one will be redone (checked) {\bgroup \setbox\b_page_one_contents\vbox to \textheight {\page_one_registered_text_area_a#1#2}% \page_one_command_package_show_state \ht\b_page_one_contents\textheight \page_col_registered_text_area_b {\box\b_page_one_contents}% \egroup} \unexpanded\def\page_col_command_package_contents_one#1#2% \box \unvbox % this one will be redone (checked) {\bgroup \forgetall % see one for comments as it is similar \strc_notes_check_if_bottom_present \d_page_one_natural_depth\dp#2\relax \setbox\b_page_one_contents\vbox to \textheight {\page_col_command_flush_top_insertions \page_one_registered_text_area_a#1#2% \hsize\d_page_col_column_width \ifgridsnapping \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax \prevdepth\openstrutdepth \page_col_command_flush_bottom_insertions \vfil \else\ifcase\bottomraggednessmode % ragged (default) \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax \prevdepth\openstrutdepth \page_col_command_flush_bottom_insertions \vfil \or % align (normal) \page_col_command_flush_bottom_insertions \or % baseline \kern\dimexpr\maxdepth-\d_page_one_natural_depth\relax \page_col_command_flush_bottom_insertions \fi\fi \fakepagenotes}% \page_one_command_package_show_state \ifconditional\c_notes_bottom_present \ifgridsnapping \ifcase\layoutlines \getrawnoflines\textheight \else \noflines\layoutlines \fi \scratchoffset\dimexpr\numexpr\noflines-\plusone\relax\lineheight+\topskip\relax \else \scratchoffset\ht\b_page_one_contents \fi \setbox\b_page_one_bottom_notes\hpack {\checksinglecolumnfootnotes % ? \hsize\d_page_col_column_width \setupnotes[\c!width=\textwidth]% \lower\scratchoffset\vbox{\placebottomnotes\par\kern\zeropoint}}% \ht\b_page_one_contents \zeropoint \wd\b_page_one_contents \zeropoint \ht\b_page_one_bottom_notes\zeropoint \wd\b_page_one_bottom_notes\zeropoint \wd\b_page_one_bottom_notes\d_page_col_column_width \page_col_registered_text_area_b {\vpack to \textheight {\hpack{\box\b_page_one_contents\box\b_page_one_bottom_notes}}}% \else \ht\b_page_one_contents\textheight \wd\b_page_one_contents\d_page_col_column_width \page_col_registered_text_area_b {\box\b_page_one_contents}% \fi \egroup} %D \unknown \unexpanded\def\page_col_command_side_float_output {% % % \ifvoid\namedinsertionnumber\s!topfloat\else \scratchwidth\wd\namedinsertionnumber\s!topfloat \ifdim\scratchwidth>\d_page_col_top_width \global\d_page_col_top_width \scratchwidth \fi \global\d_page_col_top_height\ht\namedinsertionnumber\s!topfloat \fi % % % \setbox\scratchbox\vbox\bgroup \page_col_command_package_contents_one\unvbox\normalpagebox \egroup \putboxincache\s!pagecolumn{\number\c_page_col_current}\scratchbox \ifnum\c_page_col_current=\c_page_col_n_of_columns \page_col_routine_package \page_otr_construct_and_shipout\box\normalpagebox\plusone \global\c_page_col_current\plusone \global\d_page_col_top_height\zeropoint \global\d_page_col_top_width\zeropoint % \page_col_command_flush_top_insertions % \page_col_command_flush_floats \else \ifdim\d_page_col_top_width>\zeropoint \ifdim\dimexpr\d_page_col_top_width>\d_page_col_sofar\relax \begingroup \floatingpenalty\zerocount \insert\namedinsertionnumber\s!topfloat\bgroup \vbox to \d_page_col_top_height{\vss} % can be an option \page_col_command_flush_top_insertions \page_col_command_flush_floats % so far till option \egroup \endgroup \fi \fi \global\advance\c_page_col_current\plusone \fi % \page_col_command_set_vsize \page_col_command_set_hsize} % use \currentmixedcolumns instead of \recurselevel \def\page_col_routine_package_step {% needs packaging anyway \getboxfromcache{\s!pagecolumn}{\number\recurselevel}\scratchbox \page_lines_add_numbers_to_box\scratchbox\recurselevel\c_page_col_n_of_columns\plusone % new \page_marks_synchronize_column\plusone\c_page_col_n_of_columns\recurselevel\scratchbox % backgrounds \anch_mark_column_box\scratchbox \mixedcolumnseparatorheight\ht\scratchbox \mixedcolumnseparatordepth \dp\scratchbox \inheritedpagecolumnsframedbox\recurselevel\scratchbox} \def\page_col_routine_package {\global\setbox\normalpagebox\hbox to \makeupwidth\bgroup \edef\p_separator{\pagecolumnsparameter\c!separator}% \pagecolumnseparatorwidth\d_page_col_distance \edef\p_direction{\pagecolumnsparameter\c!direction}% \ifx\p_direction\v!reverse \dostepwiserecurse\c_page_col_n_of_columns\plusone\minusone {\page_col_routine_package_step \ifnum\recurselevel>\plusone \page_col_routine_package_separate \fi}% \else \dorecurse\c_page_col_n_of_columns {\page_col_routine_package_step \ifnum\recurselevel<\c_page_col_n_of_columns \page_col_routine_package_separate \fi}% \fi \egroup \resetboxesincache{\s!pagecolumn}} %D \unknown % \unexpanded\def\page_col_command_check_if_float_fits % {\ifconditional\c_page_floats_not_permitted % \global\setfalse\c_page_floats_room % %\else\ifabsdim\dimexpr\d_page_col_available-\naturalfloatwd\relax<\onepoint % \else\ifdim\dimexpr\d_page_col_available-\naturalfloatwd\relax>-\onepoint % \global\settrue\c_page_floats_room % \else % \global\setfalse\c_page_floats_room % \fi\fi % \ifconditional\c_page_floats_room % \begingroup % \scratchdimen\dimexpr\pagetotal+\lineheight\relax % \ifdim\scratchdimen>\pagegoal % \goodbreak % \ifdim\dimexpr\d_page_col_available-\naturalfloatwd\relax>\onepoint % \global\setfalse\c_page_floats_room % \else % \global\settrue\c_page_floats_room % \fi % \fi % \endgroup % \fi % \ifconditional\c_page_floats_room % \ifdim\pagetotal>\zeropoint % \scratchdimenone\dimexpr\pagetotal+\floatheight+\d_strc_floats_top-\pageshrink\relax % \scratchdimentwo\pagegoal % \relax % needed % \ifcase\c_page_one_float_method % % method 0 : raw % \or % % method 1 : safe % \advance\scratchdimentwo -\strutdp % \or % % method 2 : tight % \advance\scratchdimenone -\onepoint % \fi % \relax % really needed ! ! ! ! % \ifdim\scratchdimenone>\scratchdimentwo % \global\setfalse\c_page_floats_room % \fi % \fi % \ifconditional\c_page_floats_room % \global\setbox\floatbox\hpack to \d_page_col_available{\hss\box\floatbox\hss}% % \fi % \fi} \unexpanded\def\page_col_command_check_if_float_fits {\ifconditional\c_page_floats_not_permitted % forget about it anyway \global\setfalse\c_page_floats_room \else % first we check the current column % \ifdim\dimexpr\d_page_col_width-\naturalfloatwd\relax>-\onepoint \ifdim\dimexpr\hsize-\naturalfloatwd\relax>-\onepoint \global\settrue\c_page_floats_room \else \global\setfalse\c_page_floats_room \fi \ifconditional\c_page_floats_room % we fit in the column but do we have room \ifdim\dimexpr\pagetotal+\lineheight\relax>\pagegoal % try again later \goodbreak \fi \ifdim\pagetotal>\zeropoint \scratchdimenone\dimexpr\pagetotal+\floatheight+\d_strc_floats_top-\pageshrink\relax \scratchdimentwo\pagegoal \relax % needed \ifcase\c_page_one_float_method % method 0 : raw \or % method 1 : safe \advance\scratchdimentwo -\strutdp \or % method 2 : tight \advance\scratchdimenone -\onepoint \fi \relax % really needed ! ! ! ! \ifdim\scratchdimenone>\scratchdimentwo % there is no room, give up \global\setfalse\c_page_floats_room % now we can decide on a top float % \fi \else % \ifconditional\c_page_floats_room % \global\setbox\floatbox\hpack to \d_page_col_float_available{\hss\box\floatbox\hss}% % \fi \fi \fi \fi \fi} %D \unknown \def\page_col_set_float_pack_hsize {\ifnum\c_page_col_current=\c_page_col_n_of_columns \c_page_col_current\plusone \else \advance\c_page_col_current\plusone \fi \page_col_command_set_hsize \hsize\d_page_col_available} \unexpanded\def\page_col_command_flush_floats {\global\settrue\c_page_floats_flushing \ifconditional\c_page_floats_some_waiting \par \page_col_set_float_pack_hsize \page_col_command_flush_floats_indeed \fi \global\savednoffloats\zerocount \global\setfalse\c_page_floats_some_waiting \global\setfalse\c_page_floats_flushing} \def\page_floats_show_pack_state_indeed#1% {\llap{\smash{\backgroundline[black]{\strut\smallinfofont\white#1\space\the\nofcollectedfloats\space of\space\the\savednoffloats:\the\hsize}}\hskip.25\emwidth}} \installtextracker {floats.collecting} {\let\page_floats_show_pack_state\page_floats_show_pack_state_indeed} {\let\page_floats_show_pack_state\gobbleoneargument} \let\page_floats_show_pack_state\gobbleoneargument \def\page_col_command_flush_floats_indeed % much in common with OTRSET {\ifconditional\c_page_floats_some_waiting \ifconditional\c_page_floats_pack_flushed \setfalse\c_page_floats_center_box % not needed as we do call directly % \page_floats_collect\s!text\hsize\emwidth % \ifnum\nofcollectedfloats=\plusone \ifdim\naturalfloatwd>\hsize \nofcollectedfloats\zerocount \fi \fi \ifnum\nofcollectedfloats>\zerocount \global\setbox\floatbox\hpack to \hsize {\page_floats_show_pack_state F% \hfil \dorecurse\nofcollectedfloats {\ifcase\columndirection % nog document wide \page_floats_flush\s!text\plusone \else \page_floats_flush\s!text{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}% \fi % this could happen at the lua end instead \scratchdimen\dimexpr\wd\floatbox-\naturalfloatwd\relax \ifdim\scratchdimen<\zeropoint \global\setbox\floatbox\hpack spread -\scratchdimen{\hss\box\floatbox\hss}% \fi % \ifdim\wd\floatbox>\textwidth % \hsize \hpack to \textwidth{\hss\box\floatbox\hss}% \textwidth \else \box\floatbox \fi \ifnum\recurselevel<\nofcollectedfloats \hfil \fi}% \hfil}% \doplacefloatbox % \page_one_insert_top_float \doubleexpandafter\page_col_command_flush_floats_indeed \else % todo \fi \else \page_floats_get % \page_one_insert_top_float \doplacefloatbox \doubleexpandafter\page_col_command_flush_floats_indeed \fi \fi} \unexpanded\def\page_col_command_flush_saved_floats % like one {\global\d_page_floats_inserted_top\zeropoint \global\d_page_floats_inserted_bottom\zeropoint \ifconditional\c_page_floats_flushing \else \page_col_command_set_top_insertions \page_col_command_set_bottom_insertions \ifconditional\c_page_floats_some_waiting \doif{\rootfloatparameter\c!cache}\v!no\page_col_command_flush_floats % could be _otr_ \else\ifconditional\c_page_margin_blocks_present \page_col_command_flush_floats \fi\fi \fi} \unexpanded\def\page_col_command_set_top_insertions {\bgroup \ifconditional\c_page_floats_some_waiting \noffloatinserts\zerocount \let\totaltopinserted\!!zeropoint \page_col_set_float_pack_hsize \page_col_command_set_top_insertions_indeed \ifnum\rootfloatparameter\c!nbottom=\zerocount \ifnum\rootfloatparameter\c!nlines>\zerocount \ifdim\totaltopinserted>\zeropoint\relax \ifdim\dimexpr\rootfloatparameter\c!nlines\lineheight+\totaltopinserted\relax>\textheight \showmessage\m!floatblocks8{\rootfloatparameter\c!nlines}% \page_otr_fill_and_eject_page % was tripple: vfilll \fi \fi \fi \fi \fi \egroup} \def\d_page_col_collected_top_float_height % pseudo {\dimexpr \d_page_floats_inserted_top + \maxcollectedfloatstotal + \ifdim\d_strc_floats_top>\d_strc_floats_bottom \d_strc_floats_top \else \d_strc_floats_bottom \fi \relax} \def\page_col_command_set_top_insertions_indeed {\ifnum\noffloatinserts<\c_page_floats_n_of_top \ifcase\savednoffloats \let\page_col_command_set_top_insertions_indeed\relax \else \page_floats_collect\s!text\hsize\emwidth \ifdim\d_page_col_collected_top_float_height<\textheight \global\setbox\floatbox\hpack to \hsize {\page_floats_show_pack_state T% \hfil \dorecurse\nofcollectedfloats {\ifcase\columndirection % nog document wide \page_floats_flush\s!text\plusone \else \page_floats_flush\s!text{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}% \fi % this could happen at the lua end instead \scratchdimen\dimexpr\wd\floatbox-\naturalfloatwd\relax \ifdim\scratchdimen<\zeropoint \global\setbox\floatbox\hpack spread -\scratchdimen{\hss\box\floatbox\hss}% \fi % \ifdim\wd\floatbox>\makeupwidth % \hsize \hpack to \makeupwidth{\hss\box\floatbox\hss}% \else \box\floatbox \fi \ifnum\recurselevel<\nofcollectedfloats \hfil \fi}% \hfil}% \page_one_prepare_top_float \xdef\totaltopinserted{\the\d_page_floats_inserted_top}% \page_one_insert_top_float \ifconditional\c_page_floats_some_waiting \advance\noffloatinserts \plusone \else \noffloatinserts\c_page_floats_n_of_top\relax \fi \page_floats_report_flushed \else \let\page_col_command_set_top_insertions_indeed\relax \fi \fi \else \ifconditional\c_page_floats_some_waiting \showmessage\m!floatblocks6{\the\c_page_floats_n_of_top}% \fi \let\page_col_command_set_top_insertions_indeed\relax \fi \page_col_command_set_top_insertions_indeed} \let\page_col_command_flush_top_insertions \page_one_command_flush_top_insertions \let\page_col_command_flush_bottom_insertions\page_one_command_flush_bottom_insertions %let\page_col_command_set_top_insertions \page_one_command_set_top_insertions \let\page_col_command_set_bottom_insertions \page_one_command_set_bottom_insertions %let\page_col_command_set_top_insertions_indeed \page_one_command_set_top_insertions \let\page_col_command_set_bottom_insertions_indeed \page_one_command_set_botttom_insertions \let\page_col_command_flush_float_box \page_one_command_flush_float_box \let\page_col_command_synchronize_side_floats \page_one_command_synchronize_side_floats \let\page_col_command_flush_side_floats \page_one_command_flush_side_floats \let\page_col_command_flush_margin_blocks \page_one_command_flush_margin_blocks \let\page_col_command_test_page \page_one_command_test_page %D The separator code is more or less the same as mixed columns but we need %D to compensate for the top floats so we comment a bit for now. \newdimen\pagecolumnseparatorheight \newdimen\pagecolumnseparatordepth \newdimen\pagecolumnseparatorwidth % \installcorenamespace{pagecolumnsseparator} % % \unexpanded\def\installpagecolumnseparator#1#2% % {\setvalue{\??pagecolumnsseparator#1}{#2}} % % \installpagecolumnseparator\v!rule % {\vrule % \s!width \pagecolumnsparameter\c!rulethickness % \s!height\pagecolumnseparatorheight % \s!depth \pagecolumnseparatordepth % \relax} % % \def\page_col_routine_package_separate % {\ifcsname\??pagecolumnsseparator\p_separator\endcsname % \page_col_command_inject_separator % \else % \hss % \fi} % % \unexpanded\def\page_col_command_inject_separator % {\begingroup % \setbox\scratchbox\hbox to \zeropoint \bgroup % \hss % \starttextproperties % \usepagecolumnscolorparameter\c!rulecolor % \begincsname\??pagecolumnsseparator\p_separator\endcsname % was \c!rule % \stoptextproperties % \hss % \egroup % \ht\scratchbox\zeropoint % \dp\scratchbox\zeropoint % \hss % \box\scratchbox % \hss % \endgroup} \def\page_col_routine_package_separate {\hss} %D \unknown \unexpanded\def\page_col_command_routine {\page_sides_output_routine} % % not: % % \unexpanded\def\page_col_command_routine % {\ifconditional\c_page_sides_short % \page_sides_output_routine_yes_column % \else % \page_sides_output_routine_nop_column % \fi} % % \let\page_sides_output_routine_nop_column\page_sides_output_routine % % \def\page_sides_output_routine_yes_column % this might become the main one too % {\unvbox\normalpagebox % bah, and the discards? % %\page_col_column % \column % \page % % why was this \global\holdinginserts\zerocount % \global\setfalse\c_page_sides_short} \let\page_col_command_flush_all_floats\relax %D \unknown \defineoutputroutine [\s!pagecolumn] [\s!page_otr_command_routine =\page_col_command_routine, \s!page_otr_command_package_contents =\page_col_command_package_contents, \s!page_otr_command_set_vsize =\page_col_command_set_vsize, \s!page_otr_command_set_hsize =\page_col_command_set_hsize, % \s!page_otr_command_synchronize_hsize =\page_col_command_synchronize_hsize, % not done \s!page_otr_command_next_page =\page_col_command_next_page, \s!page_otr_command_next_page_and_inserts =\page_col_command_next_page_and_inserts, \s!page_otr_command_set_top_insertions =\page_col_command_set_top_insertions, \s!page_otr_command_set_bottom_insertions =\page_col_command_set_bottom_insertions, \s!page_otr_command_flush_top_insertions =\page_col_command_flush_top_insertions, \s!page_otr_command_flush_bottom_insertions=\page_col_command_flush_bottom_insertions, \s!page_otr_command_check_if_float_fits =\page_col_command_check_if_float_fits, % \s!page_otr_command_set_float_hsize =\page_col_command_set_float_hsize, % not done \s!page_otr_command_flush_float_box =\page_col_command_flush_float_box, \s!page_otr_command_side_float_output =\page_col_command_side_float_output, \s!page_otr_command_synchronize_side_floats=\page_col_command_synchronize_side_floats, \s!page_otr_command_flush_floats =\page_col_command_flush_floats, \s!page_otr_command_flush_side_floats =\page_col_command_flush_side_floats, \s!page_otr_command_flush_saved_floats =\page_col_command_flush_saved_floats, \s!page_otr_command_flush_all_floats =\page_col_command_flush_all_floats, \s!page_otr_command_flush_margin_blocks =\page_col_command_flush_margin_blocks, \s!page_otr_command_test_column =\page_col_command_test_page ] %D \unknown \installfloatmethod \s!pagecolumn \v!here \page_one_place_float_here \installfloatmethod \s!pagecolumn \v!force \page_one_place_float_force \installfloatmethod \s!pagecolumn \v!left \page_one_place_float_left \installfloatmethod \s!pagecolumn \v!right \page_one_place_float_right \installfloatmethod \s!pagecolumn \v!text \page_one_place_float_text \installfloatmethod \s!pagecolumn \v!top \page_one_place_float_top \installfloatmethod \s!pagecolumn \v!bottom \page_one_place_float_bottom \installfloatmethod \s!pagecolumn \v!auto \page_one_place_float_auto \installfloatmethod \s!pagecolumn \v!margin \page_one_place_float_margin \installfloatmethod \s!pagecolumn \v!opposite \page_one_place_float_face \installfloatmethod \s!pagecolumn \v!page \page_one_place_float_page \installfloatmethod \s!pagecolumn \v!leftpage \page_one_place_float_leftpage \installfloatmethod \s!pagecolumn \v!rightpage \page_one_place_float_rightpage \installfloatmethod \s!pagecolumn \v!inmargin \page_one_place_float_inmargin \installfloatmethod \s!pagecolumn \v!inleft \page_one_place_float_leftmargin \installfloatmethod \s!pagecolumn \v!inright \page_one_place_float_rightmargin \installfloatmethod \s!pagecolumn \v!leftmargin \page_one_place_float_leftmargin \installfloatmethod \s!pagecolumn \v!rightmargin \page_one_place_float_rightmargin \installfloatmethod \s!pagecolumn \v!leftedge \page_one_place_float_leftedge \installfloatmethod \s!pagecolumn \v!rightedge \page_one_place_float_rightedge \installfloatmethod \s!pagecolumn \v!somewhere \page_one_place_float_somewhere \installfloatmethod \s!pagecolumn \v!backspace \page_one_place_float_backspace \installfloatmethod \s!pagecolumn \v!cutspace \page_one_place_float_cutspace %installfloatmethod \s!pagecolumn \s!tblr \page_one_place_float_top %installfloatmethod \s!pagecolumn \s!lrtb \page_one_place_float_top %installfloatmethod \s!pagecolumn \s!tbrl \page_one_place_float_top %installfloatmethod \s!pagecolumn \s!fxtb \page_one_place_float_top %installfloatmethod \s!pagecolumn \s!rltb \page_one_place_float_top %installfloatmethod \s!pagecolumn \s!btlr \page_one_place_float_bottom %installfloatmethod \s!pagecolumn \s!lrbt \page_one_place_float_bottom %installfloatmethod \s!pagecolumn \s!btrl \page_one_place_float_bottom %installfloatmethod \s!pagecolumn \s!rlbt \page_one_place_float_bottom %installfloatmethod \s!pagecolumn \s!fxbt \page_one_place_float_bottom %installfloatmethod \s!pagecolumn \s!fixd \page_one_place_float_force \installfloatmethod \s!pagecolumn \v!local \somelocalfloat %D The main interface: \installcorenamespace{pagecolumns} \installframedcommandhandler \??pagecolumns {pagecolumns} \??pagecolumns \setuppagecolumns [\c!distance=1.5\bodyfontsize, \c!n=\plustwo, \c!page=\v!yes, %\c!align=, % inherit (also replaces tolerance) %\c!before=, %\c!after=, %\c!separator=\v!none, %\c!setups=, %\c!balance=\v!no, %\c!blank={\v!line,\v!fixed}, yes or no \c!frame=\v!off, \c!strut=\v!no, \c!offset=\v!overlay, %\c!maxheight=\textheight, \c!maxwidth=\makeupwidth, %\c!grid=\v!tolerant, %\c!internalgrid=\v!line, \c!direction=\v!normal] \let\startpagecolumns\relax % defined later \let\stoppagecolumns \relax % defined later \appendtoks % could become an option \setuevalue{\e!start\currentpagecolumns}{\startpagecolumns[\currentpagecolumns]}% \setuevalue{\e!stop \currentpagecolumns}{\stoppagecolumns}% \to \everydefinepagecolumns \ifdefined \columnwidth \else \newdimen\columnwidth \fi \ifdefined \columndistance \else \newdimen\columndistance \fi \def\page_col_pickup_preceding {\begingroup \setupoutputroutine[\s!mixedcolumn]% \c_page_mix_routine\c_page_mix_routine_intercept \page_otr_trigger_output_routine \ifvoid\b_page_mix_preceding \else % moved here, before the packaging \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding % we need to avoid unvboxing with successive balanced on one page \global\setbox\b_page_mix_preceding\vbox\bgroup % yes or no: \forcestrutdepth \unvbox\b_page_mix_preceding \forcestrutdepth \egroup \wd\b_page_mix_preceding\makeupwidth \global\d_page_mix_preceding_height\ht\b_page_mix_preceding \fi \endgroup} \def\page_col_flush_preceding {\ifvoid\b_page_mix_preceding \else % this is just one method but ok for now \begingroup % we might need more but for now this is ok \setupfloat[\c!spacebefore=,\c!spaceafter=]% \startplacefigure[\c!location={\v!top,\v!none}]% \box\b_page_mix_preceding \stopplacefigure \endgroup \fi} \unexpanded\def\startpagecolumns {\begingroup \begingroup \dosingleempty\page_col_start} \unexpanded\def\page_col_start[#1]% {\doifelseassignment{#1}% {\let\currentpagecolumns\empty \setuppagecolumns[#1]}% {\edef\currentpagecolumns{#1}}% \edef\p_page{\pagecolumnsparameter\c!page}% \ifx\p_page\empty \setfalse\c_page_col_page \else\ifx\p_page\v!no \setfalse\c_page_col_page \else \settrue\c_page_col_page \page[\p_page]% \fi\fi \c_page_col_n_of_columns\pagecolumnsparameter\c!n\relax \ifnum\c_page_col_n_of_columns>\plusone \expandafter\page_col_start_yes \else \expandafter\page_col_start_nop \fi} % public \unexpanded\def\page_col_start_yes {\d_page_col_distance \pagecolumnsparameter\c!distance\relax % \d_page_col_max_height \pagecolumnsparameter\c!maxheight \d_page_col_max_width \pagecolumnsparameter\c!maxwidth % \d_page_col_balance_step \pagecolumnsparameter\c!step \c_page_col_current \plusone % \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 % \columnwidth \d_page_col_column_width \columndistance \d_page_col_distance % \nopenalties % % \insidecolumnstrue % NO! % \let\column\page_col_column % \def\page_floats_get_used_hsize{\makeupwidth} % a bit of a hack % \usealignparameter \pagecolumnsparameter \useblankparameter \pagecolumnsparameter % \useprofileparameter\pagecolumnsparameter % \usepagecolumnscolorparameter\c!color % \setupnotes[\c!width=\textwidth]% % \usesetupsparameter\pagecolumnsparameter % % This will become a method but for now it's good enough % \ifconditional\c_page_col_page\else \page_col_pickup_preceding \fi \setupoutputroutine[\s!pagecolumn]% \ifconditional\c_page_col_page\else \page_col_flush_preceding \fi % \setupfloats[\c!ntop=\plusthousand]% % \setupfloats[\c!nbottom=\plusthousand]% % \page_col_command_set_vsize \page_col_command_set_hsize % \nofcolumns\c_page_mix_n_of_columns % \unexpanded\def\page_col_start[##1]% {\page_col_start_nop}% % \let\stoppagecolumns\page_col_stop_yes} \unexpanded\def\page_col_start_nop {\nofcolumns\c_page_mix_n_of_columns \let\stoppagecolumns\page_col_stop_nop} \unexpanded\def\page_col_stop_yes {\column % \page_otr_eject_page \page \endgroup % \setupoutputroutine[\s!singlecolumn]% \page_otr_command_set_vsize \page_otr_command_set_hsize \page \endgroup} \unexpanded\def\page_col_stop_nop {\page \endgroup \endgroup} \protect \endinput