From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 2 Sep 2019 13:46:59 +0900
Subject: Initial commit

---
 macros/latex/contrib/multicolrule/multicolrule.dtx | 1611 ++++++++++++++++++++
 1 file changed, 1611 insertions(+)
 create mode 100644 macros/latex/contrib/multicolrule/multicolrule.dtx

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

diff --git a/macros/latex/contrib/multicolrule/multicolrule.dtx b/macros/latex/contrib/multicolrule/multicolrule.dtx
new file mode 100644
index 0000000000..85de910089
--- /dev/null
+++ b/macros/latex/contrib/multicolrule/multicolrule.dtx
@@ -0,0 +1,1611 @@
+% \iffalse meta-comment
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+multicolrule - Decorative rules between columns
+=================================================
+
+The multicolrule package lets you customize the appearance of
+the vertical rule that appears between columns of multicolumn
+text. It is primarily intended to work with the multicol
+package, hence its name, but it also supports the twocolumn
+option and \twocolumn macro provided by the standard classes
+(and related classes such as the KOMA-Script equivalents).
+
+Installation
+------------
+
+This package is provided as a .dtx file. To install it and
+compile the documentation at the same time, simply process the
+.dtx file with LaTeX (for example, `pdflatex multicolrule.dtx`).
+To extract the package only, process the file with TeX 
+(`tex multicolrule.dtx`). Note that the documentation uses
+the l3doc class to index the code, and so to get the index, you
+must issue:
+
+`makeindex -s gind.ist -o multicolrule.ind multicolrule.idx`
+
+and to get the change list, you must issue
+
+`makeindex -s gglo.ist -o multicolrule.gls multicolrule.glo`.
+
+This package requires expl3 and xparse.
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+\expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input l3docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+----------------------------------------------------------------
+multicolrule --- Decorative rules between columns
+Author: Karl Hagen
+Email: latex@polysyllabic.com
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+----------------------------------------------------------------
+
+\endpreamble
+\postamble
+Copyright (C) 2018-2019 by Karl Hagen <latex@polysyllabic.com>
+ 
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License (LPPL), either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in the file:
+    https://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+  Karl Hagen.
+
+This work consists of the files multicolrule.dtx and
+                                mcrule-examples.tex,
+and the derived files           multicolrule.ins,
+                                multicolrule.sty,
+                                multicolrule.pdf, and
+                                mcrule-examples.pdf.
+\endpostamble
+\usedir{tex/latex/multicolrule}
+\generate{
+  \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/multicolrule}
+\generate{
+  \file{\jobname.ins}{\from{\jobname.dtx}{install}}
+}
+\nopreamble\nopostamble
+\usedir{doc/latex/multicolrule}
+\generate{
+  \file{README.md}{\from{\jobname.dtx}{readme}}
+}
+\ifx\fmtname\nameofplainTeX
+\expandafter\endbatchfile
+\else
+\expandafter\endgroup
+\fi
+%</internal>
+%<*driver|package>
+\RequirePackage{expl3}
+\RequirePackage{xparse}
+%</driver|package>
+%<*driver>
+\PassOptionsToPackage{svgnames}{xcolor}
+\documentclass{l3doc}
+\usepackage[T1]{fontenc}
+\usepackage[ttscale=0.85]{libertine}
+\usepackage{microtype}
+\usepackage[tikz]{multicolrule}
+\usepackage{longtable}
+\usepackage{ragged2e}
+\usepackage{scrlayer-scrpage}
+\usepackage{scrlayer-notecolumn}
+\usepackage{bbding}
+\usepackage{pgfornament}
+\pagestyle{scrheadings}
+\automark[subsection]{section}
+\DeclareNewNoteColumn[
+  reversemarginpar,
+  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#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         
+\CodelineIndex
+\RecordChanges
+\begin{document}
+  \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%\GetFileInfo{\jobname.sty}
+%
+%\DoNotIndex{\AfterPackage,\begin,\bool_gset_true:N,\bool_if:NTF,
+%   \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,
+%   \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,
+%   \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,
+%   \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
+%  \textsf{multicolrule} --- Decorative rules between columns\thanks{^^A
+%   This file describes version \fileversion, last revised \filedate.^^A
+%  }^^A
+%}
+%\author{^^A
+%  Karl Hagen\thanks{\href{mailto://latex@polysyllabic.com}^^A
+%   {latex@polysyllabic.com}}}
+%\date{Released \filedate}
+%
+%\maketitle
+%
+% \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
+% that appears between columns of multicolumn text. It is primarily intended to
+% work with the \pkg{multicol} package, hence its name, but it also supports
+% the twocolumn option and \cs{twocolumn} macro provided by the standard
+% classes (and related classes such as the KOMA-Script equivalents), as well as
+% the \pkg{bidi} package (and through it, all RTL scripts loaded with
+% \pkg{polyglossia}).
+%\end{abstract}
+%
+%\tableofcontents
+%
+%\begin{documentation}
+% \raggedcolumns
+%
+% \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
+% space between adjacent columns, and \cs{columnseprule} specifies the width of
+% a solid vertical rule that is placed centered between the columns. The
+% \pkg{multicol} package adds the ability to change the color of the rule, but
+% in both vanilla \LaTeX{} and \pkg{multicol}, the rule itself is drawn
+% directly inside the routines that output the column boxes, and is therefore
+% difficult for users to alter.
+%
+% 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
+% 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
+% more general case. I hope someone else will find the options here useful.
+%
+% The basic line styles that \mcrule{} makes available are illustrated
+% 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 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 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}]
+% 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@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:
+%  
+% 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
+% package that outputs column text via alternate mechanisms. This includes
+% \pkg{parcolumns}, and probably other classes and packages designed to typeset
+% parallel-column text as well, although I have not done a survey to determine
+% 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
+% 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--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
+%
+% \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}
+%
+%\begin{multicols}{2}[\section{Package Options}]
+% \SetMCRule{line-style=dash-dot}
+%
+% \subsection{Default Operation}
+% 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 `tikz'}
+% \DescribeOption{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
+% \mcrule{} detects that \pkg{tikz} is already loaded, then tikz support will
+% be enabled by default. Otherwise, you need the \opt{tikz} to enable it. This
+% option also accepts explicit boolean values, so you can pass |tikz=false| if
+% you want to explicitly disable tikz support. If tikz support is not enabled
+% (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}
+%
+% \section{The User Interface}
+% |\SetMCRule| \marg{key-value list}
+%
+% \begin{multicols}{2}
+% \SetMCRule{width=2pt,line-style=circles}
+% \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.
+% \end{multicols}
+%
+% \begin{longtable}{lp{3.5in}}
+% \caption{\cs{SetMCRule} keys\label{table:mcrulekeys}} \\
+% \toprule
+% Key & Purpose\\
+% \midrule
+% \endfirsthead
+% \caption{\textbackslash SetMCRule keys (cont.)} \\
+% \toprule
+% Key & Purpose\\
+% \midrule
+% \endhead
+% \kvdesc{color} & Set the color of the rule (see sec. \ref{sec:color})\\
+% \kvdesc{color-model} & Set the color model of the rule (see sec.
+% \ref{sec:color})\\
+% \kvdesc{custom-line} & Set a custom \pkg{tikz} line for the rule 
+% (\emph{tikz only}; see sec. \ref{sec:custom})\\
+% \kvdesc{custom-pattern} & Set a custom individual pattern for the rule (see
+% sec. \ref{sec:custom})\\
+% \kvdesc{custom-tile} & Set a custom tiling pattern for the rule
+% (see sec. \ref{sec:custom})\\
+% \kvdesc{double} & Draw two copies of the rule (see sec.
+% \ref{sec:repeats})\\
+% \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
+% (\emph{multicol} only; see sec. \ref{sec:extend})\\
+% \kvdesc{extend-reserve} & Space to reserve at bottom of text area when using
+% \kvdesc{extend-fill} (\emph{multicol} only; see sec, \ref{sec:extend})\\
+% \kvdesc{extend-top} & Set an extra amount to extend the rule at the top of 
+% 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
+% sec. \ref{sec:repeats})\\
+% \kvdesc{repeat-distance} & Set the horizontal space between
+% adjacent copies of repeated rules (see sec. \ref{sec:repeats})\\
+% \kvdesc{triple} & Draw three copies of the rule (see sec.
+% \ref{sec:repeats})\\
+% \kvdesc{width} & Set the width of the rule (see sec.
+% \ref{sec:width})\\
+% \bottomrule
+% \end{longtable}
+%
+% \begin{multicols}{2}[\subsection{Styles with the `line-style' option}^^A
+%   \label{sec:linestyles}]
+%  \SetMCRule{width=4pt,line-style=solid-circles}
+%  
+% 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} 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}}
+%   \caption{Styles available for the line-style key\label{table:linestyles}}\\
+%   \toprule
+%   Style & Description\\
+%   \midrule
+%   \endfirsthead
+%   \caption{Available line-style settings (cont.)} \\
+%   \toprule
+%   Style & Description\\
+%   \midrule
+%   \endhead
+%   \kvdesc{circles} & A series of hollow circles (\emph{tikz
+%     only})\\
+%   \kvdesc{dash-dot} & A dash followed by a square dot (\emph{tikz
+%     only})\\
+%   \kvdesc{dash-dot-dot} & A dash followed by two square dots
+%     (\emph{tikz only})\\
+%   \kvdesc{dashed} & A series of dashed lines\\
+%   \kvdesc{default} & A solid rule drawn the same way as the default
+% \pkg{multicol} rule. Does not support extended rules.\\
+%   \kvdesc{dense-circles} & The same as \kvdesc{circles}
+%     but more closely spaced (\emph{tikz only})\\
+%   \kvdesc{dense-dots} & The same as \kvdesc{dots} but
+%     more closely spaced\\
+%   \kvdesc{dense-solid-circles} & The same as \kvdesc{solid-circles} but more
+% closely spaced (\emph{tikz only})\\
+%   \kvdesc{densely-dash-dot} & The same as \kvdesc{dash-dot} but more closely
+% spaced (\emph{tikz only})\\
+%   \kvdesc{densely-dash-dot-dot} & The same as \kvdesc{dash-dot-dot} but more
+% closely spaced (\emph{tikz only})\\
+%   \kvdesc{densely-dashed} & The same as \kvdesc{dashed} but more closely
+% spaced\\
+%   \kvdesc{densely-dotted} & The same as \kvdesc{dotted} but more closely
+% spaced\\
+%   \kvdesc{dots}  & A series of dots drawn with the period (full-stop) of the
+% current font\\
+%   \kvdesc{dotted} & A series of square dots\\
+%   \kvdesc{loose-dots} & The same as \kvdesc{dots} but spaced further apart\\
+%   \kvdesc{loose-circles} & The same as \kvdesc{circles} but spaced further
+% apart (\emph{tikz only})\\
+%   \kvdesc{loose-solid-circles} & The same as \kvdesc{solid-circles} but
+% spaced further apart (\emph{tikz only})\\
+%   \kvdesc{loosely-dash-dot} & The same as \kvdesc{dash-dot} but spaced
+% further apart (\emph{tikz only})\\
+%   \kvdesc{loosely-dash-dot-dot} & The same as \kvdesc{dash-dot-dot} but
+% spaced further apart (\emph{tikz only})\\
+%   \kvdesc{loosely-dashed} & The same as \kvdesc{dashed} but spaced further
+% apart\\
+%   \kvdesc{loosely-dotted} & The same as \kvdesc{dotted} but spaced further
+% apart\\
+% \kvdesc{solid} & A solid line, like \kvdesc{default}, but supports extending
+% rules\\
+% \kvdesc{solid-circles} & A series of filled circles (\emph{tikz only})\\
+% \bottomrule
+% \end{longtable}
+%
+% \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)
+% supports the rule-extension commands described in section \ref{sec:extend}.
+% This means that if you want a solid rule with altered top or bottom
+% extensions, you must explicitly set the line style to \kvdesc{solid}. If you
+% make no calls to \cs{SetMCRule} after loading \mcrule, the column divider
+% will continue to behave exactly as it does with the ordinary \pkg{multicol}
+% package.
+%
+% You can alter the rule's width and color either through \cs{SetMCRule} with
+% 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.
+%  
+% The \kvdesc{dots} style and its variants are rendered with a period (.) in
+% 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
+% behavior of the equivalently named dotted patterns in \pkg{tikz}.
+% \end{multicols}
+%
+% \subsubsection{Custom Patterns}\label{sec:custom}
+% \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\}}
+% are three options to create custom rules with \mcrule. The first is the
+% \kvdesc{custom-tile} key. This creates a rule consisting of vertically
+% stacked boxes of arbitrary content---the tile---running the height of the
+% column separator. The \kvdesc{custom-tile} key takes three parameters,
+% which must all be enclosed brackets and may not be omitted. The first
+% should contain the tokens you want to appear as the content of the tile.
+% The second is a dimension specifying the leading vertical space to apply
+% above each copy of the tile. The third is a dimension specifying the
+% trailing vertical space to insert below each copy of the tile.
+%
+% The rule in this section uses the \cs{SparkleBold} symbol from
+% \pkg{bbding}. Notice that when you use the \kvdesc{custom-tile} parameter,
+% of any of the other custom key commands, you do \emph{not} specify a separate
+% \kvdesc{line-style}. If you try to provide both, the last style given in the
+% list will be the one that is kept.
+% \end{multicols}
+%
+% \begin{multicols}{2}[\noindent\texttt{custom-pattern =} \marg{pattern} \marg{shift
+%    down} \marg{shift up}]
+% \SetMCRule{custom-pattern={\HandRight}{0pt}{0pt}} 
+%
+% The\stydsc{custom-pattern= \{\textbackslash HandRight\} \{0pt\}\{0pt\}}
+% second custom option is with the \kvdesc{custom-pattern} key. The syntax
+% is identical to that for \kvdesc{custom-tile}, but the content you specify
+% will appear once per page or column pair (if the columns occupy less than a
+% full page). This content will be vertically centered if the second and third
+% parameters are both 0pt. You can shift the content down by increasing the
+% second parameter, and up by increasing the third. The rule in this section
+% uses the \cs{HandRight} symbol from \pkg{bbding}.
+% \end{multicols}
+%
+% \begin{multicols}{2}[\noindent\texttt{custom-line =} \marg{draw command}]
+% \SetMCRule{custom-line={\path (TOP) to [ornament=88] (BOT);}}
+%
+% 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} 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} 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
+% \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. 
+% \end{multicols}
+%
+% \begin{multicols}{2}[\subsection{Colors}\label{sec:color}]
+% \SetMCRule{width=2pt,line-style=solid,color-model=cmy,color={0.7,0.5,0.3}}
+% You\stydsc{line-style=solid,\\width=2pt\\color-model=cmy,\\
+% color=\{0.7,0.5,0.3\}} can set colors for the rule through the
+% \kvdesc{color} and, optionally, the \kvdesc{color-model} keys. \mcrule{} loads the
+% \pkg{xcolor} package to manage colors, and the \kvdesc{color}
+% parameter accepts any name that \pkg{xcolor} recognizes, either natively or
+% as the result of any names you have defined with \cs{definecolor}
+% (see the \pkg{xcolor} documentation). Note that if you want to use color names that
+% are defined through the one of \pkg{xcolor}'s package options, you must load 
+% \pkg{xcolor} before both \mcrule{} and \pkg{tikz} with the relevant options.
+%  
+% To specify a color by a numeric specification, you use the
+% \kvdesc{color-model} parameter to specify any color model that
+% \pkg{xcolor} recognizes (rgb, cmy, etc), and \kvdesc{color} to
+% hold the color-specification list. Because that list is itself comma-separated,
+% you must enclose it in brackets.
+%  
+% The current color setting can always be found in
+% \cs{columnseprulecolor}. If you are running in twocolumn
+% mode without \pkg{multicol}, this command will be provided and colors will
+% work the same way they do with \pkg{multicol}. Note that setting the 
+% \kvdesc{color} key causes \cs{columnseprulecolor}
+% to be redefined within the current group only. If you directly redefine
+% \cs{columnseprulecolor}, the color of the custom rule will
+% reflect this setting. This way, the settings of any packages that might alter
+% the rule color will be respected.
+%\end{multicols}
+%
+% \begin{multicols}{2}[\subsection{Width}\label{sec:width}]
+% \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.
+%  
+% 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
+% reflect this change. Note that although some line styles do not depend 
+% directly on \cs{columnseprule} to calculate their actual width, the value
+% of \cs{columnseprule} must be greater than 0pt for any rule to appear. This
+% behavior is intentional and is in keeping with the way the default column
+% rules work.
+% \end{multicols}
+%
+% \begin{longtable}{ll}
+%   \caption{Sizes of named line widths\label{table:linewidths}} \\
+%   \toprule
+%   Name & Width\\
+%   \midrule
+%   \endfirsthead
+%   \caption{Sizes of named line widths (cont.)} \\
+%   \toprule
+%   Name & Width\\
+%   \midrule
+%   \endhead
+%   \kvdesc{ultra-thin} & 0.1pt\\
+%   \kvdesc{very-thin}  & 0.2pt\\
+%   \kvdesc{thin}       & 0.4pt\\
+%   \kvdesc{semithick}  & 0.6pt\\
+%   \kvdesc{thick}      & 0.8pt\\
+%   \kvdesc{very-thick} & 1.2pt\\
+%   \kvdesc{ultra-thick} & 1.6pt\\
+%   \bottomrule
+% \end{longtable}
+%
+% \begin{multicols}{2}[\subsection{Repeated Rules}\label{sec:repeats}]
+% \SetMCRule{line-style=dash-dot-dot,triple=2pt}
+%  
+% You can\stydsc{line-style= dash-dot-dot, triple=2pt} draw multiple,
+% 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}. 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
+% same time. If you use the key without a value \kvdesc{repeat-distance} is set
+% to \cs{columnseprule}.
+%
+% There are no checks made to ensure that repeated rules will fit in the
+% available space between columns, so you should be careful using these
+% commands, especially with thicker rules.
+% \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
+% 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 
+% \pkg{multicol} adds automatically below the columns. Note that if the amount
+% 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}
+%
+%\section{Implementation}
+%
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<@@=mcrule>
+%    \end{macrocode}
+%
+%\subsection{Preliminaries}
+%
+%    \begin{macrocode}
+\ProvidesExplPackage {multicolrule} {2019/01/01} {1.2}
+  {Decorative vertical rules between columns}
+%    \end{macrocode}
+%
+% We always need these packages.
+%    \begin{macrocode}
+\RequirePackage{l3keys2e}
+\RequirePackage{xpatch}
+\RequirePackage{xcolor}
+\RequirePackage{scrlfile}
+%    \end{macrocode}
+%
+% Define the messages we use.
+%    \begin{macrocode}
+\msg_new:nnn {multicolrule} {patch-success} {Patched~#1.}
+\msg_new:nnn {multicolrule} {patch-failure} {Error~patching~#1.}
+\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: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}
+% Flags for package options
+%    \begin{macrocode}
+\bool_new:N \g_@@_twocolumn_bool
+\bool_new:N \g_@@_use_tikz_bool
+%    \end{macrocode}
+%\end{variable}
+%
+%\begin{variable}{\l_@@_repeat_int,\l_@@_repeat_distance_dim}
+% Variables to support repeated copies of the rule.
+%    \begin{macrocode}
+\int_new:N  \l_@@_repeat_int
+\int_set:Nn \l_@@_repeat_int {1}
+\dim_new:N  \l_@@_repeat_distance_dim
+%    \end{macrocode}
+%\end{variable}
+%
+%\begin{variable}{\l_@@_extend_top_dim,
+%  \l_@@_extend_bot_dim,
+%  \l_@@_extend_fill_bool,
+%  \l_@@_extend_reserve_dim}
+% Variables to control the distance to extend the rule above and below the
+% natural column height.
+%    \begin{macrocode}
+\dim_new:N  \l_@@_extend_top_dim
+\dim_new:N  \l_@@_extend_bot_dim
+\bool_new:N \l_@@_extend_fill_bool
+\dim_new:N  \l_@@_extend_reserve_dim
+%    \end{macrocode}
+%\end{variable}
+%
+%\begin{variable}{\l_@@_color_name_tl,\l_@@_color_model_tl}
+% Keep name and color model so we can set them separately while retaining
+% the value of the other one.
+%    \begin{macrocode}
+\tl_new:N \l_@@_color_name_tl
+\tl_new:N \l_@@_color_model_tl
+%    \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.
+%
+%    \begin{macrocode}
+\@ifpackageloaded{tikz}
+{
+  \bool_gset_true:N \g_@@_use_tikz_bool
+}{}
+%    \end{macrocode}
+%
+% Set up the keys for package options and process them.
+%
+%    \begin{macrocode}
+\keys_define:nn {mcrule-opts}
+{
+  twocolumn .bool_gset:N = \g_@@_twocolumn_bool,
+  tikz      .bool_gset:N = \g_@@_use_tikz_bool,
+  tikz      .default:n   = true,
+}
+\ProcessKeysOptions{mcrule-opts}
+%    \end{macrocode}
+%
+% \subsection{Patching Output Routines}
+%
+%\begin{function}{\@@_column_height:,\@@_column_depth:}
+%
+% Get the height and depth of the box appropriate to the supported mode.
+%
+%    \begin{macrocode}
+\cs_new:Npn \@@_column_height: {}
+\cs_new:Npn \@@_column_depth: {}
+%    \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. 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} {\columnseprulecolor\vrule\@width\columnseprule}
+  {\mcruledivider}
+  {\msg_info:nnn {multicolrule} {patch-success} {#1}}
+  {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
+}
+%    \end{macrocode}
+%\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}
+  {\mcruledivider}
+  {\msg_info:nnn {multicolrule} {patch-success} {#1}}
+  {\msg_info:nnn {multicolrule} {patch-failure} {#1}}
+}
+%    \end{macrocode}
+%\end{function}
+%
+%    \begin{macrocode}
+\bool_if:NTF \g_@@_twocolumn_bool
+{
+  \@ifpackageloaded{multicol}
+  {\msg_warning:nn {multicolrule} {multicol-loaded}}{}
+%    \end{macrocode}
+% Provide the column-color macro from \pkg{multicol}.
+%    \begin{macrocode}
+  \cs_gset:Npn \columnseprulecolor {\normalcolor}
+  \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
+% rule with a macro that we can overwrite.
+%
+%    \begin{macrocode}
+  \@@_patch_twocol_output:N \@outputdblcol
+%    \end{macrocode}
+%
+% \pkg{bidi} has two output routines to patch, and it insists on being loaded
+% 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}
+  {
+    \@@_patch_twocol_output:N \RTL@outputdblcol
+    \@@_patch_twocol_output:N \LTR@outputdblcol
+  }
+}
+%    \end{macrocode}
+%
+% Now patch for \pkg{multicol}.
+%
+%    \begin{macrocode}
+{
+  \RequirePackage{multicol}
+  \@@_patch_mcol_output:N \LR@column@boxes
+  \@@_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.
+%
+%    \begin{macrocode}
+  \cs_gset:Npn \@@_column_height: {\box_ht:N \mult@rightbox}
+  \cs_gset:Npn \@@_column_depth: {\dimen\tw@}
+%    \end{macrocode}
+%
+% We need to reissue \cs{LRmulticolcolumns} to update the actual code in
+% \cmd{\mc@align@columns}.
+%
+%    \begin{macrocode}
+    \LRmulticolcolumns
+%    \end{macrocode}
+%
+% The \pkg{bidi} package supplies its own versions of most core
+% \pkg{multicol} functions, including the output boxes. Much of this is
+% unnecessary, as current versions of \pkg{multicol} support printing the
+% 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.
+%
+%    \begin{macrocode}
+  \AfterPackage!{bidi}
+  {
+    \cs_gset_eq:NN \LTR@column@boxes \LR@column@boxes
+    \cs_gset_eq:NN \RTL@column@boxes \RL@column@boxes
+%    \end{macrocode}
+%
+% While we're at it, we also redefine \cs{LRmulticolcolumns} and
+% \cs{RLmulticolcolumns} so they work the way people expect them to.
+%
+%    \begin{macrocode}
+    \cs_gset_eq:NN \LRmulticolcolumns \LTRmulticolcolumns
+    \cs_gset_eq:NN \RLmulticolcolumns \RTLmulticolcolumns
+  }
+}
+%    \end{macrocode}
+% 
+%
+% \subsection{Creating the Rules}
+% Utility functions for different rule types
+%
+%\begin{macro}{\mcruledivider}
+%
+% 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}.  \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}
+% 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} > {\c_zero_dim}}
+  {\int_compare_p:nNn {\l_@@_repeat_int} > {\c_zero_int}}
+  {
+    \mcrule_divider:
+    \prg_replicate:nn {\l_@@_repeat_int - \c_one_int}
+    {
+      \hspace{\l_@@_repeat_distance_dim}
+      \mcrule_divider:
+    }
+  }
+}
+%    \end{macrocode}
+%\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:
+{
+  \dim_eval:n {\@@_column_height: + \@@_column_depth: + 
+    \@@_extend_column_top: + \@@_extend_column_bottom:}
+}
+\cs_new:Npn \@@_column_total_depth:
+{
+  \dim_eval:n {\@@_column_depth: + \@@_extend_column_bottom:}
+}
+%    \end{macrocode}
+%\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:
+{
+  \l_@@_extend_top_dim
+}
+%    \end{macrocode}
+%\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:
+{
+  \bool_lazy_and:nnTF
+  {\bool_if_p:n {\l_@@_extend_fill_bool}}
+  {\bool_not_p:n {\g_@@_twocolumn_bool}}
+  {
+    \dim_compare:nNnTF 
+    {\@colroom - \@@_column_height: - \@@_extend_reserve:} > {\c_zero_dim}
+    {\@colroom - \@@_column_height: - \@@_extend_reserve:}
+    {\c_zero_dim}
+  }
+  {\l_@@_extend_bot_dim}
+}
+%    \end{macrocode}
+%\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} > {\c_zero_dim}
+  {\dim_eval:n {\l_@@_extend_reserve_dim + \multicolsep}}
+  {\c_zero_dim}
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\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} to specify a new line style.
+%    \begin{macrocode}
+\cs_new:Npn \mcrule_divider: {\vrule\@width\columnseprule}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_pattern:nnn}
+%  \begin{syntax}
+%    |\__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. 
+%    \begin{macrocode}
+\cs_new_nopar:Npn \@@_pattern:nnn #1#2#3
+{
+  \box_move_down:nn {\@@_column_total_depth:}
+  {
+    \vbox_to_ht:nn {\@@_column_total_height:}
+    {
+      \tex_vfill:D
+      \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
+      \tex_vfill:D
+    }
+  }
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_tile_pattern:nnn}
+%  \begin{syntax}
+%    |\__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. 
+%    \begin{macrocode}
+\cs_new_nopar:Npn \@@_tile_pattern:nnn #1#2#3
+{
+  \box_move_down:nn {\@@_column_total_depth:}
+  {
+    \vbox_to_ht:nn {\@@_column_total_height:}
+    {
+      \tex_cleaders:D \vbox:n
+      {
+        \tex_kern:D #2 \hbox:n{#1} \tex_kern:D #3
+      }
+    \tex_vfill:D
+    }
+  }
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_line_pattern:nnnn}
+%  \begin{syntax}
+%    |\__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
+{
+  \bool_if:NTF \g_@@_use_tikz_bool
+  {
+    \@@_pattern_line:n {#1}
+  } 
+  {
+    \@@_tile_pattern:nnn {\rule{\columnseprule}{#2}}{#3}{#4}
+  }
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_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.
+%    \begin{macrocode}
+\cs_new:Npn \@@_solid_line:
+{
+  \rule[-\@@_column_total_depth:]{\columnseprule}{\@@_column_total_height:}
+}
+%    \end{macrocode}
+%\end{function}
+%
+% \subsubsection{Tikz-only Routines}
+%
+% If we're supporting \pkg{tikz}, make sure it's loaded and redefine the
+% relevant functions. We turn off |expl3| syntax to load the package because
+% \pkg{tikz} relies on 2e catcodes, especially for spaces.
+%
+%    \begin{macrocode}
+\bool_if:NTF \g_@@_use_tikz_bool
+{
+  \ExplSyntaxOff
+  \RequirePackage{tikz}
+  \ExplSyntaxOn  
+%    \end{macrocode}
+% 
+%\begin{function}{\@@_tikz_picture:n}
+%  \begin{syntax}
+%    |\__mcrule_tikz_picture:n| \Arg{draw function}
+%  \end{syntax}
+% Set up the \env{tikzpicture} environment and declare two nodes, named |(TOP)|
+% and |(BOT)|. This way we can pass a \cs{draw} routine directly,
+% without worrying about the line's coordinates.
+%
+%    \begin{macrocode}
+\cs_set:Npn \@@_tikz_picture:n #1
+{
+  \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt,
+    baseline={([yshift=\@@_column_total_depth:]current~bounding~box.south)}]
+  \node (TOP) at (0,\@@_column_total_height:) {};
+  \node (BOT) at (0,0) {};
+  #1
+    \end{tikzpicture}
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_pattern_line:n}
+%  \begin{syntax}
+%    |\__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 
+% contain the name of a line style that \pkg{tikz} recognizes.
+%    \begin{macrocode}
+\cs_set:Npn \@@_pattern_line:n #1
+{
+  \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt,
+    baseline={([yshift=\@@_column_total_depth:]current~bounding~box.south)}]
+  \draw[line~width=\columnseprule,#1] (0,\@@_column_total_height:) -- (0,0);
+  \end{tikzpicture}
+}
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_circle:}
+% Draw a hollow circle with a diameter equal to |\columnseprule|. This will be
+% used as a tile pattern.
+%
+%    \begin{macrocode}
+  \cs_set:Npn \@@_circle: 
+  {
+    \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt]
+    \draw (0,0) circle[radius=.5\columnseprule];
+    \end{tikzpicture}
+  }
+%    \end{macrocode}
+%\end{function}
+%
+%\begin{function}{\@@_solid_circle:}
+% Draw a filled circle with a diameter equal to |\columnseprule|. This will be
+% used as a tile pattern.
+%
+%    \begin{macrocode} 
+  \cs_set:Npn \@@_solid_circle: 
+  {
+    \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt]
+    \fill (0,0) circle[radius=.5\columnseprule];
+    \end{tikzpicture}
+  } 
+}
+%    \end{macrocode}
+%\end{function}
+%
+% In case \pkg{tikz} functions are not active, we provide stubs
+% that issue error messages.
+%
+%    \begin{macrocode}
+{
+  \cs_set:Npn \@@_tikz_picture:n #1
+    {\msg_error:nnn {multicolrule} {tikz-required} {#1}}
+  \cs_new:Npn \@@_pattern_line:n #1
+    {\msg_error:nnn {multicolrule} {tikz-required} {#1}}
+  \cs_new:Npn \@@_circle: 
+    {\msg_error:nnn {multicolrule} {tikz-required} {circles}}
+  \cs_new:Npn \@@_solid_circle: 
+    {\msg_error:nnn {multicolrule} {tikz-required} {solid-circles}}
+}
+%    \end{macrocode}
+%
+% \subsection{Color}
+%\begin{function}{\@@_set_rule_color:}
+% Reset color definition in \cs{columnseprulecolor} by name or
+% by model and color specification.
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_rule_color:
+{
+  \tl_if_empty:NT \l_@@_color_name_tl
+  {
+    \tl_set:Nn \l_@@_color_name_tl {black}
+  }
+  \tl_if_empty:NTF \l_@@_color_model_tl
+  {
+    \cs_set:Npn \columnseprulecolor {\color{\l_@@_color_name_tl}}
+  }
+  {
+    \cs_set:Npn \columnseprulecolor 
+    {\color[\l_@@_color_model_tl]{\l_@@_color_name_tl}}
+  }
+}
+%    \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{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}
+{
+  extend-top                       .dim_set:N  = \l_@@_extend_top_dim,
+  extend-bot                       .dim_set:N  = \l_@@_extend_bot_dim,
+  extend-fill                      .bool_set:N = \l_@@_extend_fill_bool,
+  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 \mcrule_divider: 
+    {\vrule\@width\columnseprule},
+  line-style / solid               .code:n = \cs_set:Npn \mcrule_divider: 
+    {\@@_solid_line:},
+  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: 
+    {\@@_tile_pattern:nnn {.}{1pt}{0pt}},
+  line-style / loose-dots          .code:n = \cs_set:Npn \mcrule_divider:
+    {\@@_tile_pattern:nnn {.}{2pt}{2pt}},
+  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 \mcrule_divider:
+    {\@@_tile_pattern:nnn {\@@_circle:}{1pt}{0pt}},
+  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 \mcrule_divider: 
+    {\@@_tile_pattern:nnn {\@@_solid_circle:}{1pt}{1pt}},
+  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 \mcrule_divider:
+    {\@@_tile_pattern:nnn {\@@_solid_circle:}{2pt}{2pt}},
+  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 \mcrule_divider:
+    {\@@_line_pattern:nnnn {densely~dotted}{\columnseprule}{1pt}{0pt}},
+  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 \mcrule_divider:
+    {\@@_line_pattern:nnnn {dashed}{3pt}{1.5pt}{1.5pt}},
+  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 \mcrule_divider: 
+    {\@@_line_pattern:nnnn {loosely~dashed}{3pt}{3pt}{3pt}},
+  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 \mcrule_divider: 
+    {\@@_pattern_line:n{densely~dash~dot}},
+  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 \mcrule_divider:
+    {\@@_pattern_line:n{dash~dot~dot}},
+  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 \mcrule_divider:
+    {\@@_pattern_line:n{loosely~dash~dot~dot}},
+  color                             .code:n = {
+    \tl_set:Nn \l_@@_color_name_tl {#1}
+    \@@_set_rule_color:
+  },
+  color-model                       .code:n = {
+    \tl_set:Nn \l_@@_color_model_tl {#1}
+    \@@_set_rule_color:
+  },
+  custom-line         .code:n = \cs_set:Npn \mcrule_divider:
+    {\@@_tikz_picture:n {#1}},
+  custom-pattern      .code:n = \cs_set:Npn \mcrule_divider:
+    {\@@_pattern:nnn #1},
+  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},
+  width / very-thin   .code:n = \dim_set:Nn \columnseprule {0.2pt},
+  width / thin        .code:n = \dim_set:Nn \columnseprule {0.4pt},
+  width / semithick   .code:n = \dim_set:Nn \columnseprule {0.6pt},
+  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      = {
+    repeat = 1,
+    repeat-distance = #1
+  },
+  single              .default:n   = \columnseprule,
+  double              .meta:n      = {
+    repeat = 2,
+    repeat-distance = #1
+  },
+  double              .default:n   = \columnseprule,
+  triple              .meta:n      = {
+    repeat = 3,
+    repeat-distance = #1
+  },
+  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}
+%
+%\begin{macro}{\SetMCRule}
+% 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}
+{
+  \keys_set:nn {mcrule} {#1}
+}
+%    \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
+%
+% \PrintIndex
\ No newline at end of file
-- 
cgit v1.2.3

