summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/multicolumns.opm
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-05-07 03:01:09 +0000
committerNorbert Preining <norbert@preining.info>2020-05-07 03:01:09 +0000
commit56bd1f5b8377f54b4af39a114362a7762d27f13c (patch)
tree882c573288f2a3f158b490ea3de1672fca9e94a9 /macros/luatex/optex/base/multicolumns.opm
parent36d8a5cd45b5a96007208a0d5b1f52e708d0fec8 (diff)
CTAN sync 202005070301
Diffstat (limited to 'macros/luatex/optex/base/multicolumns.opm')
-rw-r--r--macros/luatex/optex/base/multicolumns.opm114
1 files changed, 114 insertions, 0 deletions
diff --git a/macros/luatex/optex/base/multicolumns.opm b/macros/luatex/optex/base/multicolumns.opm
new file mode 100644
index 0000000000..c593f72552
--- /dev/null
+++ b/macros/luatex/optex/base/multicolumns.opm
@@ -0,0 +1,114 @@
+%% This is part of OpTeX project, see http://petr.olsak.net/optex
+
+\_codedecl \begmulti {Balanced columns <2020-03-26>} % preloaded in format
+
+ \_doc -----------------------------
+ This code is documented in detail in the \"\TeX/book naruby", pages 244--246,
+ free available, \url{http://petr.olsak.net/tbn.html}, but in Czech.
+ Roughly speaking, macros complete all material between
+ \`\begmulti``<num-columns>` and \`\endmulti`
+ into one `\vbox 6`. Then the macro measures the amount of free space at the current
+ page using `\pagegoal` and `\pagtotal` and does `\vsplit` of `\vbox 6` to
+ columns with height of such free space. This is done only if we have
+ enought amount of material in `\vbox 6` to fill full page by columns.
+ This is repeated in loop until we have less amount of material in `\vbox 6`.
+ Then we run `\_balancecolumns` which balances the last part of columns.
+ Each part of printed material is distributed to main vertical list as
+ `\hbox{<columns>}` and we need not do any change in the output routine.
+
+ If you have paragraphs in `\begmulti`... `\endmulti` environment then
+ you may say `\raggedright` inside this environment and you can re-assign
+ `\widowpenalty` and `\clubppenalty` (they are set to 10000 in \OpTeX/).
+ \_cod -----------------------------
+
+\_def\_multiskip{\_medskip} % space above and below \begmulti...\endmulti
+
+\_newcount\_mullines
+
+\_def\_begmulti #1 {\_par\_bgroup\_wipeepar\_multiskip\_penalty0 \_def\_Ncols{#1}
+ \_setbox6=\_vbox\_bgroup\_penalty0
+ %% \hsize := column width = (\hsize+\colsep) / n - \colsep
+ \_advance\_hsize by\_colsep
+ \_divide\_hsize by\_Ncols \_advance\_hsize by-\_colsep
+ \_mullines=0
+ \_def\par{\_ifhmode\_endgraf\_global\_advance\_mullines by\_prevgraf\_fi}%
+}
+\_def\_endmulti{\_vskip-\_prevdepth\_vfil
+ \_ea\_egroup\_ea\_baselineskip\_the\_baselineskip\_relax
+ \_dimen0=.8\_maxdimen \_tmpnum=\_dimen0 \_divide\_tmpnum by\_baselineskip
+ \_splittopskip=\_baselineskip
+ \_setbox1=\_vsplit6 to0pt
+ %% \dimen1 := the free space on the page
+ \_ifdim\_pagegoal=\_maxdimen \_dimen1=\_vsize \_corrsize{\_dimen1}
+ \_else \_dimen1=\_pagegoal \_advance\_dimen1 by-\_pagetotal \_fi
+ \_ifdim \_dimen1<2\_baselineskip
+ \_vfil\_break \_dimen1=\_vsize \_corrsize{\_dimen1} \_fi
+ \_ifnum\_mullines<\_tmpnum \_dimen0=\_ht6 \_else \_dimen0=.8\_maxdimen \_fi
+ \_divide\_dimen0 by\_Ncols \_relax
+ %% split the material to more pages?
+ \_ifdim \_dimen0>\_dimen1 \_splitpart
+ \_else \_balancecolumns \_fi % only balancing
+ \_multiskip\_egroup
+}
+
+ \_doc -----------------------------
+ Splitting columns...
+ \_cod -----------------------------
+
+\_def\_makecolumns{\_bgroup % full page, destination height: \dimen1
+ \_vbadness=20000 \_setbox1=\_hbox{}\_tmpnum=0
+ \_loop \_ifnum\_Ncols>\_tmpnum
+ \_advance\_tmpnum by1
+ \_setbox1=\_hbox{\_unhbox1 \_vsplit6 to\_dimen1 \_hss}
+ \_repeat
+ \_hbox{}\_nobreak\_vskip-\_splittopskip \_nointerlineskip
+ \_line{\_unhbox1\_unskip}
+ \_dimen0=\_dimen1 \_divide\_dimen0 by\_baselineskip \_multiply\_dimen0 by\_Ncols
+ \_global\_advance\_mullines by-\_dimen0
+ \_egroup
+}
+\_def\_splitpart{%
+ \_makecolumns % full page
+ \_vskip 0pt plus 1fil minus\_baselineskip \_break
+ \_ifnum\_mullines<\_tmpnum \_dimen0=\_ht6 \_else \_dimen0=.8\_maxdimen \_fi
+ \_divide\_dimen0 by\_Ncols \_relax
+ \_ifx\_balancecolumns\_flushcolumns \_advance\_dimen0 by-.5\_vsize \_fi
+ \_dimen1=\_vsize \_corrsize{\_dimen1}\_dimen2=\_dimen1
+ \_advance\_dimen2 by-\_baselineskip
+ %% split the material to more pages?
+ \_ifvoid6 \_else
+ \_ifdim \_dimen0>\_dimen2 \_ea\_ea\_ea \_splitpart
+ \_else \_balancecolumns % last balancing
+ \_fi \_fi
+}
+
+ \_doc -----------------------------
+ Final balancing of the columns.
+ \_cod -----------------------------
+
+\_def\_balancecolumns{\_bgroup \_setbox7=\_copy6 % destination height: \dimen0
+ \_ifdim\_dimen0>\_baselineskip \_else \_dimen0=\_baselineskip \_fi
+ \_vbadness=20000
+ \_def\_tmp{%
+ \_setbox1=\_hbox{}\_tmpnum=0
+ \_loop \_ifnum\_Ncols>\_tmpnum
+ \_advance\_tmpnum by1
+ \_setbox1=\_hbox{\_unhbox1
+ \_ifvoid6 \_hbox to\_wd6{\_hss}\_else \_vsplit6 to\_dimen0 \_fi\_hss}
+ \_repeat
+ \_ifvoid6 \_else
+ \_advance \_dimen0 by.2\_baselineskip
+ \_setbox6=\_copy7
+ \_ea \_tmp \_fi}\_tmp
+ \_hbox{}\_nobreak\_vskip-\_splittopskip \_nointerlineskip
+ \_hbox to\_hsize{\_unhbox1\_unskip}%
+ \_egroup
+}
+\_def\_corrsize #1{%% #1 := #1 + \splittopskip - \topskip
+ \_advance #1 by \_splittopskip \_advance #1 by-\_topskip
+}
+\_public \begmulti \endmulti ;
+
+\_endcode % -------------------------------------
+
+