From 4ae4c0f7b2ba8723d6be3e162b2b500104b60d69 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 4 Oct 2019 20:48:54 +0000 Subject: multicolrule (4oct19) git-svn-id: svn://tug.org/texlive/trunk@52283 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/latex/multicolrule/multicolrule.dtx | 489 ++++++++++++++------- .../source/latex/multicolrule/multicolrule.ins | 3 - 2 files changed, 328 insertions(+), 164 deletions(-) (limited to 'Master/texmf-dist/source/latex/multicolrule') diff --git a/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx b/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx index 85de910089c..ac6d017a183 100644 --- a/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx +++ b/Master/texmf-dist/source/latex/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} diff --git a/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins b/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins index 55b23e68894..6d74aaf21d0 100644 --- a/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins +++ b/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins @@ -50,9 +50,6 @@ and the derived files multicolrule.ins, \file{\jobname.sty}{\from{\jobname.dtx}{package}} } \endbatchfile - % |\DeclareMCRulePattern| \marg{name} \marg{key-value list} - % \end{syntax} - %% Copyright (C) 2018-2019 by Karl Hagen %% %% This file may be distributed and/or modified under the -- cgit v1.2.3