texlive[49579] Master: multicolrule (2jan19)

commits+karl at tug.org commits+karl at tug.org
Wed Jan 2 23:38:45 CET 2019


Revision: 49579
          http://tug.org/svn/texlive?view=revision&revision=49579
Author:   karl
Date:     2019-01-02 23:38:45 +0100 (Wed, 02 Jan 2019)
Log Message:
-----------
multicolrule (2jan19)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/multicolrule/README.md
    trunk/Master/texmf-dist/doc/latex/multicolrule/mcrule-examples.pdf
    trunk/Master/texmf-dist/doc/latex/multicolrule/mcrule-examples.tex
    trunk/Master/texmf-dist/doc/latex/multicolrule/multicolrule.pdf
    trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx
    trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins
    trunk/Master/texmf-dist/tex/latex/multicolrule/multicolrule.sty
    trunk/Master/tlpkg/libexec/ctan2tds

Modified: trunk/Master/texmf-dist/doc/latex/multicolrule/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/multicolrule/README.md	2019-01-02 22:37:52 UTC (rev 49578)
+++ trunk/Master/texmf-dist/doc/latex/multicolrule/README.md	2019-01-02 22:38:45 UTC (rev 49579)
@@ -25,7 +25,7 @@
 
 `makeindex -s gglo.ist -o multicolrule.gls multicolrule.glo`.
 
-This package requires LaTeX3 support to run, and compiling the
-documentation requires a variety of other packages, all of which
-are available on CTAN and any modern installation (TeX Live,
-MiKTeX, etc.).
+This package requires expl3 and xparse.
+  % |\DeclareMCRulePattern| \marg{name} \marg{key-value list}
+  % \end{syntax}
+

Modified: trunk/Master/texmf-dist/doc/latex/multicolrule/mcrule-examples.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/multicolrule/mcrule-examples.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/multicolrule/mcrule-examples.tex	2019-01-02 22:37:52 UTC (rev 49578)
+++ trunk/Master/texmf-dist/doc/latex/multicolrule/mcrule-examples.tex	2019-01-02 22:38:45 UTC (rev 49579)
@@ -1,7 +1,8 @@
 % !TeX program = xelatex
 \documentclass{article}
+\usepackage[left=1in,right=1in,top=1in,bottom=1in]{geometry}
 \usepackage{fontspec}
-\usepackage[tikz]{multicolrule}[2018/12/21]
+\usepackage[tikz]{multicolrule}[2018/12/31]
 \usepackage{lipsum}
 \usepackage{bbding}
 \usepackage{pgfornament}
@@ -152,17 +153,17 @@
 \end{multicols}
 
 \begin{multicols}{2}[Custom Line]
-  \SetMCRule{width=1pt,custom-line={\draw[line width=\columnseprule] (TOP) to [ornament=88] (BOT);}}
-  \lipsum[1]
+  \SetMCRule{width=1pt,custom-line={\path (TOP) to [ornament=88] (BOT);}}
+  \lipsum[1-2]
 \end{multicols}
 
 \setlength{\columnsep}{50pt}
-
-\begin{multicols}{2}[Custom Line (+ 4 repeats), just because we can]
-  \SetMCRule{repeat=4,repeat-distance=4pt,width=1pt,custom-line={\draw[line width=\columnseprule] (TOP) to [ornament=88] (BOT);}}
-  \lipsum[1]
+\begin{multicols}{2}[Custom Line (color gray, 4 repeats), just because we can]
+  \SetMCRule{color=gray,repeat=4,repeat-distance=4pt,width=1pt,custom-line={\path (TOP) to [ornament=88] (BOT);}}
+  \lipsum[1-2]
 \end{multicols}
 
+\newpage
 \subsection*{Extended Rules}
 \setlength{\columnsep}{24pt}
 
@@ -187,10 +188,71 @@
 \end{multicols}
 And something at the end to show the reserved space
 
+\subsection*{Patterns}
+
+\DeclareMCRulePattern{left-hand}{custom-tile={\HandLeft}{8pt}{8pt}}
+\DeclareMCRulePattern{right-hand}{custom-tile={\HandRight}{8pt}{8pt}}
+\DeclareMCRulePattern{shrinking}{line-style=solid,color=blue,extend-top=-16pt}
+\begin{multicols}{3}[Alternating Patterns]
+  \SetMCRule{patterns={right-hand,left-hand}}
+  \lipsum[1-3]
+\end{multicols}
+
+\begin{multicols}{3}[Shrink and color first rule only]
+  \raggedcolumns
+  \SetMCRule{patterns=shrinking,pattern-for=1}
+  \lipsum[1-2]
+\end{multicols}
+
+\begin{multicols}{4}[Shrink and color second and third rules only]
+  \raggedcolumns
+  \SetMCRule{patterns=shrinking,pattern-after=1,pattern-for=2}
+  \lipsum[1-2]
+\end{multicols}
+
+\DeclareMCRulePattern{circlei}{width=3pt,line-style=loose-solid-circles,color=black}
+\DeclareMCRulePattern{circleii}{width=6pt,line-style=loose-solid-circles,color=black!75}
+\DeclareMCRulePattern{circleiii}{width=9pt,line-style=loose-solid-circles,color=black!50}
+\DeclareMCRulePattern{circleiv}{width=12pt,line-style=loose-solid-circles,color=black!25}
+\SetMCRule{patterns={circlei,circleii,circleiii,circleiv}}
+\begin{multicols}{4}[Growing and fading circles]
+  \raggedcolumns
+  \lipsum[1-2]
+\end{multicols}
+
+\begin{multicols}{4}[The same, pattern cycling across environment boundary]
+  \raggedcolumns
+  \lipsum[1-2]
+\end{multicols}
+
+
+\DeclareMCRulePattern{blue-double}{width=thick,line-style=solid,color=blue,double=3pt}
+\DeclareMCRulePattern{orange-triple}{width=thick,line-style=solid,color=orange,triple=3pt}
+\begin{multicols}{2}[Nested multicols environments]
+\SetMCRule{patterns={blue-double,blue-double,orange-triple}}
+
+\lipsum[1][1-5]
+
+\begin{multicols}{2}
+\lipsum[1][1-3]
+\end{multicols}  
+
+\lipsum[1][1-5]
+
+\lipsum[1][1-5]
+
+\begin{multicols}{2}
+\lipsum[1][1-3]
+\end{multicols}  
+
+\lipsum[1][1-5]
+
+\end{multicols}
+
 \subsection*{RTL Test}
 
-  \RLmulticolcolumns
-
+\RLmulticolcolumns
+\SetMCRule{patterns={}}
 \begin{multicols}{2}[Reverse Columns Only]
   \SetMCRule{custom-tile={+}{8pt}{8pt}}
   \lipsum[1]

Modified: trunk/Master/texmf-dist/doc/latex/multicolrule/multicolrule.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx	2019-01-02 22:37:52 UTC (rev 49578)
+++ trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.dtx	2019-01-02 22:38:45 UTC (rev 49579)
@@ -1,5 +1,4 @@
 % \iffalse meta-comment
-% !TEX program  = pdfLaTeX
 %<*internal>
 \iffalse
 %</internal>
@@ -31,10 +30,7 @@
 
 `makeindex -s gglo.ist -o multicolrule.gls multicolrule.glo`.
 
-This package requires LaTeX3 support to run, and compiling the
-documentation requires a variety of other packages, all of which
-are available on CTAN and any modern installation (TeX Live,
-MiKTeX, etc.).
+This package requires expl3 and xparse.
 %</readme>
 %<*internal>
 \fi
@@ -58,7 +54,7 @@
 
 \endpreamble
 \postamble
-Copyright (C) 2018 by Karl Hagen <latex at polysyllabic.com>
+Copyright (C) 2018-2019 by Karl Hagen <latex at polysyllabic.com>
  
 This file may be distributed and/or modified under the
 conditions of the LaTeX Project Public License (LPPL), either
@@ -110,6 +106,7 @@
 \usepackage{microtype}
 \usepackage[tikz]{multicolrule}
 \usepackage{longtable}
+\usepackage{ragged2e}
 \usepackage{scrlayer-scrpage}
 \usepackage{scrlayer-notecolumn}
 \usepackage{bbding}
@@ -118,17 +115,18 @@
 \automark[subsection]{section}
 \DeclareNewNoteColumn[
   reversemarginpar,
-  font=\color{Navy}\footnotesize\sffamily
+  font=\color{Navy}\footnotesize\ttfamily
 ]{illustration}
 \ProvideDocumentCommand\opt{m}{\texttt{#1}}
 \NewDocumentCommand{\stydsc}{m}{^^A
   \makenote*[illustration]{^^A
     \hspace*{32pt}\parbox{\marginparwidth-32pt}{^^A
-      \raggedright\texttt{#1}}^^A
+      \RaggedRight#1}^^A
   }^^A
 }
 \NewDocumentCommand{\mcrule}{}{\textcolor{Maroon}{multicolrule}}
 \NewDocumentCommand{\kvdesc}{m}{\textcolor{Navy}{\texttt{#1}}}
+\setlength{\parindent}{16pt}
 \setlength{\columnsep}{24pt}
 \SetMCRule{width=thin,color=Maroon,line-style=dots}
 \EnableCrossrefs         
@@ -146,15 +144,22 @@
 %   \bool_lazy_and:nnT,\cs_gset_eq:NN,\bool_if_p:n,\bool_lazy_and:nnTF,
 %   \bool_not_p:n,\bool_new:N,\box_ht:N,\box_dp:N,\box_move_down:nn,
 %   \cs_generate_variant:Nn,\cs_gset:Npn,\cs_new:Npn,
-%   \cs_new_nopar:Npn,\cs_set:Npn,\dim_compare_p:nNn,\dim_new:N,\dim_set:Nn,
+%   \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_p:nNn,\int_new:N,\int_set:Nn,\kern,\keys_define:nn,
-%   \keys_set:nn,\msg_error:nnn,\msg_info:nnn,\msg_new:nnn,\msg_warning:nn,
+%   \int_compare_nNnTF,\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,
+%   \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,
 %   \ProvidesExplPackage,\RequirePackage,\rule,\normalcolor,
-%   \tl_if_empty:NT,\tl_if_empty:NTF,\tl_new:N,\tw@,
-%   \tl_set:Nn,\vbox:n,\vbox_to_ht:nn,\vfill,\vrule,
+%   \seq_count:N,\seq_item:Nn,\seq_new:N,\seq_set_split:Nnn,
+%   \tl_if_blank:VF,\tl_if_empty:NT,\tl_if_empty:NTF,\tl_new:N,\tl_set:Nn,
+%   \tl_set:Nx,\tw@,\vbox:n,\vbox_to_ht:nn,\vfill,\vrule,\l_tmpa_tl,
 %   \cs_new_protected:Npn,\@ifpackageloaded,\@width,\xpatchcmd}
 %
 %\title{^^A
@@ -169,8 +174,11 @@
 %
 %\maketitle
 %
-%\changes{v1.0}{2018/12/15}{Initial public release}
-%\changes{v1.1}{2018/12/21}{Work with \pkg{bidi} and allow extending rules}
+% \changes{v1.0}{2018/12/15}{Initial public release}
+% \changes{v1.1}{2018/12/21}{Support bidi}
+% \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}
 %
 %\begin{abstract}
 % The \mcrule{} package lets you customize the appearance of the vertical rule
@@ -185,9 +193,10 @@
 %\tableofcontents
 %
 %\begin{documentation}
+% \raggedcolumns
 %
-%\begin{multicols}{2}[\section{Introduction}]
-%\SetMCRule{line-style=dashed}
+% \begin{multicols}{2}[\section{Introduction}]
+% \SetMCRule{line-style=dashed}
 %  
 % In\stydsc{line-style=dashed} \LaTeX, there are two lengths that control the
 % formatting between columns of multicolumn text: \cs{columnsep} specifies the
@@ -211,44 +220,49 @@
 % throughout this guide. The default line-width used is 0.4pt (thin), and the
 % default color is \texttt{Maroon}. You can also find examples of rules created
 % with all available options in the file \file{mcrule-example.pdf}.
+% \end{multicols}
 %
+% \begin{multicols}{2}
+% \SetMCRule{custom-line={\path (TOP) to [ornament=85] (BOT);},extend-top=-24pt,
+%   extend-bot=-8pt}
+% \subsection*{New for Version 1.2}
+% Version\stydsc{custom-line=\\\{\textbackslash path (TOP) to [ornament=85]
+%   (BOT);\}, extend-top=-24pt, extend-bot=-8pt} 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.
+% You can also alter the appearance of one or more separators anywhere within
+% the environment (see section \ref{sec:patterns}).
+%
 % \subsection*{New for Version 1.1}
-% Version 1.1 now supports drawing decorative rules if you have the \pkg{bidi}
+% Version 1.1 supports drawing decorative rules if you have the \pkg{bidi}
 % package loaded, which can occur automatically if you set a right-to-left
 % language with \pkg{polyglossia}. It also provides a mechanism to extend or
-% shrink rules by fixed amounts, as well as to have the rule fill the available
-% space to the end of the text area (see section \ref{sec:extend}).
-%
+% shrink rules beyond the natural height of the columns, as well as to have the
+% rule fill the available space to the end of the text area (see section
+% \ref{sec:extend}).
 % \end{multicols}
 %
 % \begin{multicols}{2}[\subsection{Bugs and Known Limitations}]
-% There\stydsc{line-style=dots} are likely bugs that remain to be uncovered,
-% as well as missing features and inefficient methods that should be improved
-% upon. The development code is maintained on github
-% (\url{https://github.com/polysyllabic/multicolrule}), and you can file
+% The\stydsc{line-style=dots} \mcrule{} package is written using expl3 syntax,
+% and so requires a less-than-ancient installation of \LaTeX. It requires the
+% packages \pkg{l3keys2e}, \pkg{xparse}, \pkg{xpatch}, \pkg{xcolor},
+% \pkg{scrlfile}, and depending on the mode of operation may also require
+% \pkg{multicol} and \pkg{tikz}. If you have an up-to-date distribution, these
+% requirements should cause no issues.
+%
+% I am sure that there are bugs that remain to be uncovered, inefficient methods
+% that could stand improvement, and useful features that still need to be
+% implemented. The development code is maintained on
+% \href{https://github.com/polysyllabic/multicolrule}{github}, and you can file
 % feature requests or bug reports there. Alternatively, you can send an email
 % to \href{mailto://latex@polysyllabic.com}{latex at polysyllabic.com}. I welcome
 % contributions for additional styles, especially to provide more options when
 % running the package without \pkg{tikz}.
+%
+% The following are the issues I'm currently aware of that aren't \mcrule{}
+% errors but which may cause buggy looking behavior:
 %  
-% 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
-% below a pattern, but the basic problem is a side-effect of the way these
-% patterns are implemented (with \cs{cleaders}), which means that only an
-% integer number of copies can be produced. Lines drawn with \pkg{tikz} do not
-% have this problem.
-% 
-% I have also noticed occasional instances, most noticeably when a
-% \env{multicols} environment starts near the bottom of a page and the columns
-% continue to the next one, where the rules are either somewhat shorter than
-% they should be or shifted upward from where they belong. In the limited
-% testing I have done, this appears to be a consequence of how \pkg{multicol}
-% works, as the default rules show the same behavior. I may try to nail down
-% this issue in future version, but as it's an edge case that disappears when
-% you add page breaks or rewrite the text to alter how the columns are filled,
-% it hasn't seemed worth taking the time to fix at this point.
-% 
 % This package works by patching the output routines of either \pkg{multicol}
 % or the \LaTeX{} kernel, depending on the mode of operation. If \pkg{bidi} is
 % loaded, it will also patch that. It will have no effect if you use a class or
@@ -259,22 +273,36 @@
 % send me an email or file a feature request on github and I'll see what I can
 % do.
 % 
-% \mcrule{} is written using expl3 syntax, and so requires a less-than-ancient
-% installation of \LaTeX. It uses the packages \pkg{l3keys2e}, \pkg{xparse},
-% \pkg{xpatch}, and \pkg{xcolor}, and depending on the mode of operation may
-% also require \pkg{multicol} and \pkg{tikz}. If you have an up-to-date
-% distribution, these requirements should cause no issues.
+% 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
+% below a pattern, but the basic problem is a side-effect of the way these
+% patterns are implemented (with \cs{cleaders}), which means that only an
+% integer number of copies can be produced. Lines drawn with \pkg{tikz} do not
+% have this problem.
+%
+% 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.
 % \end{multicols}
 %
 % \begin{multicols}{2}[\subsection{License}]
 % \SetMCRule{width=ultra-thick,line-style=dotted}
 % The\stydsc{\texttt{line-style=dotted, width=ultra-thick}} \mcrule{}
-% package is copyright 2018 by Karl Hagen. It may be distributed and/or
+% package is copyright 2018--2019 by Karl Hagen. It may be distributed and/or
 % modified under the conditions of the \LaTeX{} Project Public License, either
 % version 1.3c of this license or (at your option) any later version. The
 % latest version of this license is in
-% \url{http://www.latex-project.org/lppl.txt}.
-%  
+%
+% \medskip
+% \noindent{\footnotesize\url{http://www.latex-project.org/lppl.txt}.}
+% \medskip
+%
 % This work has the LPPL maintenance status `maintained.' The Current
 % Maintainer of this work is Karl Hagen.
 % \end{multicols}
@@ -283,32 +311,16 @@
 % \SetMCRule{line-style=dash-dot}
 %
 % \subsection{Default Operation}
-% If\stydsc{line-style=dash-dot} you load \mcrule{} with its default settings,
-% it will enable \pkg{multicol} support, and that package will be loaded if it
+% Loading\stydsc{line-style=dash-dot} \mcrule{} with its default settings
+% enables \pkg{multicol} support, and that package will be loaded if it
 % hasn't been already. Note that if you need to pass any parameters to
 % \pkg{multicol}, such as |docolaction|, you should load \pkg{multicol} with
 % the appropriate settings \emph{before} you load \mcrule, as \LaTeX{} does not
 % support reloading packages with different parameters.
 % 
-% \subsection{Option `twocolumn'}
-% \DescribeOption{twocolumn}
-% The \mcrule{} package recognizes the option \opt{twocolumn},
-% either as a package option or as a global class option. If you pass this option
-% to your document class, you do not need to pass it a second time to the
-% package. It is only necessary to use the package option if you plan to have a
-% predominantly one-column document and use \cs{twocolumn} to switch
-% temporarily into two-column mode.
-% 
-% Because \pkg{multicol} does not work well with the ordinary two-column
-% mode, \mcrule{} is only designed to work with one or the other at a time. If
-% you try to use the \opt{twocolumn} option when
-% \pkg{multicol} has already been loaded, you will receive a warning, and
-% nothing is guaranteed. But the custom rules will at best only appear in the
-% conventional two-column mode and not within a \env{multicols} environment.
-% 
 % \subsection{Option `tikz'}
 % \DescribeOption{tikz}
-% You have access to a wider set of line styles if you also use the \pkg{tikz}
+% You can use more line styles if you also use the \pkg{tikz}
 % package. Some line styles are only available if \pkg{tikz} is enabled, and
 % others look better with it. The default behavior of \mcrule{} depends on the
 % status of the \pkg{tikz} package at the time \mcrule{} is loaded. If
@@ -319,25 +331,41 @@
 % (or if it is explicitly disabled), the line styles marked \emph{tikz only}
 % in section \ref{sec:linestyles} will be unavailable and errors will result
 % if you try to use them.
+%
+% \subsection{Option `twocolumn'}
+% \DescribeOption{twocolumn}
+% The \mcrule{} package recognizes the option \opt{twocolumn},
+% either as a package option or as a global class option. If you pass this option
+% to your document class, you do not need to pass it a second time to the
+% package. It is only necessary to use the package option if you plan to have a
+% predominantly one-column document and use \cs{twocolumn} to switch
+% temporarily into two-column mode.
+% 
+% Because \pkg{multicol} does not work well with the ordinary two-column
+% mode, \mcrule{} is only designed to work with one or the other at a time. If
+% you try to use the \opt{twocolumn} option when \pkg{multicol} has already
+% been loaded, you will receive a warning and nothing is guaranteed. But the
+% custom rules will at best only appear in the conventional two-column mode and
+% not within a \env{multicols} environment.
 % \end{multicols}
 %
-% \begin{multicols}{2}[\section{The User Interface}]
+% \section{The User Interface}
+% |\SetMCRule| \marg{key-value list}
+%
+% \begin{multicols}{2}
 % \SetMCRule{width=2pt,line-style=circles}
-% The\stydsc{line-style=circles,\\width=2pt} \mcrule{} package has
-% just a single user command:
-%
-% \cs{SetMCRule} \marg{key-value}
-%
-% \noindent It takes one parameter containing a key-value list of all options you
-% want to set. You can issue this command in the preamble or the document body.
-% Changes to the rule settings are local to the current group. For example, if
-% you call \cs{SetMCRule} inside a \env{multicols} environment, the rule
-% settings will revert to their previous values once the environment ends. Also
-% note that any changes made with \cs{SetMCRule} when multiple columns are
-% active will appear starting on the same page as your current location when you
-% issue the command, and will extend the height of the full column box. It is not
-% possible to have a rule change styles in the middle of a page unless you close
-% out one \env{multicols} environment and begin another.
+% \noindent \DescribeMacro{\SetMCRule}
+% The\stydsc{line-style=circles,\\ width=2pt} main user command for \mcrule{} is
+% \cs{SetMCRule}. It takes one parameter containing a key-value list of all
+% options you want to set. You can issue this command in the preamble or the
+% document body. Changes to the rule settings are local to the current group.
+% For example, if you call \cs{SetMCRule} inside a \env{multicols} environment,
+% the rule settings will revert to their previous values once the environment
+% ends. Also note that any changes made with \cs{SetMCRule} when multiple
+% columns are active will appear starting on the same page as your current
+% location when you issue the command, and will extend the height of the full
+% column box. It is not possible to have a rule change styles in the middle of
+% a page unless you close out one \env{multicols} environment and begin another.
 %  
 % Table \ref{table:mcrulekeys} summarizes the keys available in \cs{SetMCRule}.
 % The functions of each is described in detail in the sections that follow.
@@ -375,6 +403,12 @@
 % the column (see sec. \ref{sec:extend})\\
 % \kvdesc{line-style} & Select the type of rule printed 
 % (default=\emph{default}; see sec. \ref{sec:linestyles})\\
+% \kvdesc{pattern-after} & Number of separators to delay before beginning to
+% use the specified patterns (default=0; see sec. \ref{sec:patterns})\\
+% \kvdesc{pattern-for} & Number times separators to apply the patterns to
+% before returning to default (default=$-1$; see sec. \ref{sec:patterns})\\
+% \kvdesc{patterns} & Specify one or more patterns use to draw rules. 
+% (default=\emph{none}; see sec. \ref{sec:patterns})\\
 % \kvdesc{single} & Draw a single copy of the rule (\emph{default};
 % see sec. \ref{sec:repeats})\\
 % \kvdesc{repeat} & Set the number of times to draw the rule (see
@@ -392,17 +426,22 @@
 %   \label{sec:linestyles}]
 %  \SetMCRule{width=4pt,line-style=solid-circles}
 %  
-% You\stydsc{line-style= solid-circles,\\ width=4pt} choose a style for the rule
-% with the \kvdesc{line-style} key.  If the predefined styles are insufficient,
-% see section \ref{sec:custom} for different ways to customize it. The width of
-% most line styles depends on the setting of \cs{columnseprule}, the default
-% \LaTeX{} length that controls the width of the column rule (see section
-% \ref{sec:width}). 
+% You\stydsc{line-style=solid-circles, width=4pt} can choose a style for the
+% rule with the \kvdesc{line-style} key. If the predefined styles are
+% insufficient for your purpose, see section \ref{sec:custom} for different
+% ways to customize the rule in even more radical ways. The width of many line
+% styles scales directly with the setting of \cs{columnseprule}, the default
+% \LaTeX{} length that controls the width of the column rule, but even those
+% that do not, the width must be non-zero for the rule to display (see section
+% \ref{sec:width}).
 %  
 % Table \ref{table:linestyles} summarizes the available line styles. Most of
 % the basic patterns come in three versions, differing only in how closely the
 % pattern is spaced: normal, dense, and loose. These settings parallel those
-% found in \pkg{tikz}.
+% found in \pkg{tikz} and use the same spacing between elements. There are no
+% named settings for double lines and the like because you control that feature
+% separately, with the \kvdesc{repeat} key. All line styles can be repeated as
+% many times as you like (see section \ref{sec:repeats}).
 % \end{multicols}
 %
 % \begin{longtable}{lp{3in}}
@@ -461,7 +500,7 @@
 % \bottomrule
 % \end{longtable}
 %
-% \begin{multicols}{2}[\subsubsection{Notes on the Styles}]
+% \begin{multicols}{2}
 % \SetMCRule{width=thin,line-style=solid} 
 % The\stydsc{line-style=solid} \kvdesc{default} and \kvdesc{solid} line styles
 % are nearly the same, except that the \kvdesc{solid} line (as of version 1.1)
@@ -476,14 +515,12 @@
 % the \kvdesc{width} and \kvdesc{color} keys described in sections
 % \ref{sec:width} and \ref{sec:color}, respectively, or directly by changing
 % the value of \cs{columnseprule} and renewing the \cs{columnseprulecolor}
-% macro. All line styles, including \kvdesc{default}, can be repeated as many
-% times as you like (see section \ref{sec:repeats}).
+% macro.
 %  
 % The \kvdesc{dots} style and its variants are rendered with a period (.) in
-% the currently active font. This means that changing \cs{columnseprule} will
-% not change the size of these dots, although, as with all rules, it will not
-% appear at all if \cs{columnseprule} is set to 0pt. Custom tiles and patterns
-% also do not scale with \cs{columnseprule}.
+% the currently active font. This is one of the styles, mentioned above, that
+% do not change their size as the line width increases. The same is true of
+% custom tiles.
 %
 % The \kvdesc{dotted} styles differ from \kvdesc{dots} in that the former are
 % squares with side lengths equal to \cs{columnseprule}. This mirrors the
@@ -491,9 +528,9 @@
 % \end{multicols}
 %
 % \subsubsection{Custom Patterns}\label{sec:custom}
-%
-% \begin{multicols}{2}[\noindent\texttt{custom-tile=} \marg{pattern} \marg{space above}
-%   \marg{space below}]
+% \noindent\texttt{custom-tile =} \marg{pattern} \marg{space above}
+%   \marg{space below}
+% \begin{multicols}{2}
 % \SetMCRule{custom-tile={\SparkleBold}{16pt}{16pt}}
 %
 % There\stydsc{custom-tile= \{\textbackslash SparkleBold\} \{16pt\}\{16pt\}}
@@ -514,7 +551,7 @@
 % list will be the one that is kept.
 % \end{multicols}
 %
-% \begin{multicols}{2}[\noindent\texttt{custom-pattern=} \marg{pattern} \marg{shift
+% \begin{multicols}{2}[\noindent\texttt{custom-pattern =} \marg{pattern} \marg{shift
 %    down} \marg{shift up}]
 % \SetMCRule{custom-pattern={\HandRight}{0pt}{0pt}} 
 %
@@ -528,26 +565,25 @@
 % uses the \cs{HandRight} symbol from \pkg{bbding}.
 % \end{multicols}
 %
-% \clearpage
-% \begin{multicols}{2}[\noindent\texttt{custom-line=} \marg{draw command}]
-% \SetMCRule{width=1pt,custom-line={\draw[line width=\columnseprule] (TOP) to
-%   [ornament=88] (BOT);}}
+% \begin{multicols}{2}[\noindent\texttt{custom-line =} \marg{draw command}]
+% \SetMCRule{custom-line={\path (TOP) to [ornament=88] (BOT);}}
 %
-% The\stydsc{custom-line=\{ \textbackslash draw[line width= \textbackslash
-%   columnseprule] (TOP) to [ornament=88] (BOT);\},\\width=1pt} third custom
+% The\stydsc{custom-line=\{\textbackslash path (TOP) to [ornament=88]
+%   (BOT);\}} third custom
 % pattern involves setting your own \pkg{tikz} drawing
 % function using the key \kvdesc{custom-line}. The rule in this section is
 % drawn with an ornament from \pkg{pgfornaments}. Obviously, this feature
 % requires \pkg{tikz} support. The value you provide to the
 % \kvdesc{custom-line} key should consist of a \pkg{tikz} command, such as
-% \cs{draw}, without the surrounding \env{tikzpicture} environment.
+% \cs{draw} or \cs{path}, without the surrounding \env{tikzpicture}
+% environment.
 % 
 % Before the drawing command is called, \mcrule{} will set up a
 % \env{tikzpicture} with both the x- and y-coordinates scaled to points, and
 % two nodes, named \texttt{(TOP)} and \texttt{(BOT)}, which are set to the
 % coordinates of the top and bottom of the rule. You can then specify your own
-% \cs{draw} function in whatever way you like. The rule separating these
-% columns was drawn with a decorative element from the \pkg{pgfornaments}
+% \cs{draw} or \cs{path} function in whatever way you like. The rule separating
+% these columns was drawn with a decorative element from the \pkg{pgfornaments}
 % package.
 %
 % This function will use the color set in
@@ -631,7 +667,8 @@
 % adjacent copies of any rule by setting the number of times to draw the rule
 % with the \kvdesc{repeat} key. The space between copies is controlled with the
 % \kvdesc{repeat-distance} key. Initially, this distance is set to
-% \cs{columnseprule}.
+% \cs{columnseprule}. Note that you must enter an actual dimension expression
+% for this distance. The names used for line widths are not accepted.
 %  
 % The keys \kvdesc{single}, \kvdesc{double}, and \kvdesc{triple} are shorthand
 % methods to set the number of repeats and the \kvdesc{repeat-distance} at the
@@ -655,10 +692,11 @@
 % 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 small
-% \env{multicol} environment. 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.
+% 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
@@ -677,8 +715,104 @@
 % you request for reserved space is less than the amount actually available at
 % the end of the page, the rule will not extend below the columns and you
 % probably will find this material spilling onto the next page anyway.
-% 
 %\end{multicols}
+%
+%\subsection{Rule Patterns}
+% \begin{syntax}
+  % |\DeclareMCRulePattern| \marg{name} \marg{key-value list}
+  % \end{syntax}
+%\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.
+%
+% 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.
+%
+% 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.
+%
+%\end{multicols}
+%
+% The columns above were defined with the following:
+%\begin{verbatim}
+% \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}
+%
+%\DeclareMCRulePattern{shrink-me}{line-style=solid,extend-top=-3\baselineskip}
+%\begin{multicols}{3}
+% \SetMCRule{line-style=solid,patterns=shrink-me,pattern-for=1}  
+% If\stydsc{patterns=shrink-me, pattern-for=1\\ See the code sample below for
+% the definition of `shrink-me'} you want to alter the rule only for certain
+% column separators, you can use
+% the \kvdesc{pattern-after} and \kvdesc{pattern-for} keys, both of which
+% take integer values, in conjunction with \kvdesc{patterns}. 
+%
+% The \kvdesc{pattern-for} key means ``use the given pattern or patterns for
+% this many column separators only.'' Afterwards, the pattern will be disabled,
+% meaning that it won't be applied any more and only the settings applied
+% directly will be in effect until it is reset. A negative value to this key
+% means that the patterns will be repeated indefinitely. The default is $-1$.
+%
+% The \kvdesc{pattern-after} key means ``wait until after this many column
+% separators before starting to apply the pattern. The default is 0. If you use
+% it in conjunction with \kvdesc{pattern-for}, the count of modified column
+% separators begins after the skipped columns.
+%
+% 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.
+%
+% Using predefined patterns adds processing overhead, since they must be
+% applied each time the rule is drawn. Therefore it is more efficient to avoid
+% patterns unless you need to actually change the line style from column to
+% column, although if you compile on a reasonably modern computer, you are
+% 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.
+%
+%\end{multicols}
+
+% Shrinking the final two column separators in four-column text:
+%\begin{verbatim}
+% \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{documentation}
 %
 %\begin{implementation}
@@ -696,8 +830,8 @@
 %\subsection{Preliminaries}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage {multicolrule} {2018/12/21} {1.1}
-  {Decorative~vertical~rules~between~columns}
+\ProvidesExplPackage {multicolrule} {2019/01/01} {1.2}
+  {Decorative vertical rules between columns}
 %    \end{macrocode}
 %
 % We always need these packages.
@@ -712,11 +846,14 @@
 %    \begin{macrocode}
 \msg_new:nnn {multicolrule} {patch-success} {Patched~#1.}
 \msg_new:nnn {multicolrule} {patch-failure} {Error~patching~#1.}
-\msg_new:nnn {multicolrule} {tikz-required}
+\msg_new:nnnn {multicolrule} {tikz-required} {Tikz~required}
 {The~'#1'~setting~requires~tikz~to~work.~Either~load~tikz~before~you~load~
   multicolrule~or~use~multicolrule's~'tikz'~package~option.}
-\msg_new:nnn {multicolrule} {multicol-loaded} {You~are~using~the~'twocolumn'~
-  option~with~multicol~already~loaded.~You~will~likely~run~into~problems.}
+\msg_new:nnnn {multicolrule} {multicol-loaded} {Multicol~loaded} {You~are~
+  using~the~'twocolumn'~option~with~multicol~already~loaded.~You~will~likely~
+  run~into~problems.}
+\msg_new:nnnn {multicolrule} {pattern-undefined} {Pattern~undefined}
+  {The~multicolrule~pattern~'#1'~has~not~been~defined.}
 %    \end{macrocode}
 %
 %\begin{variable}{\g_@@_twocolumn_bool,\g_@@_use_tikz_bool}
@@ -759,6 +896,19 @@
 %    \end{macrocode}
 %\end{variable}
 %
+%\begin{variable}{\g_@@_patterns_prop, \g_@@_pattern_count_int,
+% \g_@@_pattern_for_int, \g_@@_pattern_after_int,
+% \l_@@_pattern_list_seq}
+% Variables to support defined patterns.
+%    \begin{macrocode}
+\prop_new:N \g_@@_patterns_prop
+\int_new:N  \g_@@_pattern_count_int
+\int_new:N  \g_@@_pattern_for_int
+\int_new:N  \g_@@_pattern_after_int
+\seq_new:N  \l_@@_pattern_list_seq
+%    \end{macrocode}
+%\end{variable}
+%
 % If \pkg{tikz} is already loaded, enable \pkg{tikz}-sensitive line styles
 % unless the user explicitly disables them. If \pkg{tikz} is not already
 % loaded, these functions are disabled unless they are explicitly loaded.
@@ -794,16 +944,20 @@
 %    \end{macrocode}
 %\end{function}
 %
+%\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.
-%
-%\begin{function}{\@@_patch_mcol_output:N}
+% other, but not both. As of version 1.2, 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
+%   \cs{mcruledivider}}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_patch_mcol_output:N #1
 {
-  \xpatchcmd{#1} {\vrule\@width\columnseprule} {\mcruledivider}
+  \xpatchcmd{#1} {\columnseprulecolor\vrule\@width\columnseprule}
+  {\mcruledivider}
   {\msg_info:nnn {multicolrule} {patch-success} {#1}}
   {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
 }
@@ -811,11 +965,14 @@
 %\end{function}
 %
 %\begin{function}{\@@_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}}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_patch_twocol_output:N #1
 {
   \xpatchcmd{#1} {\normalcolor\vrule\@width\columnseprule}
-  {\columnseprulecolor\mcruledivider}
+  {\mcruledivider}
   {\msg_info:nnn {multicolrule} {patch-success} {#1}}
   {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
 }
@@ -847,7 +1004,6 @@
 % 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}
   {
@@ -916,26 +1072,73 @@
 %
 %\begin{macro}{\mcruledivider}
 %
-% This is the function directly called by the patched output routines. It's
-% given a \LaTeX2 name so the user can redefine it if necessary. Its main
-% function is to call the internal function \cs{_@@_divider:}, which contains
+% 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
 % the actual rule-typesetting instructions, the number of times specified in
-% \cs{l_@@_repeat_int}. We only call \cs{_@@_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.
+% \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:Npn \mcruledivider
+\cs_new_protected:Npn \mcruledivider
 {
+%    \end{macrocode}
+% If the |pattern-after| counter is set, wait that many iterations of the rule
+% before we apply the patterns.
+%    \begin{macrocode}
+  \int_compare:nNnTF {\g_@@_pattern_after_int} > {\c_zero_int}
+  {
+    \int_gdecr:N \g_@@_pattern_after_int
+  }
+  {
+%    \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}}
+    {! \int_compare_p:nNn {\g_@@_pattern_for_int} = {\c_zero_int}}
+    {
+      \int_gincr:N \g_@@_pattern_count_int
+      \int_compare:nNnT {\g_@@_pattern_count_int} >
+       {\seq_count:N \l_@@_pattern_list_seq}
+      {
+        \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_if_blank:VF \l_tmpa_tl
+      {
+        \@@_set_pattern:V \l_tmpa_tl
+      }
+      \int_compare:nNnT {\g_@@_pattern_for_int} > {\c_zero_int}
+      {
+        \int_gdecr:N \g_@@_pattern_for_int
+      }
+    }
+  }
+%    \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} > {0pt}}
-  {\int_compare_p:nNn {\l_@@_repeat_int} > {0}}
+  {\dim_compare_p:nNn {\columnseprule} > {\c_zero_dim}}
+  {\int_compare_p:nNn {\l_@@_repeat_int} > {\c_zero_int}}
   {
-    \@@_divider:
-    \prg_replicate:nn {\l_@@_repeat_int - 1}
+    \mcrule_divider:
+    \prg_replicate:nn {\l_@@_repeat_int - \c_one_int}
     {
       \hspace{\l_@@_repeat_distance_dim}
-      \@@_divider:
+      \mcrule_divider:
     }
   }
 }
@@ -943,9 +1146,7 @@
 %\end{macro}
 %
 %\begin{function}{\@@_column_total_height:,\@@_column_total_depth:}
-%
 % Get column height and depth with any explicit alterations.
-%
 %    \begin{macrocode}
 \cs_new:Npn \@@_column_total_height:
 {
@@ -960,13 +1161,11 @@
 %\end{function}
 %
 %\begin{function}{\@@_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
 % these might theoretically be useful, I'm not going to implement them until
 % someone comes along with a use-case for it.
-%
 %    \begin{macrocode}
 \cs_new:Npn \@@_extend_column_top:
 {
@@ -976,12 +1175,10 @@
 %\end{function}
 %
 %\begin{function}{\@@_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
 % available than requested, we give everything we can.
-%
 %    \begin{macrocode}
 \cs_new:Npn \@@_extend_column_bottom:
 {
@@ -990,9 +1187,9 @@
   {\bool_not_p:n {\g_@@_twocolumn_bool}}
   {
     \dim_compare:nNnTF 
-    {\@colroom - \@@_column_height: - \@@_extend_reserve:} > {0pt}
+    {\@colroom - \@@_column_height: - \@@_extend_reserve:} > {\c_zero_dim}
     {\@colroom - \@@_column_height: - \@@_extend_reserve:}
-    {0pt}
+    {\c_zero_dim}
   }
   {\l_@@_extend_bot_dim}
 }
@@ -1000,28 +1197,25 @@
 %\end{function}
 %
 %\begin{function}{\@@_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}
 \cs_new:Npn \@@_extend_reserve:
 {
-  \dim_compare:nNnTF {\l_@@_extend_reserve_dim} > {0pt}
+  \dim_compare:nNnTF {\l_@@_extend_reserve_dim} > {\c_zero_dim}
   {\dim_eval:n {\l_@@_extend_reserve_dim + \multicolsep}}
-  {0pt}
+  {\c_zero_dim}
 }
 %    \end{macrocode}
 %\end{function}
 %
-%\begin{function}{\@@_divider:}
-% This is the internal routine that contains the instructions to draw one copy
+%\begin{function}{\mcrule_divider:}
+% This is the routine that contains the instructions to draw one copy
 % of rule between columns. The default is identical to the original definition
 % used by \pkg{multicol}. It will be reset each time the user calls
-% \cs{MCSetRule}.
-%
+% \cs{MCSetRule} to specify a new line style.
 %    \begin{macrocode}
-\cs_new:Npn \@@_divider: {\vrule\@width\columnseprule}
+\cs_new:Npn \mcrule_divider: {\vrule\@width\columnseprule}
 %    \end{macrocode}
 %\end{function}
 %
@@ -1033,7 +1227,6 @@
 % 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. 
-% 
 %    \begin{macrocode}
 \cs_new_nopar:Npn \@@_pattern:nnn #1#2#3
 {
@@ -1041,9 +1234,9 @@
   {
     \vbox_to_ht:nn {\@@_column_total_height:}
     {
-      \vfill
-      \kern #2 \hbox:n{#1} \kern #3
-      \vfill
+      \tex_vfill:D
+      \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
+      \tex_vfill:D
     }
   }
 }
@@ -1065,11 +1258,11 @@
   {
     \vbox_to_ht:nn {\@@_column_total_height:}
     {
-      \cleaders \vbox:n
+      \tex_cleaders:D \vbox:n
       {
-        \kern #2 \hbox:n{#1} \kern #3
+        \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
       }
-    \vfill
+    \tex_vfill:D
     }
   }
 }
@@ -1153,7 +1346,6 @@
 % For the \pkg{tikz} versions of the predefined lines, we just draw
 % a line the length of the column box. \meta{tikz pattern} should 
 % contain the name of a line style that \pkg{tikz} recognizes.
-%
 %    \begin{macrocode}
 \cs_set:Npn \@@_pattern_line:n #1
 {
@@ -1234,9 +1426,51 @@
 %    \end{macrocode}
 %\end{function}
 %
+% \subsection{Patterns}
+%
+%\begin{function}{\@@_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
+% pattern in the list.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_pattern_list:n #1
+{
+  \seq_set_split:Nnn \l_@@_pattern_list_seq {,} {#1}
+  \int_gzero:N \g_@@_pattern_count_int
+  \int_gzero:N \g_@@_pattern_after_int
+  \int_gset:Nn \g_@@_pattern_for_int {-1}
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_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.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_pattern:n #1
+{
+  \prop_get:NnNTF \g_@@_patterns_prop {#1} \l_tmpa_tl
+  {
+    \keys_set_filter:nnV {mcrule} {patterns} \l_tmpa_tl
+  }
+  {
+    \msg_error:nnn {multicolrule} {pattern-undefined} {#1}
+  }
+  \tl_set:Nn \l_tmpa_tl {\prop_item:Nn \g_@@_patterns_prop {#1}}
+}
+\cs_generate_variant:Nn \@@_set_pattern:n {V}
+%    \end{macrocode}
+%\end{function}
+%
 % \subsection{Key-Values}
 % Set up all the key definitions. For the line styles, this involves
-% resetting \cs{_@@_divider:} to an appropriate value.
+% resetting \cs{mcrule_divider:} to an appropriate value.
+% \changes{v1.1}{2018/12/21}{Added extend-top, extend-bot, extend-fill, and
+%   extend-reserve keys}
+% \changes{v1.2}{2019/1/1}{Added patterns, pattern-after, and pattern-for
+%   keys}
 %
 %    \begin{macrocode}
 \keys_define:nn {mcrule}
@@ -1247,51 +1481,51 @@
   extend-fill                      .default:n = true,
   extend-reserve                   .dim_set:N  = \l_@@_extend_reserve_dim,
   line-style                       .choice:,
-  line-style / default             .code:n = \cs_set:Npn \@@_divider: 
+  line-style / default             .code:n = \cs_set:Npn \mcrule_divider: 
     {\vrule\@width\columnseprule},
-  line-style / solid               .code:n = \cs_set:Npn \@@_divider: 
+  line-style / solid               .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_solid_line:},
-  line-style / dots                .code:n = \cs_set:Npn \@@_divider:
+  line-style / dots                .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn {.}{1pt}{1pt}},
-  line-style / dense-dots          .code:n = \cs_set:Npn \@@_divider: 
+  line-style / dense-dots          .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_tile_pattern:nnn {.}{1pt}{0pt}},
-  line-style / loose-dots          .code:n = \cs_set:Npn \@@_divider:
+  line-style / loose-dots          .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn {.}{2pt}{2pt}},
-  line-style / circles             .code:n = \cs_set:Npn \@@_divider: 
+  line-style / circles             .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_tile_pattern:nnn {\@@_circle:}{1pt}{1pt}},
-  line-style / dense-circles       .code:n = \cs_set:Npn \@@_divider:
+  line-style / dense-circles       .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn {\@@_circle:}{1pt}{0pt}},
-  line-style / loose-circles       .code:n = \cs_set:Npn \@@_divider: 
+  line-style / loose-circles       .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_tile_pattern:nnn {\@@_circle:}{2pt}{2pt}},
-  line-style / solid-circles       .code:n = \cs_set:Npn \@@_divider: 
+  line-style / solid-circles       .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_tile_pattern:nnn {\@@_solid_circle:}{1pt}{1pt}},
-  line-style / dense-solid-circles .code:n = \cs_set:Npn \@@_divider:
+  line-style / dense-solid-circles .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn {\@@_solid_circle:}{1pt}{0pt}},
-  line-style / loose-solid-circles .code:n = \cs_set:Npn \@@_divider:
+  line-style / loose-solid-circles .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn {\@@_solid_circle:}{2pt}{2pt}},
-  line-style / dotted              .code:n = \cs_set:Npn \@@_divider: 
+  line-style / dotted              .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_line_pattern:nnnn {dotted}{\columnseprule}{1pt}{1pt}},
-  line-style / densely-dotted      .code:n = \cs_set:Npn \@@_divider:
+  line-style / densely-dotted      .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_line_pattern:nnnn {densely~dotted}{\columnseprule}{1pt}{0pt}},
-  line-style / loosely-dotted      .code:n = \cs_set:Npn \@@_divider:
+  line-style / loosely-dotted      .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_line_pattern:nnnn {loosely~dotted}{\columnseprule}{2pt}{2pt}},
-  line-style / dashed              .code:n = \cs_set:Npn \@@_divider:
+  line-style / dashed              .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_line_pattern:nnnn {dashed}{3pt}{1.5pt}{1.5pt}},
-  line-style / densely-dashed      .code:n = \cs_set:Npn \@@_divider:
+  line-style / densely-dashed      .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_line_pattern:nnnn {densely~dashed}{3pt}{1pt}{1pt}},
-  line-style / loosely-dashed      .code:n = \cs_set:Npn \@@_divider: 
+  line-style / loosely-dashed      .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_line_pattern:nnnn {loosely~dashed}{3pt}{3pt}{3pt}},
-  line-style / dash-dot            .code:n = \cs_set:Npn \@@_divider:
+  line-style / dash-dot            .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_pattern_line:n{dash~dot}},
-  line-style / densely-dash-dot    .code:n = \cs_set:Npn \@@_divider: 
+  line-style / densely-dash-dot    .code:n = \cs_set:Npn \mcrule_divider: 
     {\@@_pattern_line:n{densely~dash~dot}},
-  line-style / loosely-dash-dot    .code:n = \cs_set:Npn \@@_divider:
+  line-style / loosely-dash-dot    .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_pattern_line:n{loosely~dash~dot}},
-  line-style / dash-dot-dot         .code:n = \cs_set:Npn \@@_divider:
+  line-style / dash-dot-dot         .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_pattern_line:n{dash~dot~dot}},
-  line-style / densely-dash-dot-dot .code:n = \cs_set:Npn \@@_divider:
+  line-style / densely-dash-dot-dot .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_pattern_line:n{densely~dash~dot~dot}},
-  line-style / loosely-dash-dot-dot .code:n = \cs_set:Npn \@@_divider:
+  line-style / loosely-dash-dot-dot .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_pattern_line:n{loosely~dash~dot~dot}},
   color                             .code:n = {
     \tl_set:Nn \l_@@_color_name_tl {#1}
@@ -1301,11 +1535,11 @@
     \tl_set:Nn \l_@@_color_model_tl {#1}
     \@@_set_rule_color:
   },
-  custom-line         .code:n = \cs_set:Npn \@@_divider:
+  custom-line         .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tikz_picture:n {#1}},
-  custom-pattern      .code:n = \cs_set:Npn \@@_divider:
+  custom-pattern      .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_pattern:nnn #1},
-  custom-tile         .code:n = \cs_set:Npn \@@_divider:
+  custom-tile         .code:n = \cs_set:Npn \mcrule_divider:
     {\@@_tile_pattern:nnn #1},
   width               .choice:,
   width / ultra-thin  .code:n = \dim_set:Nn \columnseprule {0.1pt},
@@ -1315,35 +1549,39 @@
   width / thick       .code:n = \dim_set:Nn \columnseprule {0.8pt},
   width / very-thick  .code:n = \dim_set:Nn \columnseprule {1.2pt},
   width / ultra-thick .code:n = \dim_set:Nn \columnseprule {1.6pt},
-  width / unknown     .code:n = {\dim_set:Nn \columnseprule {#1}},
-  repeat              .int_set:N = \l_@@_repeat_int,
-  repeat-distance     .dim_set:N = \l_@@_repeat_distance_dim,
-  single              .meta:n = {
+  width / unknown     .code:n = \dim_set:Nn \columnseprule {#1},
+  repeat              .int_set:N   = \l_@@_repeat_int,
+  repeat-distance     .dim_set:N   = \l_@@_repeat_distance_dim,
+  single              .meta:n      = {
     repeat = 1,
     repeat-distance = #1
   },
-  single              .default:n = \columnseprule,
-  double              .meta:n = {
+  single              .default:n   = \columnseprule,
+  double              .meta:n      = {
     repeat = 2,
     repeat-distance = #1
   },
-  double              .default:n = \columnseprule,
-  triple              .meta:n = {
+  double              .default:n   = \columnseprule,
+  triple              .meta:n      = {
     repeat = 3,
     repeat-distance = #1
   },
-  triple              .default:n = \columnseprule,
+  triple              .default:n   = \columnseprule,
+  patterns            .code:n      = \@@_set_pattern_list:n {#1},
+  patterns            .groups:n    = {patterns},
+  pattern-after       .int_gset:N  = \g_@@_pattern_after_int,
+  pattern-for         .int_gset:N  = \g_@@_pattern_for_int,
 }
 %    \end{macrocode}
 %
 % \subsection{User Interface}
-% With only one command, this section is short. All we do is set whatever keys
-% the user passes. All the real work is done in the definitions above.
 %
 %\begin{macro}{\SetMCRule}
-%\begin{syntax}
-%  |\SetMCRule| \marg{key-value list}
-%\end{syntax}
+% Set all keys for \mcrule{}
+% \begin{syntax}
+% |\SetMCRule| \marg{key-value list}
+% \end{syntax}
+% All we do here is pass the argument to expl3's key-setting routine.
 %    \begin{macrocode}
 \NewDocumentCommand{\SetMCRule}{m}
 {
@@ -1352,10 +1590,22 @@
 %    \end{macrocode}
 %\end{macro}
 %
+%\begin{macro}{\DeclareMCRulePattern}
+% Declare a new style pattern. 
+% \begin{syntax}
+% |\DeclareMCRule| \marg{name} \marg{key-value list}
+% \end{syntax}
+% If a pattern of that name exists, it will be overwritten silently.
+%    \begin{macrocode}
+\NewDocumentCommand{\DeclareMCRulePattern}{m m}
+{
+  \prop_gput:Nnn \g_@@_patterns_prop {#1} {#2}
+}
+%    \end{macrocode}
+%\end{macro}
+%
 %\end{implementation}
 %
 % \PrintChanges
 %
-% \newpage
-%
 % \PrintIndex
\ No newline at end of file

Modified: trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins	2019-01-02 22:37:52 UTC (rev 49578)
+++ trunk/Master/texmf-dist/source/latex/multicolrule/multicolrule.ins	2019-01-02 22:38:45 UTC (rev 49579)
@@ -27,7 +27,7 @@
 
 \endpreamble
 \postamble
-Copyright (C) 2018 by Karl Hagen <latex at polysyllabic.com>
+Copyright (C) 2018-2019 by Karl Hagen <latex at polysyllabic.com>
 
 This file may be distributed and/or modified under the
 conditions of the LaTeX Project Public License (LPPL), either
@@ -50,7 +50,10 @@
   \file{\jobname.sty}{\from{\jobname.dtx}{package}}
 }
 \endbatchfile
-%% Copyright (C) 2018 by Karl Hagen <latex at polysyllabic.com>
+  % |\DeclareMCRulePattern| \marg{name} \marg{key-value list}
+  % \end{syntax}
+
+%% Copyright (C) 2018-2019 by Karl Hagen <latex at polysyllabic.com>
 %% 
 %% This file may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License (LPPL), either

Modified: trunk/Master/texmf-dist/tex/latex/multicolrule/multicolrule.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/multicolrule/multicolrule.sty	2019-01-02 22:37:52 UTC (rev 49578)
+++ trunk/Master/texmf-dist/tex/latex/multicolrule/multicolrule.sty	2019-01-02 22:38:45 UTC (rev 49579)
@@ -15,8 +15,11 @@
 %% 
 \RequirePackage{expl3}
 \RequirePackage{xparse}
-\ProvidesExplPackage {multicolrule} {2018/12/21} {1.1}
-  {Decorative~vertical~rules~between~columns}
+  % |\DeclareMCRulePattern| \marg{name} \marg{key-value list}
+  % \end{syntax}
+
+\ProvidesExplPackage {multicolrule} {2019/01/01} {1.2}
+  {Decorative vertical rules between columns}
 \RequirePackage{l3keys2e}
 \RequirePackage{xpatch}
 \RequirePackage{xcolor}
@@ -23,11 +26,14 @@
 \RequirePackage{scrlfile}
 \msg_new:nnn {multicolrule} {patch-success} {Patched~#1.}
 \msg_new:nnn {multicolrule} {patch-failure} {Error~patching~#1.}
-\msg_new:nnn {multicolrule} {tikz-required}
+\msg_new:nnnn {multicolrule} {tikz-required} {Tikz~required}
 {The~'#1'~setting~requires~tikz~to~work.~Either~load~tikz~before~you~load~
   multicolrule~or~use~multicolrule's~'tikz'~package~option.}
-\msg_new:nnn {multicolrule} {multicol-loaded} {You~are~using~the~'twocolumn'~
-  option~with~multicol~already~loaded.~You~will~likely~run~into~problems.}
+\msg_new:nnnn {multicolrule} {multicol-loaded} {Multicol~loaded} {You~are~
+  using~the~'twocolumn'~option~with~multicol~already~loaded.~You~will~likely~
+  run~into~problems.}
+\msg_new:nnnn {multicolrule} {pattern-undefined} {Pattern~undefined}
+  {The~multicolrule~pattern~'#1'~has~not~been~defined.}
 \bool_new:N \g__mcrule_twocolumn_bool
 \bool_new:N \g__mcrule_use_tikz_bool
 \int_new:N  \l__mcrule_repeat_int
@@ -39,6 +45,11 @@
 \dim_new:N  \l__mcrule_extend_reserve_dim
 \tl_new:N \l__mcrule_color_name_tl
 \tl_new:N \l__mcrule_color_model_tl
+\prop_new:N \g__mcrule_patterns_prop
+\int_new:N  \g__mcrule_pattern_count_int
+\int_new:N  \g__mcrule_pattern_for_int
+\int_new:N  \g__mcrule_pattern_after_int
+\seq_new:N  \l__mcrule_pattern_list_seq
 \@ifpackageloaded{tikz}
 {
   \bool_gset_true:N \g__mcrule_use_tikz_bool
@@ -54,7 +65,8 @@
 \cs_new:Npn \__mcrule_column_depth: {}
 \cs_new_protected:Npn \__mcrule_patch_mcol_output:N #1
 {
-  \xpatchcmd{#1} {\vrule\@width\columnseprule} {\mcruledivider}
+  \xpatchcmd{#1} {\columnseprulecolor\vrule\@width\columnseprule}
+  {\mcruledivider}
   {\msg_info:nnn {multicolrule} {patch-success} {#1}}
   {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
 }
@@ -61,7 +73,7 @@
 \cs_new_protected:Npn \__mcrule_patch_twocol_output:N #1
 {
   \xpatchcmd{#1} {\normalcolor\vrule\@width\columnseprule}
-  {\columnseprulecolor\mcruledivider}
+  {\mcruledivider}
   {\msg_info:nnn {multicolrule} {patch-success} {#1}}
   {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
 }
@@ -95,17 +107,44 @@
     \cs_gset_eq:NN \RLmulticolcolumns \RTLmulticolcolumns
   }
 }
-\cs_new:Npn \mcruledivider
+\cs_new_protected:Npn \mcruledivider
 {
+  \int_compare:nNnTF {\g__mcrule_pattern_after_int} > {\c_zero_int}
+  {
+    \int_gdecr:N \g__mcrule_pattern_after_int
+  }
+  {
+    \bool_lazy_and:nnT
+    {\int_compare_p:nNn {\seq_count:N \l__mcrule_pattern_list_seq} > {\c_zero_int}}
+    {! \int_compare_p:nNn {\g__mcrule_pattern_for_int} = {\c_zero_int}}
+    {
+      \int_gincr:N \g__mcrule_pattern_count_int
+      \int_compare:nNnT {\g__mcrule_pattern_count_int} >
+       {\seq_count:N \l__mcrule_pattern_list_seq}
+      {
+        \int_gset:Nn \g__mcrule_pattern_count_int {\c_one_int}
+      }
+      \tl_set:Nx \l_tmpa_tl {\seq_item:Nn \l__mcrule_pattern_list_seq {\g__mcrule_pattern_count_int} }
+      \tl_if_blank:VF \l_tmpa_tl
+      {
+        \__mcrule_set_pattern:V \l_tmpa_tl
+      }
+      \int_compare:nNnT {\g__mcrule_pattern_for_int} > {\c_zero_int}
+      {
+        \int_gdecr:N \g__mcrule_pattern_for_int
+      }
+    }
+  }
+  \columnseprulecolor
   \bool_lazy_and:nnT
-  {\dim_compare_p:nNn {\columnseprule} > {0pt}}
-  {\int_compare_p:nNn {\l__mcrule_repeat_int} > {0}}
+  {\dim_compare_p:nNn {\columnseprule} > {\c_zero_dim}}
+  {\int_compare_p:nNn {\l__mcrule_repeat_int} > {\c_zero_int}}
   {
-    \__mcrule_divider:
-    \prg_replicate:nn {\l__mcrule_repeat_int - 1}
+    \mcrule_divider:
+    \prg_replicate:nn {\l__mcrule_repeat_int - \c_one_int}
     {
       \hspace{\l__mcrule_repeat_distance_dim}
-      \__mcrule_divider:
+      \mcrule_divider:
     }
   }
 }
@@ -129,19 +168,19 @@
   {\bool_not_p:n {\g__mcrule_twocolumn_bool}}
   {
     \dim_compare:nNnTF
-    {\@colroom - \__mcrule_column_height: - \__mcrule_extend_reserve:} > {0pt}
+    {\@colroom - \__mcrule_column_height: - \__mcrule_extend_reserve:} > {\c_zero_dim}
     {\@colroom - \__mcrule_column_height: - \__mcrule_extend_reserve:}
-    {0pt}
+    {\c_zero_dim}
   }
   {\l__mcrule_extend_bot_dim}
 }
 \cs_new:Npn \__mcrule_extend_reserve:
 {
-  \dim_compare:nNnTF {\l__mcrule_extend_reserve_dim} > {0pt}
+  \dim_compare:nNnTF {\l__mcrule_extend_reserve_dim} > {\c_zero_dim}
   {\dim_eval:n {\l__mcrule_extend_reserve_dim + \multicolsep}}
-  {0pt}
+  {\c_zero_dim}
 }
-\cs_new:Npn \__mcrule_divider: {\vrule\@width\columnseprule}
+\cs_new:Npn \mcrule_divider: {\vrule\@width\columnseprule}
 \cs_new_nopar:Npn \__mcrule_pattern:nnn #1#2#3
 {
   \box_move_down:nn {\__mcrule_column_total_depth:}
@@ -148,9 +187,9 @@
   {
     \vbox_to_ht:nn {\__mcrule_column_total_height:}
     {
-      \vfill
-      \kern #2 \hbox:n{#1} \kern #3
-      \vfill
+      \tex_vfill:D
+      \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
+      \tex_vfill:D
     }
   }
 }
@@ -160,11 +199,11 @@
   {
     \vbox_to_ht:nn {\__mcrule_column_total_height:}
     {
-      \cleaders \vbox:n
+      \tex_cleaders:D \vbox:n
       {
-        \kern #2 \hbox:n{#1} \kern #3
+        \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
       }
-    \vfill
+    \tex_vfill:D
     }
   }
 }
@@ -241,6 +280,25 @@
     {\color[\l__mcrule_color_model_tl]{\l__mcrule_color_name_tl}}
   }
 }
+\cs_new_protected:Npn \__mcrule_set_pattern_list:n #1
+{
+  \seq_set_split:Nnn \l__mcrule_pattern_list_seq {,} {#1}
+  \int_gzero:N \g__mcrule_pattern_count_int
+  \int_gzero:N \g__mcrule_pattern_after_int
+  \int_gset:Nn \g__mcrule_pattern_for_int {-1}
+}
+\cs_new_protected:Npn \__mcrule_set_pattern:n #1
+{
+  \prop_get:NnNTF \g__mcrule_patterns_prop {#1} \l_tmpa_tl
+  {
+    \keys_set_filter:nnV {mcrule} {patterns} \l_tmpa_tl
+  }
+  {
+    \msg_error:nnn {multicolrule} {pattern-undefined} {#1}
+  }
+  \tl_set:Nn \l_tmpa_tl {\prop_item:Nn \g__mcrule_patterns_prop {#1}}
+}
+\cs_generate_variant:Nn \__mcrule_set_pattern:n {V}
 \keys_define:nn {mcrule}
 {
   extend-top                       .dim_set:N  = \l__mcrule_extend_top_dim,
@@ -249,51 +307,51 @@
   extend-fill                      .default:n = true,
   extend-reserve                   .dim_set:N  = \l__mcrule_extend_reserve_dim,
   line-style                       .choice:,
-  line-style / default             .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / default             .code:n = \cs_set:Npn \mcrule_divider:
     {\vrule\@width\columnseprule},
-  line-style / solid               .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / solid               .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_solid_line:},
-  line-style / dots                .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dots                .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {.}{1pt}{1pt}},
-  line-style / dense-dots          .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dense-dots          .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {.}{1pt}{0pt}},
-  line-style / loose-dots          .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loose-dots          .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {.}{2pt}{2pt}},
-  line-style / circles             .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / circles             .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {\__mcrule_circle:}{1pt}{1pt}},
-  line-style / dense-circles       .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dense-circles       .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {\__mcrule_circle:}{1pt}{0pt}},
-  line-style / loose-circles       .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loose-circles       .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {\__mcrule_circle:}{2pt}{2pt}},
-  line-style / solid-circles       .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / solid-circles       .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {\__mcrule_solid_circle:}{1pt}{1pt}},
-  line-style / dense-solid-circles .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dense-solid-circles .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {\__mcrule_solid_circle:}{1pt}{0pt}},
-  line-style / loose-solid-circles .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loose-solid-circles .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn {\__mcrule_solid_circle:}{2pt}{2pt}},
-  line-style / dotted              .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dotted              .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_line_pattern:nnnn {dotted}{\columnseprule}{1pt}{1pt}},
-  line-style / densely-dotted      .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / densely-dotted      .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_line_pattern:nnnn {densely~dotted}{\columnseprule}{1pt}{0pt}},
-  line-style / loosely-dotted      .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loosely-dotted      .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_line_pattern:nnnn {loosely~dotted}{\columnseprule}{2pt}{2pt}},
-  line-style / dashed              .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dashed              .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_line_pattern:nnnn {dashed}{3pt}{1.5pt}{1.5pt}},
-  line-style / densely-dashed      .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / densely-dashed      .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_line_pattern:nnnn {densely~dashed}{3pt}{1pt}{1pt}},
-  line-style / loosely-dashed      .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loosely-dashed      .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_line_pattern:nnnn {loosely~dashed}{3pt}{3pt}{3pt}},
-  line-style / dash-dot            .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dash-dot            .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern_line:n{dash~dot}},
-  line-style / densely-dash-dot    .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / densely-dash-dot    .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern_line:n{densely~dash~dot}},
-  line-style / loosely-dash-dot    .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loosely-dash-dot    .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern_line:n{loosely~dash~dot}},
-  line-style / dash-dot-dot         .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / dash-dot-dot         .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern_line:n{dash~dot~dot}},
-  line-style / densely-dash-dot-dot .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / densely-dash-dot-dot .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern_line:n{densely~dash~dot~dot}},
-  line-style / loosely-dash-dot-dot .code:n = \cs_set:Npn \__mcrule_divider:
+  line-style / loosely-dash-dot-dot .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern_line:n{loosely~dash~dot~dot}},
   color                             .code:n = {
     \tl_set:Nn \l__mcrule_color_name_tl {#1}
@@ -303,11 +361,11 @@
     \tl_set:Nn \l__mcrule_color_model_tl {#1}
     \__mcrule_set_rule_color:
   },
-  custom-line         .code:n = \cs_set:Npn \__mcrule_divider:
+  custom-line         .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tikz_picture:n {#1}},
-  custom-pattern      .code:n = \cs_set:Npn \__mcrule_divider:
+  custom-pattern      .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_pattern:nnn #1},
-  custom-tile         .code:n = \cs_set:Npn \__mcrule_divider:
+  custom-tile         .code:n = \cs_set:Npn \mcrule_divider:
     {\__mcrule_tile_pattern:nnn #1},
   width               .choice:,
   width / ultra-thin  .code:n = \dim_set:Nn \columnseprule {0.1pt},
@@ -317,30 +375,38 @@
   width / thick       .code:n = \dim_set:Nn \columnseprule {0.8pt},
   width / very-thick  .code:n = \dim_set:Nn \columnseprule {1.2pt},
   width / ultra-thick .code:n = \dim_set:Nn \columnseprule {1.6pt},
-  width / unknown     .code:n = {\dim_set:Nn \columnseprule {#1}},
-  repeat              .int_set:N = \l__mcrule_repeat_int,
-  repeat-distance     .dim_set:N = \l__mcrule_repeat_distance_dim,
-  single              .meta:n = {
+  width / unknown     .code:n = \dim_set:Nn \columnseprule {#1},
+  repeat              .int_set:N   = \l__mcrule_repeat_int,
+  repeat-distance     .dim_set:N   = \l__mcrule_repeat_distance_dim,
+  single              .meta:n      = {
     repeat = 1,
     repeat-distance = #1
   },
-  single              .default:n = \columnseprule,
-  double              .meta:n = {
+  single              .default:n   = \columnseprule,
+  double              .meta:n      = {
     repeat = 2,
     repeat-distance = #1
   },
-  double              .default:n = \columnseprule,
-  triple              .meta:n = {
+  double              .default:n   = \columnseprule,
+  triple              .meta:n      = {
     repeat = 3,
     repeat-distance = #1
   },
-  triple              .default:n = \columnseprule,
+  triple              .default:n   = \columnseprule,
+  patterns            .code:n      = \__mcrule_set_pattern_list:n {#1},
+  patterns            .groups:n    = {patterns},
+  pattern-after       .int_gset:N  = \g__mcrule_pattern_after_int,
+  pattern-for         .int_gset:N  = \g__mcrule_pattern_for_int,
 }
 \NewDocumentCommand{\SetMCRule}{m}
 {
   \keys_set:nn {mcrule} {#1}
 }
-%% Copyright (C) 2018 by Karl Hagen <latex at polysyllabic.com>
+\NewDocumentCommand{\DeclareMCRulePattern}{m m}
+{
+  \prop_gput:Nnn \g__mcrule_patterns_prop {#1} {#2}
+}
+%% Copyright (C) 2018-2019 by Karl Hagen <latex at polysyllabic.com>
 %% 
 %% This file may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License (LPPL), either

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2019-01-02 22:37:52 UTC (rev 49578)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2019-01-02 22:38:45 UTC (rev 49579)
@@ -2385,7 +2385,7 @@
 
 

 $standardsource = '(\.(bat|c|drv|dtx|fea|fdd|ins|sfd)'
-                  . '|configure.*|install-sh|Makefile\..*|ltxdoc\.cfg)$';
+                  . '|configure.*|install-sh|Makefile.*|ltxdoc\.cfg)$';
 %specialsource= (
  'FAQ-en',              'NULL',
  'ae',                  '\.mtx|\.etx|\.tex|clean|go|install|makepl',



More information about the tex-live-commits mailing list