From 72c9345e5bafe708888bf65448a81d1aee8275ed Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Sat, 5 Oct 2019 03:01:15 +0000
Subject: CTAN sync 201910050301

---
 macros/latex/contrib/multicolrule/multicolrule.dtx | 489 ++++++++++++++-------
 1 file changed, 328 insertions(+), 161 deletions(-)

(limited to 'macros/latex/contrib/multicolrule/multicolrule.dtx')

diff --git a/macros/latex/contrib/multicolrule/multicolrule.dtx b/macros/latex/contrib/multicolrule/multicolrule.dtx
index 85de910089..ac6d017a18 100644
--- a/macros/latex/contrib/multicolrule/multicolrule.dtx
+++ b/macros/latex/contrib/multicolrule/multicolrule.dtx
@@ -147,12 +147,13 @@ and the derived files           multicolrule.ins,
 %   \cs_new_nopar:Npn,\cs_set:Npn,
 %   \c_one_int,\c_zero_dim,\c_zero_int,
 %   \dim_compare_p:nNn,\dim_new:N,\dim_set:Nn,
-%   \dim_compare:nNnTF,\dim_eval:n,\dimen,
-%   \end,\ExplSyntaxOff,\ExplSyntaxOn,\fill,\hbox:n,\hspace,\ht,
-%   \int_compare_nNnTF,\int_compare_p:nNn,
+%   \dim_compare:nNnTF,\dim_eval:n,\dim_max:nn,\dimen,
+%   \end,\ExplSyntaxOff,\ExplSyntaxOn,\exp_stop_f:,
+%   \fill,\fp_to_dim:n,\hbox:n,\hspace,\ht,
+%   \int_compare:nNnTF,\int_compare:nNnT,\int_compare_p:nNn,
 %   \int_gdecr:N,\int_gincr:N,\int_gset:Nn,\int_gzero:N,
 %   \int_new:N,\int_set:Nn,\kern,\keys_define:nn,
-%   \keys_set:nn,\keys_set_finter:nnn,
+%   \keys_set:nn,\keys_set_filter:nnV,
 %   \msg_error:nnn,\msg_info:nnn,\msg_new:nnn,\msg_new:nnnn,\msg_warning:nn,
 %   \NewDocumentCommand,\node,\prg_replicate:nn,\ProcessKeysOptions,
 %   \prop_get:NnNTF,\prop_gput:Nnn,\prop_item:Nn,\prop_new:N,
@@ -179,6 +180,7 @@ and the derived files           multicolrule.ins,
 % \changes{v1.1}{2018/12/21}{Allow extended rules}
 % \changes{v1.2}{2019/1/1}{Define rule patterns}
 % \changes{v1.2}{2019/1/1}{Allow per-column rule changes}
+% \changes{v1.2a}{2019/2/12}{Improve documentation}
 %
 %\begin{abstract}
 % The \mcrule{} package lets you customize the appearance of the vertical rule
@@ -210,7 +212,7 @@ and the derived files           multicolrule.ins,
 % Of course it's a legitimate question why anyone should \emph{want} to change
 % this rule, or indeed use one at all, as good typography tends to avoid using
 % large vertical lines.\footnote{See, for example, the remarks in the
-% documentation for the \pkg{booktabs} package} In my own case, I needed to
+% documentation for the \pkg{booktabs} package.} In my own case, I needed to
 % modify the rule because of the requirements of a particular style I was
 % imitating, and having done the hard work of creating the necessary
 % infrastructure for one line style, it was simple to extend the solution to a
@@ -225,9 +227,16 @@ and the derived files           multicolrule.ins,
 % \begin{multicols}{2}
 % \SetMCRule{custom-line={\path (TOP) to [ornament=85] (BOT);},extend-top=-24pt,
 %   extend-bot=-8pt}
-% \subsection*{New for Version 1.2}
+% \subsection*{New for Version 1.3}
 % Version\stydsc{custom-line=\\\{\textbackslash path (TOP) to [ornament=85]
-%   (BOT);\}, extend-top=-24pt, extend-bot=-8pt} 1.2 adds the ability to define
+% (BOT);\}, extend-top=-24pt, extend-bot=-8pt} 1.3 adds a strut rule. This
+% places an invisible rule (a strut) that obeys the other options for the rule.
+% Using a strut allows you to achieve effects such as selectively disabling one
+% separator within a pattern or using the extend and reserve options to control
+% the spacing to the text outside the \env{multicols} environment.
+%
+% \subsection*{New for Version 1.2}
+% Version 1.2 adds the ability to define
 % patterns, which are aliases for a series of \cs{SetMCRule} settings. With
 % patterns, you can change individual separators on the same page. For example,
 % in three-column text, the left separator can differ from the right.
@@ -272,7 +281,7 @@ and the derived files           multicolrule.ins,
 % whether this is the case. If you would like support for one of these, please
 % send me an email or file a feature request on github and I'll see what I can
 % do.
-% 
+%
 % The line styles that work by repeating elements in a tiled pattern may have
 % significant gaps at the end of columns, particularly for larger patterns.
 % You can mitigate this problem slightly by tweaking the spaces above and
@@ -284,11 +293,10 @@ and the derived files           multicolrule.ins,
 % Extending rules beyond their natural column lengths can seriously mess up
 % the output, including, in certain edge cases, causing \pkg{multicol} to
 % overprint columns or even put them in the margins. The fact that the extended
-% rule occupies space on the page instead of extending up into the margin was a
-% deliberate design decision and is necessary to support the
-% \kvdesc{extend-fill} and \kvdesc{extend-reserve} options work correctly. A
-% future version may support drawing the rules to a background layer so that
-% the text is not shifted.
+% rule affects the vertical layout was a deliberate design decision and is
+% necessary to support the \kvdesc{extend-fill} and \kvdesc{extend-reserve}
+% options. A future version may support drawing the rules to a background layer
+% so that the text is not shifted.
 % \end{multicols}
 %
 % \begin{multicols}{2}[\subsection{License}]
@@ -350,7 +358,11 @@ and the derived files           multicolrule.ins,
 % \end{multicols}
 %
 % \section{The User Interface}
-% |\SetMCRule| \marg{key-value list}
+% \begin{function}{\SetMCRule}
+% \begin{syntax}
+% \cs{SetMCRule} \meta{key-value list}
+% \end{syntax}
+% \end{function}
 %
 % \begin{multicols}{2}
 % \SetMCRule{width=2pt,line-style=circles}
@@ -393,6 +405,8 @@ and the derived files           multicolrule.ins,
 % (see sec. \ref{sec:custom})\\
 % \kvdesc{double} & Draw two copies of the rule (see sec.
 % \ref{sec:repeats})\\
+% \kvdesc{expand} & Change the extend distance by the same amount at the top
+% and bottom of the column (see sec. \ref{sec:extend})\\
 % \kvdesc{extend-bot} & Set an extra amount to extend the rule at the bottom of
 % the column (see sec. \ref{sec:extend})\\
 % \kvdesc{extend-fill} & Extend rule to the bottom of the text area
@@ -415,6 +429,8 @@ and the derived files           multicolrule.ins,
 % sec. \ref{sec:repeats})\\
 % \kvdesc{repeat-distance} & Set the horizontal space between
 % adjacent copies of repeated rules (see sec. \ref{sec:repeats})\\
+% \kvdesc{shift} & Shift the extend distance downward; this affects both the
+% top and bottom of the column (see sec. \ref{sec:extend})\\
 % \kvdesc{triple} & Draw three copies of the rule (see sec.
 % \ref{sec:repeats})\\
 % \kvdesc{width} & Set the width of the rule (see sec.
@@ -497,6 +513,7 @@ and the derived files           multicolrule.ins,
 % \kvdesc{solid} & A solid line, like \kvdesc{default}, but supports extending
 % rules\\
 % \kvdesc{solid-circles} & A series of filled circles (\emph{tikz only})\\
+% \kvdesc{strut} & An invisible (0pt) strut is drawn in place of a solid rule.\\
 % \bottomrule
 % \end{longtable}
 %
@@ -525,6 +542,12 @@ and the derived files           multicolrule.ins,
 % The \kvdesc{dotted} styles differ from \kvdesc{dots} in that the former are
 % squares with side lengths equal to \cs{columnseprule}. This mirrors the
 % behavior of the equivalently named dotted patterns in \pkg{tikz}.
+%
+% The \kvdesc{strut} style draws a 0pt rule. Like every other line style,
+% however, the value of \cs{columnseprule} must be greater than 0pt for it
+% to be drawn. An invisible rule can be useful if you want to disable a rule
+% in the middle of a cycle of patterns or in conjunction with the extend
+% various extend options. See section \ref{sec:extend}.
 % \end{multicols}
 %
 % \subsubsection{Custom Patterns}\label{sec:custom}
@@ -589,9 +612,16 @@ and the derived files           multicolrule.ins,
 % This function will use the color set in
 % \cs{columnseprulecolor} if you don't set it explicitly within the tikz
 % command, but you must provide everything else necessary to draw the line
-% correctly, including the line width. Note that this function should be
-% considered experimental. It works for single-line commands such as the one
-% shown in the example, but I haven't tested it with anything more elaborate. 
+% correctly, including the line width. Note that nothing limits you to drawing
+% a picture that fits within the space between the columns. If the rule is
+% wider than the available space, it will be centered between the columns and
+% overlap the text. Normally, of course, that will be undesirable, but you can
+% use it to your advantage in certain cases. The file \file{mcrule-example.pdf}
+% contains examples showing the effect of a rule that is too wide, as well as
+% a custom rule which includes horizontal rules at the top and bottom of the
+% column.\footnote{This latter rule was developed as an answer to
+% \href{https://tex.stackexchange.com/questions/473828/horizontal-rules-before-and-after-multicols}
+% {StackExchange question 473828}.}
 % \end{multicols}
 %
 % \begin{multicols}{2}[\subsection{Colors}\label{sec:color}]
@@ -627,8 +657,9 @@ and the derived files           multicolrule.ins,
 % \SetMCRule{width=thick,line-style=dash-dot-dot}
 % You\stydsc{line-style= dash-dot-dot,\\ width=thick} can set the width of the
 % rule with the \kvdesc{width} key. Legal values are any explicit dimension or
-% dimension expression, as well as with names that parallel those used by
-% \pkg{tikz}, except that spaces in the key names are replaced with hyphens.
+% dimension expression, as well as one of the names listed in table
+% \ref{table:linewidths}. These names parallel those used by \pkg{tikz}, except
+% that spaces in the key names are replaced with hyphens.
 %  
 % The current width of the rule is kept in \cs{columnseprule}, just as in
 % vanilla \LaTeX, and if it is set separately, the custom rule's width will
@@ -681,33 +712,49 @@ and the derived files           multicolrule.ins,
 % \end{multicols}
 %
 %\begin{multicols}{2}[\subsection{Extended Rules}\label{sec:extend}]
-% \SetMCRule{line-style=dashed,extend-top=-16pt,extend-bot=-16pt}
-%
-% You\stydsc{line-style=dashed, extend-top=-16pt, extend-bot=-16pt} can specify
-% an additional amount by which the top or bottom of the rule projects beyond
-% the column's natural length with the keys \kvdesc{extend-top} and
-% \kvdesc{extend-bot}, each of which can be set to a dimension expression.
-% Extending the top of the rule with a positive dimension will push the columns
-% down from any preceding material. A positive value for \kvdesc{extend-bot}
-% does the same in the other direction when a column ends in the middle of a
-% page, but the rule will extend into the the bottom margin if the column goes
-% to the end of the page, and so you probably only want to use this in very
-% limited situations where you need a special effect for one column or a small
-% \env{multicol} environment. Overprinting and other bizarre effects can
-% result from extending the rule in the wrong place. Negative values for both
-% keys may be more generally useful, as they have the effect of shrinking the
-% rule. This behavior is illustrated with the rule for this section.
-%
-% The \kvdesc{extend-fill} key is a boolean option that, when set to true, will
-% extend the rule to occupy any space between the bottom of the columns and the
-% end of the text area. Providing the key with no value is equivalent to
-% |extend-fill=true|. This option has no effect unless the \pkg{multicol}
-% package is loaded.
-%
-% If you want text below the \env{multicols} environment when using
-% \kvdesc{extend-fill}, you can reserve space for it with
-% \kvdesc{extend-reserve}, which takes a dimension expression specifying the
-% vertical space to leave available after the rule. If the value is greater
+% \SetMCRule{line-style=dashed,expand=-16pt}
+%
+% You\stydsc{line-style=dashed, expand=-16pt} can specify an additional amount
+% by which the top or bottom of the rule projects beyond the column's natural
+% length with the keys \kvdesc{extend-top} and \kvdesc{extend-bot}, each of
+% which can be set to a dimension expression. Extending the top of the rule
+% with a positive dimension will push the columns down from any preceding
+% material. A positive value for \kvdesc{extend-bot} does the same in the other
+% direction when a column ends in the middle of a page, but the rule will
+% extend into the the bottom margin if the column goes to the end of the page.
+% 
+% Note that positive values for extending the rules should be used with
+% caution and only in situations where you need a special effect for one column
+% or a small \env{multicol} environment. (See section \ref{sec:patterns} for a
+% way to limit the change to one or a few columns.) Overprinting and other
+% bizarre effects can result from extending the rule in the wrong place.
+% Negative values for both keys may be more generally useful, as they have the
+% effect of shrinking the rule. This behavior is illustrated with the rule for
+% this section.
+%
+% The \kvdesc{expand} and \kvdesc{shift} keys provide shorthands for two
+% common situations. You can use \kvdesc{expand} to set the same value for
+% \kvdesc{extend-top} and \kvdesc{extend-bot} For example, |expand=-16pt| is
+% equivalent to |extend-bot=-16pt, extend-top=-16pt|. The \kvdesc{shift} key
+% moves the rule downward for positive values and upward for negative ones
+% without changing the overall length of the rule. More precisely, |shift=x|
+% translates to |extend-bot=x, extend-top=-x|. For example, |shift=16pt| is
+% equivalent to |extend-bot=16pt, extend-top=-16pt|.
+%\end{multicols}
+%
+%\begin{multicols}{2}
+% \SetMCRule{line-style=solid,extend-fill}
+% The\stydsc{line-style=solid, extend-fill} \kvdesc{extend-fill} key is a
+% boolean option that, when set to true, will extend the rule to occupy any
+% space between the bottom of the columns and the end of the text area.
+% Providing the key with no value is equivalent to |extend-fill=true|. This
+% option is only relevant for the \env{multicols} environment. It will have
+% no effect with either \env{multicols*} or the plain \LaTeX{} two-column mode.
+%
+% If you want text below and on the same page as the \env{multicols}
+% environment when using \kvdesc{extend-fill}, you can reserve space for it
+% with \kvdesc{extend-reserve}, which takes a dimension expression specifying
+% the vertical space to leave available after the rule. If the value is greater
 % than zero, the height of the extended line will be reduced by the reserved
 % amount plus the value of \cs{multicolsep}. In other words, you only have to
 % specify the actual space you need for the text itself, not the space that 
@@ -717,54 +764,64 @@ and the derived files           multicolrule.ins,
 % probably will find this material spilling onto the next page anyway.
 %\end{multicols}
 %
-%\subsection{Rule Patterns}
+%\subsection{Rule Patterns}\label{sec:patterns}
+% \begin{function}{\DeclareMCRulePattern}
 % \begin{syntax}
-  % |\DeclareMCRulePattern| \marg{name} \marg{key-value list}
-  % \end{syntax}
+% \cs{DeclareMCRulePattern} \marg{name} \marg{key-value list}
+% \end{syntax}
+% \end{function}
 %\DeclareMCRulePattern{left-hand}{custom-tile={\HandLeft}{8pt}{8pt}}
 %\DeclareMCRulePattern{right-hand}{custom-tile={\HandRight}{8pt}{8pt}}
 %\begin{multicols}{3}
 % \noindent \DescribeMacro{\DeclareMCRulePattern}
 % \SetMCRule{patterns={right-hand,left-hand}}
 % A\stydsc{patterns=\{right-hand, left-hand\}\\ See the code sample below for
-% the definitions of the patterns} ``pattern'' refers to a bundle of settings used by \mcrule. You can declare
-% a pattern for a line style with the command \cs{DeclareMCRulePattern}. The
-% \meta{name} should consist of letters and hyphens only. The
-% \meta{key-value list} can contain all keys that are valid for \cs{SetMCRule}
-% with the exception of \kvdesc{patterns}. If you put something like
-% |patterns=foo| in the definition of a pattern, you won't get an error, but it
-% will be ignored.
+% the definitions of the patterns} \emph{pattern} refers to a bundle of
+% settings used by \mcrule. Although you can use patterns as a shortcut to save
+% you a little typing, their main purpose is to let you to alter individual
+% rules within a multicol environment. For example, if you have three-column
+% text, you can make the left rule different from the right one. In two-column
+% text, you can have different rules for alternating pages.
+%
+% You declare a pattern for a line style with the command
+% \cs{DeclareMCRulePattern}. The \meta{name} should consist of letters and
+% hyphens only. The \meta{key-value list} can contain all keys that are valid
+% for \cs{SetMCRule} with the exception of \kvdesc{patterns}, which is filtered
+% out. In other words, if you put something like |patterns=foo| in the
+% pattern definition, it will be ignored.
 %
 % Once you have declared a pattern, you can use it as a value for the
 % \kvdesc{patterns} argument of \cs{SetMCRule}. This key can accept either a
 % single pattern or a comma-separated list of patterns. If you use a
 % comma-separated list, make sure you enclose it in braces.
 %
-% When a pattern is in effect, its settings are applied on top of whatever
-% the prior settings are. If you set the key to an empty list, any patterns
-% currently in effect will be canceled, and \mcrule{} will revert to the
-% previous settings.
+% When a pattern is in effect, its settings are applied on top of the prior
+% settings. If you set the key to an empty list, any patterns currently in
+% effect will be canceled, and \mcrule{} will revert to the previous settings.
 %
 % If the \kvdesc{patterns} key contains more than one pattern, \mcrule{} will
 % cycle through the list of patterns, using one pattern each time a rule is
-% drawn between columns. (Note, the patterns do not cycle within a single
-% column separator if you use the \kvdesc{repeat} key.) This cycle is global,
-% so if the number columns is not a multiple of the number of patterns and you
-% start a new \env{multicols} environment with the same patterns in effect, the
-% cycle will pick up where it left off. Every time you set new patternss,
-% however, the cycle begins anew.
-%
+% drawn between columns. Note that the patterns do not cycle within a single
+% column separator if you use the \kvdesc{repeat} key. This cycle is global,
+% so if the number column separators is not a multiple of the number of
+% patterns and you start a new \env{multicols} environment with the same
+% patterns in effect, the cycle will pick up where it left off. Every time you
+% set new patterns, however, the cycle begins anew with the first pattern in
+% the list.
 %\end{multicols}
 %
-% The columns above were defined with the following:
-%\begin{verbatim}
+% \noindent The columns above were defined with the following commands:
+%
+% \medskip
+%
+% \begin{BVerbatim}
 % \DeclareMCRulePattern{left-hand}{custom-tile={\HandLeft}{8pt}{8pt}}
 % \DeclareMCRulePattern{right-hand}{custom-tile={\HandRight}{8pt}{8pt}}
 % \begin{multicols}{3}
 %   \SetMCRule{patterns={right-hand,left-hand}}
 %   ...
 % \end{multicols}
-%\end{verbatim}
+% \end{BVerbatim}
 %
 %\DeclareMCRulePattern{shrink-me}{line-style=solid,extend-top=-3\baselineskip}
 %\begin{multicols}{3}
@@ -789,7 +846,7 @@ and the derived files           multicolrule.ins,
 % For example, suppose you have four-column text and want to alter the third
 % column separator on the first page of the environment only.\footnote{Remember
 % that you have one less column separator than you have columns.} You could
-% accomplish this task with the code above.
+% accomplish this task with the code below.
 %
 % Using predefined patterns adds processing overhead, since they must be
 % applied each time the rule is drawn. Therefore it is more efficient to avoid
@@ -798,20 +855,24 @@ and the derived files           multicolrule.ins,
 % unlikely to notice too much delay.
 %
 % Note that any settings you provide in the same command where you apply a 
-% \kvdesc{patterns} key do not alter definition of the pattern. If you do this,
-% you are altering the settings in effect before the pattern is applied.
+% \kvdesc{patterns} key do not alter definition of the pattern, even if they
+% come after the \kvdesc{patterns} key. Such settings will take effect before
+% the pattern is applied and will reappear after the pattern ends, if it does.
 %
 %\end{multicols}
-
-% Shrinking the final two column separators in four-column text:
-%\begin{verbatim}
+%
+% \noindent Shrinking the final two column separators in four-column text:
+%
+% \medskip
+%
+%\begin{BVerbatim}
 % \DeclareMCRulePattern{shrink-me}{line-style=solid,
 %    extend-top=-3\baselineskip}
 % \begin{multicols}{4}
 %   \SetMCRule{patterns=shrink-me,pattern-after=1,pattern-for=2}
 %   ...
 % \end{multicols}
-%\end{verbatim}
+%\end{BVerbatim}
 %
 %\end{documentation}
 %
@@ -830,7 +891,7 @@ and the derived files           multicolrule.ins,
 %\subsection{Preliminaries}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage {multicolrule} {2019/01/01} {1.2}
+\ProvidesExplPackage {multicolrule} {2019/10/01} {1.3}
   {Decorative vertical rules between columns}
 %    \end{macrocode}
 %
@@ -932,23 +993,50 @@ and the derived files           multicolrule.ins,
 \ProcessKeysOptions{mcrule-opts}
 %    \end{macrocode}
 %
-% \subsection{Patching Output Routines}
+% \subsection{Patching Output Routines}\label{sec:patching}
+% Now that we know what mode we're going to run in, we patch the output
+% routine(s) to substitute our custom rule for the vanilla one. Since
+% \pkg{multicol} doesn't fully support twocolumn mode, we patch one or the
+% other, but not both. 
 %
-%\begin{function}{\@@_column_height:,\@@_column_depth:}
+% First we set some stubs for functions we'll need to redirect depending on
+% the mode we're operating in.
 %
-% Get the height and depth of the box appropriate to the supported mode.
+%\begin{macro}{\@@_column_height:}
+% Returns the fixed height of the columns. The actual code to calculate the
+% height is set when we set the appropriate mode.
 %
 %    \begin{macrocode}
 \cs_new:Npn \@@_column_height: {}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_column_depth:}
+% Returns the maximum depth of the columns. The actual code to calculate the
+% depth is set when we set the appropriate mode.
+%
+%    \begin{macrocode}
 \cs_new:Npn \@@_column_depth: {}
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_patch_mcol_output:N}
-% Now that we know what mode we're going to run in, we patch the output
-% routine(s) to substitute our custom rule for the vanilla one. Since
-% \pkg{multicol} doesn't fully support twocolumn mode, we patch one or the
-% other, but not both. As of version 1.2, we make \cs{columnseprulecolor}
+%\begin{macro}{\@@_column_overflow:}
+% Returns the amount by which text overflows the bottom of the columns. This
+% situation occurs in \pkg{multicol} when \cs{maxbalancingoverflow} is greater
+% than 0 (by default it's 12pt) and there would otherwise be a widow at the end
+% of the environment, so we don't check for it in two-column mode.
+% \changes{v1.2a}{2019/2/12}{New internal function}
+%
+%    \begin{macrocode}
+\cs_new:Npn \@@_column_overflow: {0pt}
+%    \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@_patch_mcol_output:N}
+% We create a helper macro to simplify patching the appropriate part of the
+% relevant \pkg{multicol} routines. The search and replace texts are identical
+% across several routines, so only the name of the function to be patched
+% needs to be passed as a parameter. We make \cs{columnseprulecolor}
 % part of \cs{mcruledivider} so that we can set the color as part of a
 % style pattern.
 % \changes{v1.2}{2019/1/1}{Move \cs{columnseprulecolor} inside
@@ -962,9 +1050,9 @@ and the derived files           multicolrule.ins,
   {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_patch_twocol_output:N}
+%\begin{macro}{\@@_patch_twocol_output:N}
 % The same idea as above, only for the vanilla twocolumn mode.
 % \changes{v1.2}{2019/1/1}{Move \cs{columnseprulecolor} inside
 %   \cs{mcruledivider}}
@@ -977,7 +1065,9 @@ and the derived files           multicolrule.ins,
   {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
+%
+% Now the actual patching begins.
 %
 %    \begin{macrocode}
 \bool_if:NTF \g_@@_twocolumn_bool
@@ -985,15 +1075,23 @@ and the derived files           multicolrule.ins,
   \@ifpackageloaded{multicol}
   {\msg_warning:nn {multicolrule} {multicol-loaded}}{}
 %    \end{macrocode}
-% Provide the column-color macro from \pkg{multicol}.
+%
+% Default \LaTeX{} lacks \cs{columnseprulecolor}, so if we're in two-column
+% mode, we provide it here.
+%
 %    \begin{macrocode}
   \cs_gset:Npn \columnseprulecolor {\normalcolor}
+%    \end{macrocode}
+%
+% In vanilla twocolumn mode, the column height and depth can be taken directly
+% from \cmd{\@outputbox}.
+%
+%    \begin{macrocode}
   \cs_gset:Npn \@@_column_height: {\box_ht:N \@outputbox}
   \cs_gset:Npn \@@_column_depth: {\box_dp:N \@outputbox}
-  \@@_patch_twocol_output:N \@outputdblcol
 %    \end{macrocode}
 %
-% Now patch the relevant code in |\@outputdblcol|, replacing the hard-coded
+% Now patch the relevant code in \cmd{\@outputdblcol}, replacing the hard-coded
 % rule with a macro that we can overwrite.
 %
 %    \begin{macrocode}
@@ -1004,6 +1102,7 @@ and the derived files           multicolrule.ins,
 % after \pkg{xcolor}, \pkg{tikz}, \emph{and} \pkg{multicol}, so it must always
 % be loaded after us. We use \cs{AfterPackage} from \pkg{scrlfile} to insert
 % the patch if \pkg{bidi} is loaded later on.
+%
 %    \begin{macrocode}
   \AfterPackage!{bidi}
   {
@@ -1022,14 +1121,48 @@ and the derived files           multicolrule.ins,
   \@@_patch_mcol_output:N \RL@column@boxes
 %    \end{macrocode}
 %
-% Although taking the height of \cmd{\mult@rightbox} is a reliable way
-% to get the column height, the same isn't true for the depth, so we
-% use |\dimen\tw@|, which \pkg{multicol} uses to hold the maximum
-% depth of all the columns, instead.
+% In LTR mode, we are invoked after a column has been typeset, which destroys
+% their boxes in the process. So the only boxes we can be sure still exist are
+% \cmd{\mult@rightbox}, which will be set to the same column height as all the
+% others, and \cmd{\mult@nat@firstbox}, which contains the first column at its
+% natural height.
 %
 %    \begin{macrocode}
-  \cs_gset:Npn \@@_column_height: {\box_ht:N \mult@rightbox}
-  \cs_gset:Npn \@@_column_depth: {\dimen\tw@}
+  \cs_gset:Npn \@@_column_height:
+  {
+    \box_ht:N \mult@rightbox 
+  }
+%    \end{macrocode}
+%
+% Since the depth can differ from column to column, we use |\dimen\tw@|,
+% which \pkg{multicol} uses to hold the maximum depth of all the columns
+% already typeset, but as it won't have reached the final one yet, we check
+% that too. This could lead to an inconsistent height in the event that
+% there are 3 or more columns and a middle column has a significantly larger
+% depth than either the previous columns or the last column, but for now it
+% does not seem worth accounting for a condition that is likely to be very
+% rare in actual user documents.
+% \changes{v1.2a}{2019/2/12}{Check depth of final column}
+%
+%    \begin{macrocode}
+  \cs_gset:Npn \@@_column_depth:
+  {
+    \dim_max:nn {\dimen\tw@}{\box_dp:N \mult@rightbox}
+  }
+%    \end{macrocode}
+%
+% To avoid widows, \pkg{multicol} allows some overflow, by default up to 12pt,
+% and so it's possible that some text will overflow beyond the fixed bottom of
+% the column. In this case, our rule won't descend far enough. To correct, we
+% measure the column overflow as the difference between the natural height of
+% the first box and the height of the last column, and add that amount if it's
+% greater than 0pt.
+%
+%    \begin{macrocode}
+\cs_gset:Npn \@@_column_overflow:
+{
+  \dim_max:nn {\box_ht:N \mult@nat@firstbox - \box_ht:N \mult@rightbox}{0pt}
+}
 %    \end{macrocode}
 %
 % We need to reissue \cs{LRmulticolcolumns} to update the actual code in
@@ -1045,9 +1178,8 @@ and the derived files           multicolrule.ins,
 % columns in right-to-left order, and the effect is to leave the original
 % \pkg{multicol} definitions loaded but unused. As a result, after these
 % changes, the \pkg{multicol} commands \cs{LRmulticolcolumns} and
-% \cs{RLmulticolcolumns} have no visible effect. But as \pkg{bidi} also
-% reworks the footnotes extensively, it's easier just to patch the equivalent
-% output routines rather than rewrite it properly.
+% \cs{RLmulticolcolumns} have no visible effect. First we replace
+% \pkg{bidi}'s copies of the column boxes routines with our patched version.
 %
 %    \begin{macrocode}
   \AfterPackage!{bidi}
@@ -1065,28 +1197,24 @@ and the derived files           multicolrule.ins,
   }
 }
 %    \end{macrocode}
-% 
 %
 % \subsection{Creating the Rules}
-% Utility functions for different rule types
-%
-%\begin{macro}{\mcruledivider}
+% Now we declare utility functions for different rule types.
 %
-% This is the function directly called by the patched output routines. It
-% has a \LaTeX2 name so the user can redefine it if necessary. Its main
-% function is to call the internal function \cs{mcrule_divider:}, which contains
+%\begin{function}{\mcruledivider}
+% This is the function directly called by the patched output routines. Its main
+% purpose is to call the internal function \cs{mcrule_divider:}, which contains
 % the actual rule-typesetting instructions, the number of times specified in
-% \cs{l_@@_repeat_int}.  \pkg{multicol} puts the rule in a group
-% in order to keep the color contained, which means that any local changes
-% here will be lost at the end of the rule. For this reason, we must set the
-% pattern, if any, here in order to support having different line styles
-% between different columns.
+% \cs{l_@@_repeat_int}. \pkg{multicol} puts the rule in a group in order to keep
+% the color contained, which means that any local changes here will be lost at
+% the end of the rule. For this reason, we must set the pattern, if any, here in
+% order to support having different line styles between different columns.
 %
-% \changes{v1.2}{2019/1/1}{Add pattern support}
 %    \begin{macrocode}
 \cs_new_protected:Npn \mcruledivider
 {
 %    \end{macrocode}
+% \changes{v1.2}{2019/1/1}{Add pattern support}
 % If the |pattern-after| counter is set, wait that many iterations of the rule
 % before we apply the patterns.
 %    \begin{macrocode}
@@ -1096,9 +1224,11 @@ and the derived files           multicolrule.ins,
   }
   {
 %    \end{macrocode}
+%
 % Don't change if the pattern is empty or the |pattern-for| counter has
 % expired. The way the logic works here, negative values of |pattern-for|
 % result in an indefinite number of repeats.
+%
 %    \begin{macrocode}
     \bool_lazy_and:nnT
     {\int_compare_p:nNn {\seq_count:N \l_@@_pattern_list_seq} > {\c_zero_int}}
@@ -1110,7 +1240,8 @@ and the derived files           multicolrule.ins,
       {
         \int_gset:Nn \g_@@_pattern_count_int {\c_one_int}
       }
-      \tl_set:Nx \l_tmpa_tl {\seq_item:Nn \l_@@_pattern_list_seq {\g_@@_pattern_count_int} }
+      \tl_set:Nx \l_tmpa_tl {\seq_item:Nn \l_@@_pattern_list_seq
+        {\g_@@_pattern_count_int} }
       \tl_if_blank:VF \l_tmpa_tl
       {
         \@@_set_pattern:V \l_tmpa_tl
@@ -1122,13 +1253,17 @@ and the derived files           multicolrule.ins,
     }
   }
 %    \end{macrocode}
+%
 % Now that the pattern has been changed we can set the color.
+%
 %    \begin{macrocode}
   \columnseprulecolor
 %    \end{macrocode}
+%
 % We only call \cs{mcrule_divider:} if \cs{columnseprule} $>0$, so that all
 % line styles can be turned off by setting it to 0, just as is the case with
 % the vanilla rules.
+%
 %    \begin{macrocode}
   \bool_lazy_and:nnT
   {\dim_compare_p:nNn {\columnseprule} > {\c_zero_dim}}
@@ -1143,24 +1278,27 @@ and the derived files           multicolrule.ins,
   }
 }
 %    \end{macrocode}
-%\end{macro}
+%\end{function}
 %
-%\begin{function}{\@@_column_total_height:,\@@_column_total_depth:}
+%\begin{macro}{\@@_column_total_height:,\@@_column_total_depth:}
 % Get column height and depth with any explicit alterations.
+% \changes{v1.2a}{2019/2/12}{Account for overflow text}
+% 
 %    \begin{macrocode}
 \cs_new:Npn \@@_column_total_height:
 {
   \dim_eval:n {\@@_column_height: + \@@_column_depth: + 
-    \@@_extend_column_top: + \@@_extend_column_bottom:}
+    \@@_extend_column_top: + \@@_column_overflow: + \@@_extend_column_bottom:}
 }
 \cs_new:Npn \@@_column_total_depth:
 {
-  \dim_eval:n {\@@_column_depth: + \@@_extend_column_bottom:}
+  \dim_eval:n {\@@_column_depth: + \@@_column_overflow: +
+    \@@_extend_column_bottom:}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_extend_column_top:}
+%\begin{macro}{\@@_extend_column_top:}
 % Currently, the extend amount for the top is just the 
 % |\l_@@_extend_top_dim| distance. In the future we may allow more complex
 % criteria, such as by odd or even page, or on a particular page. Although
@@ -1172,9 +1310,9 @@ and the derived files           multicolrule.ins,
   \l_@@_extend_top_dim
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_extend_column_bottom:}
+%\begin{macro}{\@@_extend_column_bottom:}
 % The |extend-fill| option, which is only applicable with \pkg{multicol},
 % extends the rule from the bottom of the column to the end of the text area,
 % minus whatever reserved space the user specifies. If there's less space
@@ -1194,9 +1332,9 @@ and the derived files           multicolrule.ins,
   {\l_@@_extend_bot_dim}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_extend_reserve:}
+%\begin{macro}{\@@_extend_reserve:}
 % The reserved space is the amount of user-provided space we want, but we also
 % have to account for the space added with \cs{multicolsep}.
 %    \begin{macrocode}
@@ -1207,7 +1345,7 @@ and the derived files           multicolrule.ins,
   {\c_zero_dim}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
 %\begin{function}{\mcrule_divider:}
 % This is the routine that contains the instructions to draw one copy
@@ -1219,14 +1357,15 @@ and the derived files           multicolrule.ins,
 %    \end{macrocode}
 %\end{function}
 %
-%\begin{function}{\@@_pattern:nnn}
+%\begin{macro}{\@@_pattern:nnn}
 %  \begin{syntax}
-%    |\__mcrule_pattern:nnn| \Arg{pattern} \Arg{space above} \Arg{space below}
+%    \cs{@@_mcrule_pattern:nnn} \Arg{pattern} \Arg{space above} \Arg{space below}
 %  \end{syntax}
 % Typesets a single copy of a pattern, vertically centered, in a vertical
 % box that is the height of the current column. The pattern must be
-% something that can go in a horizontal box. The spaces above and below
-% must be fixed dimensions. 
+% something that can go in a horizontal box. The \meta{space above} and
+% \meta{space below} arguments must be dimension expressions.
+% \changes{v1.2a}{2018/1/2}{Allow evaluated dimensions for kerns}
 %    \begin{macrocode}
 \cs_new_nopar:Npn \@@_pattern:nnn #1#2#3
 {
@@ -1235,22 +1374,25 @@ and the derived files           multicolrule.ins,
     \vbox_to_ht:nn {\@@_column_total_height:}
     {
       \tex_vfill:D
-      \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
+      \tex_kern:D \dim_eval:n {#2} \exp_stop_f:
+      \hbox:n{#1}
+      \tex_kern:D \dim_eval:n {#3} \exp_stop_f:
       \tex_vfill:D
     }
   }
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_tile_pattern:nnn}
+%\begin{macro}{\@@_tile_pattern:nnn}
 %  \begin{syntax}
-%    |\__mcrule_tile_pattern:nnn| \Arg{pattern} \Arg{space above} \Arg{space below}
+%    \cs{mcrule_tile_pattern:nnn} \Arg{pattern} \Arg{space above} \Arg{space below}
 %  \end{syntax}
 % Typesets multiple copies of pattern, tiled so as to occupy a vertical box
 % that is the height of the current column. The pattern must be something
-% that can go in a horizontal box. The spaces above and below must be fixed
-% dimensions. 
+% that can go in a horizontal box. The \meta{space above} and
+% \meta{space below} arguments must be dimension expressions.
+% \changes{v1.2a}{2018/1/2}{Allow evaluated dimensions for kerns}
 %    \begin{macrocode}
 \cs_new_nopar:Npn \@@_tile_pattern:nnn #1#2#3
 {
@@ -1260,24 +1402,27 @@ and the derived files           multicolrule.ins,
     {
       \tex_cleaders:D \vbox:n
       {
-        \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
+        \tex_kern:D \dim_eval:n {#2} \exp_stop_f:
+        \hbox:n{#1}
+        \tex_kern:D \dim_eval:n {#3} \exp_stop_f:
       }
     \tex_vfill:D
     }
   }
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_line_pattern:nnnn}
+%\begin{macro}{\@@_line_pattern:nnnn}
 %  \begin{syntax}
-%    |\__mcrule_line_pattern:nnnn| \Arg{tikz-name} \Arg{height} \Arg{space above}
+%    \cs{@@_mcrule_line_pattern:nnnn} \Arg{tikz-name} \Arg{height} \Arg{space above}
 %      \Arg{space below}
 %  \end{syntax}
 % This function can draw a line pattern using either a \pkg{tikz} name or
 % directly (as a tiled pattern). The latter case is currently limited to line
 % patterns that can be described in terms of a solid line of length
 % \meta{height} separated by spaces above and/or below the line.
+%
 %    \begin{macrocode}
 \cs_new:Npn \@@_line_pattern:nnnn #1#2#3#4
 {
@@ -1290,9 +1435,9 @@ and the derived files           multicolrule.ins,
   }
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_solid_line:}
+%\begin{macro}{\@@_solid_line:}
 % Unlike the default solid line, which is created with a simple \tn{vrule},
 % this version allows us to extend the line beyond the natural space of the
 % column.
@@ -1302,7 +1447,18 @@ and the derived files           multicolrule.ins,
   \rule[-\@@_column_total_depth:]{\columnseprule}{\@@_column_total_height:}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
+%
+%\begin{macro}{\@@_strut:}
+% Uses a zero-width rule, regardless of the actual value of \cs{columnseprule}.
+% \changes{v1.3}{2019/10/1}{New function}
+%    \begin{macrocode}
+\cs_new:Npn \@@_strut:
+{
+  \rule[-\@@_column_total_depth:]{0pt}{\@@_column_total_height:}
+}
+%    \end{macrocode}
+%\end{macro}
 %
 % \subsubsection{Tikz-only Routines}
 %
@@ -1318,7 +1474,7 @@ and the derived files           multicolrule.ins,
   \ExplSyntaxOn  
 %    \end{macrocode}
 % 
-%\begin{function}{\@@_tikz_picture:n}
+%\begin{macro}{\@@_tikz_picture:n}
 %  \begin{syntax}
 %    |\__mcrule_tikz_picture:n| \Arg{draw function}
 %  \end{syntax}
@@ -1337,11 +1493,11 @@ and the derived files           multicolrule.ins,
     \end{tikzpicture}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_pattern_line:n}
+%\begin{macro}{\@@_pattern_line:n}
 %  \begin{syntax}
-%    |\__mcrule_pattern_line:n| \Arg{tikz pattern}
+%    \cs{@@_mcrule_pattern_line:n} \Arg{tikz pattern}
 %  \end{syntax}
 % For the \pkg{tikz} versions of the predefined lines, we just draw
 % a line the length of the column box. \meta{tikz pattern} should 
@@ -1355,9 +1511,9 @@ and the derived files           multicolrule.ins,
   \end{tikzpicture}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_circle:}
+%\begin{macro}{\@@_circle:}
 % Draw a hollow circle with a diameter equal to |\columnseprule|. This will be
 % used as a tile pattern.
 %
@@ -1369,9 +1525,9 @@ and the derived files           multicolrule.ins,
     \end{tikzpicture}
   }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_solid_circle:}
+%\begin{macro}{\@@_solid_circle:}
 % Draw a filled circle with a diameter equal to |\columnseprule|. This will be
 % used as a tile pattern.
 %
@@ -1384,7 +1540,7 @@ and the derived files           multicolrule.ins,
   } 
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
 % In case \pkg{tikz} functions are not active, we provide stubs
 % that issue error messages.
@@ -1403,7 +1559,7 @@ and the derived files           multicolrule.ins,
 %    \end{macrocode}
 %
 % \subsection{Color}
-%\begin{function}{\@@_set_rule_color:}
+%\begin{macro}{\@@_set_rule_color:}
 % Reset color definition in \cs{columnseprulecolor} by name or
 % by model and color specification.
 %
@@ -1424,11 +1580,11 @@ and the derived files           multicolrule.ins,
   }
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
 % \subsection{Patterns}
 %
-%\begin{function}{\@@_set_pattern_list:n}
+%\begin{macro}{\@@_set_pattern_list:n}
 % Sets a comma-separated list of patterns as a sequence for later use. The
 % global counter that indicates where we are in the list is also reset here, so
 % setting a list of patterns always means that the next rule will use the first
@@ -1442,9 +1598,9 @@ and the derived files           multicolrule.ins,
   \int_gset:Nn \g_@@_pattern_for_int {-1}
 }
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
-%\begin{function}{\@@_set_pattern:n}
+%\begin{macro}{\@@_set_pattern:n}
 %  
 % Set the keys an individual pattern. To avoid potential recursion and loops,
 % we filter out the key `pattern' when it appears in a pattern definition.
@@ -1462,7 +1618,7 @@ and the derived files           multicolrule.ins,
 }
 \cs_generate_variant:Nn \@@_set_pattern:n {V}
 %    \end{macrocode}
-%\end{function}
+%\end{macro}
 %
 % \subsection{Key-Values}
 % Set up all the key definitions. For the line styles, this involves
@@ -1471,6 +1627,7 @@ and the derived files           multicolrule.ins,
 %   extend-reserve keys}
 % \changes{v1.2}{2019/1/1}{Added patterns, pattern-after, and pattern-for
 %   keys}
+% \changes{v1.2a}{2019/2/12}{Added expand and shift shortcuts}
 %
 %    \begin{macrocode}
 \keys_define:nn {mcrule}
@@ -1480,11 +1637,21 @@ and the derived files           multicolrule.ins,
   extend-fill                      .bool_set:N = \l_@@_extend_fill_bool,
   extend-fill                      .default:n = true,
   extend-reserve                   .dim_set:N  = \l_@@_extend_reserve_dim,
+  expand                           .code:n = {    
+    \dim_set:Nn \l_@@_extend_bot_dim {#1}
+    \dim_set:Nn \l_@@_extend_top_dim {#1}
+  },
+  shift                            .code:n = {    
+    \dim_set:Nn \l_@@_extend_bot_dim {#1}
+    \dim_set:Nn \l_@@_extend_top_dim {\fp_to_dim:n {-1 * \l_@@_extend_bot_dim}}
+  },
   line-style                       .choice:,
   line-style / default             .code:n = \cs_set:Npn \mcrule_divider: 
     {\vrule\@width\columnseprule},
   line-style / solid               .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_solid_line:},
+  line-style / strut               .code:n = \cs_set:Npn \mcrule_divider: 
+    {\@@_strut:},
   line-style / dots                .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn {.}{1pt}{1pt}},
   line-style / dense-dots          .code:n = \cs_set:Npn \mcrule_divider: 
@@ -1591,10 +1758,10 @@ and the derived files           multicolrule.ins,
 %\end{macro}
 %
 %\begin{macro}{\DeclareMCRulePattern}
-% Declare a new style pattern. 
 % \begin{syntax}
-% |\DeclareMCRule| \marg{name} \marg{key-value list}
+%   \cs{DeclareMCRule} \Arg{name} \meta{key-value list}
 % \end{syntax}
+% Declare a new style pattern. 
 % If a pattern of that name exists, it will be overwritten silently.
 %    \begin{macrocode}
 \NewDocumentCommand{\DeclareMCRulePattern}{m m}
-- 
cgit v1.2.3

