diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/page-mcl.mkxl')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/page-mcl.mkxl | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/page-mcl.mkxl b/Master/texmf-dist/tex/context/base/mkxl/page-mcl.mkxl new file mode 100644 index 00000000000..d36e76d94f4 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/page-mcl.mkxl @@ -0,0 +1,542 @@ +%D \module +%D [ file=page-mcl, +%D version=2020.07.26, % stripped down redone page-mul +%D title=\CONTEXT\ Page Macros, +%D subtitle=Multicolumns Limited, +%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 / Multicolumns Limited} + +\unprotect + +%D Columns are kind of hairy in \TEX\ and we would be better if no one needed them. +%D Anyway, we do need some support and no mechanism can serve all. The original +%D multicolumn mechanism of \MKII\ was never fully adapted to \MKIV, where mixed +%D columns and page columns showed up instead. However, for some cases a dumb +%D mechanism makes sense, so again we introduce multi columns, but without float +%D hacks. This one will be optimized for mixed usage as for instance itemize needs. +%D Their main advantage is that they can better deal with notes, which are hairy in +%D themselves. This will (for now) only happen in \LMTX. +%D +%D The code is stripped down ancient \MKII\ code and might become cleaner as it +%D evolves. Macros keep similar names but take a different namespace. The code is +%D not yet perfect wrt spacing! + +% \enableexperiments[itemize.columns] +% +% \starttext +% +% \startmulticolumns +% \dorecurse{10}{\samplefile{ward}\footnote{note #1}\par} +% \stopmulticolumns +% +% \dorecurse{4}{\samplefile{ward}\par} +% +% \startitemize[packed,columns,two] +% \dorecurse{100}{\startitem test #1 \footnote{this is a footnote #1}\stopitem} +% \stopitemize +% +% \stoptext + +\ifdefined \startmulticolumns + + % we're testing and don't want to remake the format + +\else + +\installcorenamespace {multicolumns} + +\installframedcommandhandler \??multicolumns {multicolumns} \??multicolumns + +\newdimen \d_page_mcl_available_width +\newdimen \d_page_mcl_distance +\newdimen \d_page_mcl_leftskip +\newdimen \d_page_mcl_rightskip +\newdimen \d_page_mcl_used_width +\newdimen \d_page_mcl_temp +\newdimen \d_page_mcl_saved_pagetotal % brrr, still needed ? + +\newcount \c_page_mcl_balance_minimum +\newcount \c_page_mcl_n_of_lines + +\newbox \b_page_mcl_preceding +\newdimen \d_page_mcl_preceding_height +\newconditional\c_page_mcl_preceding_present + +\newbox \b_page_mcl_rest_of_page +\newbox \b_page_mcl_page + +\newconditional\c_page_mcl_reverse +\newconditional\c_page_mcl_balance + +\newconstant \c_page_mcl_routine + +\setnewconstant\c_page_mcl_routine_regular \zerocount +\setnewconstant\c_page_mcl_routine_intercept \plusone +\setnewconstant\c_page_mcl_routine_continue \plustwo +\setnewconstant\c_page_mcl_routine_balance \plusthree +\setnewconstant\c_page_mcl_routine_error \plusfour + +\newbox \b_page_mcl_balance_content +\newconstant \c_page_mcl_balance_tries_max +\newcount \c_page_mcl_balance_tries +\newdimen \d_page_mcl_balance_target +\newdimen \d_page_mcl_balance_natural_height +\newdimen \d_page_mcl_balance_step +\newconditional\c_page_mcl_balance_possible + +\c_page_mcl_balance_tries_max 250 % 100 is too small when floats are involved + +%def\m_page_mcl_overshoot_ratio{\ifgridsnapping0\else.5\fi} +\def\m_page_mcl_overshoot_ratio{.5} + +\fi + +\protected\def\page_mcl_command_set_hsize + {\d_page_mcl_available_width\dimexpr + \makeupwidth + -\d_page_mcl_leftskip + -\d_page_mcl_rightskip + -\nofcolumns\d_page_mcl_distance + +\d_page_mcl_distance + \relax + \d_page_mcl_used_width\dimexpr + \d_page_mcl_available_width/\nofcolumns + \relax + \textwidth\d_page_mcl_used_width + \hsize\d_page_mcl_used_width} + +\protected\def\page_mcl_set_n_of_lines#1% + {\d_page_mcl_temp\dimexpr + +\textheight + \ifdim\d_page_mcl_preceding_height>\zeropoint -\d_page_mcl_preceding_height \fi +% \ifdim\ht\b_page_mcl_preceding>\zeropoint -\ht\b_page_mcl_preceding \fi + -#1% + \relax + \getnoflines\d_page_mcl_temp + \ifnum\layoutlines>\zerocount \ifnum\noflines>\layoutlines + \noflines\layoutlines + \fi \fi + \c_page_mcl_n_of_lines\noflines} + +% \protected\def\page_mcl_command_set_vsize +% {%%\page_one_command_set_vsize % indeed? +% \page_mcl_set_n_of_lines\zeropoint +% \d_page_mcl_temp\nofcolumns\dimexpr +% \c_page_mcl_n_of_lines\openlineheight +% % +\m_page_mcl_overshoot_ratio\openlineheight % collect enough data +% \relax +% \global\vsize \d_page_mcl_temp +% \global\pagegoal\d_page_mcl_temp} % let's do it only here, reports maxdimen anyway + +\protected\def\page_mcl_command_set_vsize + {\global\vsize\dimexpr\nofcolumns\textheight+\nofcolumns\lineheight\relax + \pagegoal\dimexpr + \vsize +% -\d_page_floats_inserted_top % needs checking +% -\d_page_floats_inserted_bottom % needs checking + -\c_page_mix_n_of_columns\insertheights + \relax} + +\protected\def\page_mcl_command_routine + {\ifcase\c_page_mcl_routine + \page_one_command_routine + \or + \page_mcl_routine_intercept + \or + \page_mcl_routine_continue + \or + \page_mcl_routine_balance + \or + \page_mcl_routine_error + \fi} + +\let\page_mcl_command_package_contents\page_one_command_package_contents + +\def\page_mcl_routine_intercept + {\global\setbox\b_page_mcl_preceding\vbox + {\page_otr_command_flush_top_insertions + \unvbox\normalpagebox}} + +\def\page_mcl_routine_error + {\showmessage\m!columns3\empty + \page_otr_construct_and_shipout\unvbox\normalpagebox\zerocount} % three arguments + +\protected\def\page_mcl_initialize_variables + {\reseteverypar % maybe still freeze .... + \dontcomplain + \settopskip + \setmaxdepth + \topskip 1\topskip + \splittopskip \topskip + \splitmaxdepth \maxdepth + \boxmaxdepth \maxdepth % dangerous + \emergencystretch\zeropoint + \relax} + +\def\page_mcl_flush_preceding_normal + {\unvbox\b_page_mcl_preceding} + +\def\page_mcl_flush_preceding_ongrid + {\scratchdimen\dimexpr + \d_page_mcl_saved_pagetotal + -\d_page_mcl_preceding_height + -\topskip + \relax + \box\b_page_mcl_preceding + \kern\scratchdimen} + +\def\page_mcl_flush_packaged_columns_continued + {\page_mcl_flush_packaged_columns_indeed + \box\b_page_mcl_page} + +\def\page_mcl_flush_packaged_columns_balanced + {\bgroup + \page_mcl_flush_packaged_columns_indeed + \getnoflines{\htdp\b_page_mcl_page}% + \ht\b_page_mcl_page\dimexpr + \noflines\openlineheight + -\openstrutdepth + \ifgridsnapping + % quick hack (at least it works with itemize) + \else + -\openlineheight + +\topskip + \fi + \relax + \dp\b_page_mcl_page\openstrutdepth + \box\b_page_mcl_page + \egroup} + +\def\page_mcl_synchronize_marks + {\dohandleallcolumns{\page_marks_synchronize_column\plusone\nofcolumns\mofcolumns\currentcolumnbox}} + +\def\page_mcl_flush_packaged_columns_indeed + {\ifvoid\b_page_mcl_preceding + \setfalse\c_page_mcl_preceding_present % will be set elsewhere + \else + \settrue\c_page_mcl_preceding_present + \page_apply_postprocessors_box\b_page_mcl_preceding + \fi + \forgetall + \page_mcl_initialize_variables + \page_mcl_synchronize_marks + \setbox\b_page_mcl_page\vpack + {\ifconditional\c_page_mcl_reverse\reversehpack\else\naturalhpack\fi to \makeupwidth + {\hskip\ifconditional\c_page_mcl_reverse\d_page_mcl_rightskip\else\d_page_mcl_leftskip\fi\relax + \dohandleallcolumns + {\wd\currentcolumnbox\d_page_mcl_used_width + \setbox\scratchbox\hpack{\strut\box\currentcolumnbox}% hm, why strut + \anch_mark_column_box\scratchbox\currentcolumn + \box\scratchbox + \hfil}% + \unskip + \hskip\ifconditional\c_page_mcl_reverse\d_page_mcl_leftskip\else\d_page_mcl_rightskip\fi}}% + \ifconditional\c_page_mcl_preceding_present + \settrue\c_page_mcl_preceding_present + \ifgridsnapping + \page_mcl_flush_preceding_ongrid % obey grid settings, force on grid + \else + \page_mcl_flush_preceding_normal % ignore grid settings, not on grid + \fi + \fi + \global\d_page_mcl_preceding_height\zeropoint + \page_otr_command_set_vsize + \dosomebreak\nobreak % hm, only needed when topstuff + \ifgridsnapping \else + \ifconditional\c_page_mcl_preceding_present + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip\relax + \fi + \fi + \prevdepth\openstrutdepth + \nointerlineskip + \dp\b_page_mcl_page\zeropoint} + +\def\page_mcl_split_column#1#2% copy or box + {\global\setbox\currentcolumnbox\vsplit#1 upto #2} + +\def\page_mcl_routine_continue + {\bgroup + \forgetall + \page_mcl_initialize_variables + \settotalinsertionheight + \page_mcl_set_n_of_lines\totalinsertionheight + \d_page_mcl_balance_target\c_page_mcl_n_of_lines\openlineheight + \dohandleallcolumns{\page_mcl_split_column\normalpagebox\d_page_mcl_balance_target}% + \setbox\b_page_mcl_rest_of_page\vpack{\unvbox\normalpagebox}% + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vpack to \d_page_mcl_balance_target + {\unvbox\currentcolumnbox % wel of niet \unvbox ? + \vfill}}% + \setbox\b_page_mcl_preceding\vpack{\page_mcl_flush_packaged_columns_continued}% + \page_otr_construct_and_shipout\box\b_page_mcl_preceding\zerocount % three arguments + \page_otr_command_set_hsize + \page_otr_command_set_vsize + \unvbox\b_page_mcl_rest_of_page + \egroup} + +\def\page_mcl_routine_balance + {\bgroup + % why no \forgetall here + \page_mcl_initialize_variables + \widowpenalty\zerocount + \setbox\b_page_mcl_balance_content\vpack{\unvbox\normalpagebox}% + \ifdim\ht\b_page_mcl_balance_content>\openlineheight % at least one line + \ifnum\c_page_mcl_balance_minimum<\plustwo % balance anyway + \settrue\c_page_mcl_balance_possible + \else % check criterium to available lines + \getnoflines{\ht\b_page_mcl_balance_content}% + \divide\noflines \nofcolumns \relax + \ifnum\noflines<\c_page_mcl_balance_minimum \relax + \ifdim\dimexpr\ht\b_page_mcl_balance_content+\openlineheight\relax>\makeupheight + \settrue\c_page_mcl_balance_possible % column exceeding text height + \else + \setfalse\c_page_mcl_balance_possible % it seems to fit + \fi + \else + \settrue\c_page_mcl_balance_possible % balance indeed + \fi + \fi + \else + \setfalse\c_page_mcl_balance_possible % balancing does not make sense + \fi + \ifconditional\c_page_mcl_balance_possible % start balancing, was: \ifdim\ht\b_page_mcl_balance_content>\openlineheight + \page_mcl_balance_try_one + \page_mcl_balance_try_two + \else + % a one liner is not properly handled here, so best rewrite the text then + \showmessage\m!columns{10}\empty + \global\setbox\firstcolumnbox\vpack{\unvbox\b_page_mcl_balance_content}% + \fi + \c_page_mcl_routine\c_page_mcl_routine_error + %\baselinebottom % forces depth in separation rule + \page_mcl_flush_packaged_columns_balanced + %\allowbreak + \egroup} + +% \showmakeup + +\def\page_mcl_balance_try_one + {\d_page_mcl_balance_target\dimexpr\ht\b_page_mcl_balance_content+\topskip-\baselineskip\relax + \divide\d_page_mcl_balance_target \nofcolumns + \vbadness\plustenthousand + \c_page_mcl_balance_tries\zerocount + \bgroup + \ifgridsnapping + \d_page_mcl_balance_step\lineheight + \else + \d_page_mcl_balance_step\spacingfactor\onepoint % rubish + \fi + \doloop\page_mcl_balance_try_one_attempt + \global\setbox\b_page_mcl_rest_of_page\box\voidbox + \ifnum\c_page_mcl_balance_tries>\c_page_mcl_balance_tries_max\relax + \showmessage\m!columns7\empty + \else + \showmessage\m!columns8{\the\c_page_mcl_balance_tries}% + \fi + \egroup} + +\def\page_mcl_balance_try_one_attempt + {\advance\c_page_mcl_balance_tries \plusone + \global\setbox\b_page_mcl_rest_of_page\copy\b_page_mcl_balance_content\relax + \dohandleallcolumns{\page_mcl_split_column\b_page_mcl_rest_of_page\d_page_mcl_balance_target}% + \d_page_mcl_balance_natural_height\zeropoint + \dohandleallcolumns\page_mcl_balance_try_one_attempt_step +\advance\d_page_mcl_balance_natural_height-33\scaledpoint % some slack + \ifnum\c_page_mcl_balance_tries>\c_page_mcl_balance_tries_max\relax + \exitloop + \orelse\ifdim\ht\b_page_mcl_rest_of_page>\zeropoint + \advance\d_page_mcl_balance_target\d_page_mcl_balance_step\relax + \orelse\ifdim\d_page_mcl_balance_natural_height>\ht\firstcolumnbox\relax + \advance\d_page_mcl_balance_target\d_page_mcl_balance_step\relax + \else + \exitloop + \fi} + +\def\page_mcl_balance_try_one_attempt_step + {\ifcase\currentcolumn\or\else + \ifdim\ht\currentcolumnbox>\d_page_mcl_balance_natural_height\relax + \d_page_mcl_balance_natural_height\ht\currentcolumnbox + \fi + \fi} + +\def\page_mcl_balance_try_two % hm ... can probably go + {\dohandleallcolumnscs\page_mcl_balance_try_two_step} + +% \def\page_mcl_balance_try_two_step +% {\global\setbox\currentcolumnbox\vbox to \ht\firstcolumnbox +% {\box\currentcolumnbox +% \vfill}} + +\def\page_mcl_balance_try_two_step + {%\global\setbox\currentcolumnbox\box\currentcolumnbox + \ht\currentcolumnbox\ht\firstcolumnbox} + +\permanent\tolerant\protected\def\startmulticolumns[#1]% + {\bgroup + \ifinsidecolumns + \page_mcl_start_nop + \else + \setupmulticolumns[#1]% + \nofcolumns\multicolumnsparameter\c!n\relax + \ifnum\nofcolumns>\plusone + \page_mcl_start_yes + \nofmulticolumns\nofcolumns + \else + \page_mcl_start_nop + \fi + \fi} + +\aliased\let\stopmulticolumns\relax + +\def\page_mcl_start_nop + {\enforced\let\stopmulticolumns\page_mcl_stop_nop} + +\permanent\protected\def\page_mcl_stop_nop + {\egroup} + +\protected\def\page_mcl_start_yes + {\whitespace + \begingroup + \enforced\let\stopmulticolumns\page_mcl_stop_indeed + \global\insidecolumnstrue + \global\insidemulticolumnstrue + % + \d_page_mcl_distance\multicolumnsparameter\c!distance\relax + % + \edef\p_direction{\multicolumnsparameter\c!direction}% + \ifx\p_direction\v!right + \setfalse\c_page_mcl_reverse + \else + \settrue\c_page_mcl_reverse + \fi + % + \edef\p_balance{\multicolumnsparameter\c!balance}% + \ifx\p_balance\v!yes + \settrue\c_page_mcl_balance + \else + \setfalse\c_page_mcl_balance + \fi + % + \usealignparameter\multicolumnsparameter + % + \edef\p_blank{\multicolumnsparameter\c!blank}% + \ifempty\p_blank \else + \setupblank[\p_blank]% + \fi + % + \ifdim\s_spac_whitespace_parskip>\zeropoint\relax + \setupwhitespace[\p_blank]% + \fi + \c_page_mcl_balance_minimum\multicolumnsparameter\c!ntop\relax + % + \begingroup + % + \d_page_mcl_leftskip \leftskip + \d_page_mcl_rightskip\rightskip + \leftskip \zeropoint + \rightskip \zeropoint + \hangafter \zerocount + \hangindent \zeropoint + % + \widowpenalty \zerocount % will become option + \clubpenalty \zerocount % will become option + % + \ifdim\dimexpr\pagetotal+\parskip+\openlineheight\relax<\pagegoal + \allowbreak + \else + \break % sometimes fails + \fi + \appendtoks + \topskip1\topskip % best a switch + \to \everybodyfont + \the\everybodyfont % ugly here + \saveinterlinespace % ugly here + % + \initializecolumns\nofcolumns + % + \reseteverypar % todo + % + \ifdim\pagetotal=\zeropoint \else + \verticalstrut + \vskip-\struttotal + \fi + \global\d_page_mcl_saved_pagetotal\pagetotal + \setupoutputroutine[\s!multicolumn]% + \c_page_mcl_routine\c_page_mcl_routine_intercept + \page_otr_trigger_output_routine + \global\d_page_mcl_preceding_height\ht\b_page_mcl_preceding + \c_page_mcl_routine\c_page_mcl_routine_continue + \page_otr_command_set_hsize + \page_otr_command_set_vsize} + +\permanent\protected\def\page_mcl_stop_indeed + {\relax + \synchronizeoutput + \par + \ifconditional\c_page_mcl_balance + \c_page_mcl_routine\c_page_mcl_routine_continue + \goodbreak + \c_page_mcl_routine\c_page_mcl_routine_balance + \else + \goodbreak + \fi + % still the multi column routine + \page_otr_trigger_output_routine % the prevdepth is important, try e.g. toclist in + \prevdepth\zeropoint % columns before some noncolumned text text + % + \c_page_mcl_routine\c_page_mcl_routine_regular + % + \ifvoid\b_page_mcl_preceding\else + \unvbox\b_page_mcl_preceding + \fi + \global\d_page_mcl_preceding_height\zeropoint + \endgroup % here + \nofcolumns\plusone + \nofmulticolumns\plusone + \page_otr_command_set_vsize + \dosomebreak\allowbreak + \page_floats_column_pop_saved + % + \global\insidemulticolumnsfalse + \global\insidecolumnsfalse + \endgroup + \egroup}% + +\setupmulticolumns + [\c!n=2, + \c!ntop=1, + \c!direction=\v!right, + \c!distance=1.5\bodyfontsize, % influenced by switching + \c!balance=\v!yes, + \c!align={\v!text,\v!tolerant}, + \c!blank={\v!line,\v!fixed}] + +\defineoutputroutine + [\s!multicolumn] + [\s!page_otr_command_routine =\page_mcl_command_routine, + \s!page_otr_command_package_contents=\page_mcl_command_package_contents, + \s!page_otr_command_set_vsize =\page_mcl_command_set_vsize, + \s!page_otr_command_set_hsize =\page_mcl_command_set_hsize] + +\let\strc_itemgroups_start_columns_old\strc_itemgroups_start_columns +\let\strc_itemgroups_stop_columns_old \strc_itemgroups_stop_columns + +\def\strc_itemgroups_start_columns_new{\startmulticolumns[\c!n=\itemgroupparameter\c!n]} +\def\strc_itemgroups_stop_columns_new {\stopmulticolumns} + +\installtexexperiment + {itemize.columns} + {\let\strc_itemgroups_start_columns\strc_itemgroups_start_columns_new + \let\strc_itemgroups_stop_columns \strc_itemgroups_stop_columns_new} + {\let\strc_itemgroups_start_columns\strc_itemgroups_start_columns_old + \let\strc_itemgroups_stop_columns \strc_itemgroups_stop_columns_old} + +\protect \endinput |