%%
%% This is file `multicolrule.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% multicolrule.dtx  (with options: `package')
%% ----------------------------------------------------------------
%% 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
%% ----------------------------------------------------------------
%% 
\RequirePackage{expl3}
\RequirePackage{xparse}
\ProvidesExplPackage {multicolrule} {2020/09/14} {1.3a}
  {Decorative vertical rules between columns}
\RequirePackage{l3keys2e}
\RequirePackage{xpatch}
\RequirePackage{xcolor}
\RequirePackage{scrlfile}
\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.}
\bool_new:N \g__mcrule_twocolumn_bool
\bool_new:N \g__mcrule_use_tikz_bool
\bool_new:N \g__mcrule_paracol_bool
\int_new:N  \l__mcrule_repeat_int
\int_set:Nn \l__mcrule_repeat_int {1}
\dim_new:N  \l__mcrule_repeat_distance_dim
\dim_new:N  \l__mcrule_extend_top_dim
\dim_new:N  \l__mcrule_extend_bot_dim
\bool_new:N \l__mcrule_extend_fill_bool
\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
}{}
\keys_define:nn {mcrule-opts}
{
  twocolumn .bool_gset:N = \g__mcrule_twocolumn_bool,
  twocolumn .default:n   = true,
  tikz      .bool_gset:N = \g__mcrule_use_tikz_bool,
  tikz      .default:n   = true,
  paracol   .bool_gset:N = \g__mcrule_paracol_bool,
  paracol   .default:n   = true,
}
\ProcessKeysOptions{mcrule-opts}
\cs_new:Npn \__mcrule_column_height: {}
\cs_new:Npn \__mcrule_column_depth: {}
\cs_new:Npn \__mcrule_column_overflow: {0pt}
\cs_new_protected:Npn \__mcrule_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}}
}
\cs_new_protected:Npn \__mcrule_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}}
}
\bool_if:NTF \g__mcrule_twocolumn_bool
{
  \@ifpackageloaded{multicol}
  {\msg_warning:nn {multicolrule} {multicol-loaded}}{}
  \cs_gset:Npn \columnseprulecolor {\normalcolor}
  \cs_gset:Npn \__mcrule_column_height: {\box_ht:N \@outputbox}
  \cs_gset:Npn \__mcrule_column_depth: {\box_dp:N \@outputbox}
  \__mcrule_patch_twocol_output:N \@outputdblcol
  \AfterAtEndOfPackage*{bidi}
  {
    \__mcrule_patch_twocol_output:N \RTL@outputdblcol
    \__mcrule_patch_twocol_output:N \LTR@outputdblcol
  }
}
{
  \RequirePackage{multicol}
  \__mcrule_patch_mcol_output:N \LR@column@boxes
  \__mcrule_patch_mcol_output:N \RL@column@boxes
  \cs_gset:Npn \__mcrule_column_height:
  {
    \box_ht:N \mult@rightbox
  }
  \cs_gset:Npn \__mcrule_column_depth:
  {
    \dim_max:nn {\dimen\tw@}{\box_dp:N \mult@rightbox}
  }
\cs_gset:Npn \__mcrule_column_overflow:
{
  \dim_max:nn {\box_ht:N \mult@nat@firstbox - \box_ht:N \mult@rightbox}{0pt}
}
    \LRmulticolcolumns
  \AfterPackage!{bidi}
  {
    \cs_gset_eq:NN \LTR@column@boxes \LR@column@boxes
    \cs_gset_eq:NN \RTL@column@boxes \RL@column@boxes
    \cs_gset_eq:NN \LRmulticolcolumns \LTRmulticolcolumns
    \cs_gset_eq:NN \RLmulticolcolumns \RTLmulticolcolumns
  }
}
\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} > {\c_zero_dim}}
  {\int_compare_p:nNn {\l__mcrule_repeat_int} > {\c_zero_int}}
  {
    \mcrule_divider:
    \prg_replicate:nn {\l__mcrule_repeat_int - \c_one_int}
    {
      \hspace{\l__mcrule_repeat_distance_dim}
      \mcrule_divider:
    }
  }
}
\cs_new:Npn \__mcrule_column_total_height:
{
  \dim_eval:n {\__mcrule_column_height: + \__mcrule_column_depth: +
    \__mcrule_extend_column_top: + \__mcrule_column_overflow: + \__mcrule_extend_column_bottom:}
}
\cs_new:Npn \__mcrule_column_total_depth:
{
  \dim_eval:n {\__mcrule_column_depth: + \__mcrule_column_overflow: +
    \__mcrule_extend_column_bottom:}
}
\cs_new:Npn \__mcrule_extend_column_top:
{
  \l__mcrule_extend_top_dim
}
\cs_new:Npn \__mcrule_extend_column_bottom:
{
  \bool_lazy_and:nnTF
  {\bool_if_p:n {\l__mcrule_extend_fill_bool}}
  {\bool_not_p:n {\g__mcrule_twocolumn_bool}}
  {
    \dim_compare:nNnTF
    {\@colroom - \__mcrule_column_height: - \__mcrule_extend_reserve:} > {\c_zero_dim}
    {\@colroom - \__mcrule_column_height: - \__mcrule_extend_reserve:}
    {\c_zero_dim}
  }
  {\l__mcrule_extend_bot_dim}
}
\cs_new:Npn \__mcrule_extend_reserve:
{
  \dim_compare:nNnTF {\l__mcrule_extend_reserve_dim} > {\c_zero_dim}
  {\dim_eval:n {\l__mcrule_extend_reserve_dim + \multicolsep}}
  {\c_zero_dim}
}
\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:}
  {
    \vbox_to_ht:nn {\__mcrule_column_total_height:}
    {
      \tex_vfill:D
      \tex_kern:D \dim_eval:n {#2} \exp_stop_f:
      \hbox:n{#1}
      \tex_kern:D \dim_eval:n {#3} \exp_stop_f:
      \tex_vfill:D
    }
  }
}
\cs_new_nopar:Npn \__mcrule_tile_pattern:nnn #1#2#3
{
  \box_move_down:nn {\__mcrule_column_total_depth:}
  {
    \vbox_to_ht:nn {\__mcrule_column_total_height:}
    {
      \tex_cleaders:D \vbox:n
      {
        \tex_kern:D \dim_eval:n {#2} \exp_stop_f:
        \hbox:n{#1}
        \tex_kern:D \dim_eval:n {#3} \exp_stop_f:
      }
    \tex_vfill:D
    }
  }
}
\cs_new:Npn \__mcrule_line_pattern:nnnn #1#2#3#4
{
  \bool_if:NTF \g__mcrule_use_tikz_bool
  {
    \__mcrule_pattern_line:n {#1}
  }
  {
    \__mcrule_tile_pattern:nnn {\rule{\columnseprule}{#2}}{#3}{#4}
  }
}
\cs_new:Npn \__mcrule_solid_line:
{
  \rule[-\__mcrule_column_total_depth:]{\columnseprule}{\__mcrule_column_total_height:}
}
\cs_new:Npn \__mcrule_strut:
{
  \rule[-\__mcrule_column_total_depth:]{0pt}{\__mcrule_column_total_height:}
}
\bool_if:NTF \g__mcrule_use_tikz_bool
{
  \ExplSyntaxOff
  \RequirePackage{tikz}
  \ExplSyntaxOn
\cs_set:Npn \__mcrule_tikz_picture:n #1
{
  \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt,
    baseline={([yshift=\__mcrule_column_total_depth:]current~bounding~box.south)}]
  \node (TOP) at (0,\__mcrule_column_total_height:) {};
  \node (BOT) at (0,0) {};
  #1
    \end{tikzpicture}
}
\cs_set:Npn \__mcrule_pattern_line:n #1
{
  \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt,
    baseline={([yshift=\__mcrule_column_total_depth:]current~bounding~box.south)}]
  \draw[line~width=\columnseprule,#1] (0,\__mcrule_column_total_height:) -- (0,0);
  \end{tikzpicture}
}
  \cs_set:Npn \__mcrule_circle:
  {
    \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt]
    \draw (0,0) circle[radius=.5\columnseprule];
    \end{tikzpicture}
  }
  \cs_set:Npn \__mcrule_solid_circle:
  {
    \begin{tikzpicture}[x=1pt,y=1pt,inner~sep=0pt,outer~sep=0pt]
    \fill (0,0) circle[radius=.5\columnseprule];
    \end{tikzpicture}
  }
}
{
  \cs_set:Npn \__mcrule_tikz_picture:n #1
    {\msg_error:nnn {multicolrule} {tikz-required} {#1}}
  \cs_new:Npn \__mcrule_pattern_line:n #1
    {\msg_error:nnn {multicolrule} {tikz-required} {#1}}
  \cs_new:Npn \__mcrule_circle:
    {\msg_error:nnn {multicolrule} {tikz-required} {circles}}
  \cs_new:Npn \__mcrule_solid_circle:
    {\msg_error:nnn {multicolrule} {tikz-required} {solid-circles}}
}
\cs_new_protected:Npn \__mcrule_set_rule_color:
{
  \tl_if_empty:NT \l__mcrule_color_name_tl
  {
    \tl_set:Nn \l__mcrule_color_name_tl {black}
  }
  \tl_if_empty:NTF \l__mcrule_color_model_tl
  {
    \cs_set:Npn \columnseprulecolor {\color{\l__mcrule_color_name_tl}}
  }
  {
    \cs_set:Npn \columnseprulecolor
    {\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,
  extend-bot                       .dim_set:N  = \l__mcrule_extend_bot_dim,
  extend-fill                      .bool_set:N = \l__mcrule_extend_fill_bool,
  extend-fill                      .default:n = true,
  extend-reserve                   .dim_set:N  = \l__mcrule_extend_reserve_dim,
  expand                           .code:n = {
    \dim_set:Nn \l__mcrule_extend_bot_dim {#1}
    \dim_set:Nn \l__mcrule_extend_top_dim {#1}
  },
  shift                            .code:n = {
    \dim_set:Nn \l__mcrule_extend_bot_dim {#1}
    \dim_set:Nn \l__mcrule_extend_top_dim {\fp_to_dim:n {-1 * \l__mcrule_extend_bot_dim}}
  },
  line-style                       .choice:,
  line-style / default             .code:n = \cs_set:Npn \mcrule_divider:
    {\vrule\@width\columnseprule},
  line-style / solid               .code:n = \cs_set:Npn \mcrule_divider:
    {\__mcrule_solid_line:},
  line-style / strut               .code:n = \cs_set:Npn \mcrule_divider:
    {\__mcrule_strut:},
  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:
    {\__mcrule_tile_pattern:nnn {.}{1pt}{0pt}},
  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:
    {\__mcrule_tile_pattern:nnn {\__mcrule_circle:}{1pt}{1pt}},
  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:
    {\__mcrule_tile_pattern:nnn {\__mcrule_circle:}{2pt}{2pt}},
  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:
    {\__mcrule_tile_pattern:nnn {\__mcrule_solid_circle:}{1pt}{0pt}},
  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:
    {\__mcrule_line_pattern:nnnn {dotted}{\columnseprule}{1pt}{1pt}},
  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:
    {\__mcrule_line_pattern:nnnn {loosely~dotted}{\columnseprule}{2pt}{2pt}},
  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:
    {\__mcrule_line_pattern:nnnn {densely~dashed}{3pt}{1pt}{1pt}},
  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:
    {\__mcrule_pattern_line:n{dash~dot}},
  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:
    {\__mcrule_pattern_line:n{loosely~dash~dot}},
  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:
    {\__mcrule_pattern_line:n{densely~dash~dot~dot}},
  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}
    \__mcrule_set_rule_color:
  },
  color-model                       .code:n = {
    \tl_set:Nn \l__mcrule_color_model_tl {#1}
    \__mcrule_set_rule_color:
  },
  custom-line         .code:n = \cs_set:Npn \mcrule_divider:
    {\__mcrule_tikz_picture:n {#1}},
  custom-pattern      .code:n = \cs_set:Npn \mcrule_divider:
    {\__mcrule_pattern:nnn #1},
  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},
  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__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      = {
    repeat = 2,
    repeat-distance = #1
  },
  double              .default:n   = \columnseprule,
  triple              .meta:n      = {
    repeat = 3,
    repeat-distance = #1
  },
  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}
}
\NewDocumentCommand{\DeclareMCRulePattern}{m m}
{
  \prop_gput:Nnn \g__mcrule_patterns_prop {#1} {#2}
}
%% Copyright (C) 2018-2020 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.
%%
%% End of file `multicolrule.sty'.
