% RainbowBrackets v. 1.1.1 y. 2025
% 
% Copyright (C) 2025 Paul Eduard Koenig
% pauleduardkoenig (at) gmail [dot] com
% Goethe University Frankfurt, Institute of Linguistics
%
% --------------------------------
% 
% Provides automatic coloring of nested parentheses using a configurable color cycle.
% Tracks nesting depth with a counter and warns about unbalanced parentheses at end of document.
% 
% This file 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:
% http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of
% LaTeX version 2008-05-04 or later.
% 
% This work has the LPPL maintenance status `maintained'.
% The Current Maintainer of this work is Paul Eduard Koenig.
% This work consists of the files rainbowbrackets.sty and rainbowbrackets_doc.tex
%
% ------------------------------------------------------------ 
% header
% ------------------------------------------------------------ 
%
% The groundwork of this package is based on workd by Ryan Reich, jub0bs, and Matthew Towers
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{rainbowbrackets}[2025-07-18 v. 1.1.1 LaTeX package that colors parentheses on the same nesting level with a matching color.]
\RequirePackage{xparse, xcolor, expl3, kvoptions}

\SetupKeyvalOptions{
	family=RB,
	prefix=RB@
}
\DeclareStringOption[default]{style}
\DeclareStringOption[10]{max}
\ProcessKeyvalOptions*

\let\@rbmaxbackup\RB@max
\NewDocumentCommand{\setrainbowbracketmax}{m}{%
\def\RB@max{#1}%
}
\NewDocumentCommand{\resetrainbowbracketmax}{}{%
\def\RB@max{\@rbmaxbackup}%
}

\newcounter{@rbbparenscounter}
\newcommand{\@countlparen}{\addtocounter{@rbbparenscounter}{1}\@rbbrainbow{\@rblparen}}
\newcommand{\@countrparen}{\@rbbrainbow{\@rbrparen}\addtocounter{@rbbparenscounter}{-1}}

\newcommand{\@countlpareN}{\addtocounter{@rbbparenscounter}{1}\@rbbrainbowbf{\@rblparen}}
\newcommand{\@countrpareN}{\@rbbrainbowbf{\@rbrparen}\addtocounter{@rbbparenscounter}{-1}}

% This snipped is based on work by Ryan Reich, jub0bs, and Matthew Towers
% https://github.com/matthew-towers/latex-rainbow
\begingroup
\catcode`(\active
\catcode`)\active
\gdef\@count@rbbparenscounter{%
\let(\@countlparen%
\let)\@countrparen%
}
\gdef\@count@rbbparenscounteR{%
\let(\@countlpareN%
\let)\@countrpareN%
}
\endgroup

\let\@rblparen(
\let\@rbrparen)
\newenvironment{rb}{\catcode`(\active\catcode`)\active\@count@rbbparenscounter}{\ifnum\value{@rbbparenscounter}=0\relax\else\ifnum\value{@rbbparenscounter}<0\relax\PackageWarning{rainbowbrackets}{Unbalanced parentheses detected! Counter value is \number\numexpr\value{@rbbparenscounter}\relax. Did you forget an opening parenthesis?}\else\PackageWarning{rainbowbrackets}{Unbalanced parentheses detected! Counter value is \number\numexpr\value{@rbbparenscounter}\relax. Did you forget a closing parenthesis?}\fi\fi\setcounter{@rbbparenscounter}{0}}
\newenvironment{rB}{\catcode`(\active\catcode`)\active\@count@rbbparenscounteR}{\ifnum\value{@rbbparenscounter}=0\relax\else\ifnum\value{@rbbparenscounter}<0\relax\PackageWarning{rainbowbrackets}{Unbalanced parentheses detected! Counter value is \number\numexpr\value{@rbbparenscounter}\relax. Did you forget an opening parenthesis?}\else\PackageWarning{rainbowbrackets}{Unbalanced parentheses detected! Counter value is \number\numexpr\value{@rbbparenscounter}\relax. Did you forget a closing parenthesis?}\fi\fi\setcounter{@rbbparenscounter}{0}}
% End of snippet


\ExplSyntaxOn

% Style logic
\clist_new:N \l_colorcodes_clist
\int_new:N \l_index_int

\cs_new_protected:Nn \rb_define_style_colors:n
  {
	\clist_set:Nx \l_colorcodes_clist { 000000 , b4611E , 3CB44B , 4363D8 , F58231 , 911EB4 , B41E2D , 7BB41E , B41E93 , FFE119 }
	\str_case:nnF { #1 }
      {
        { default }  {}
        { neon }  { \clist_set:Nx \l_colorcodes_clist  { 000000, 001EFF , 39FF14 , FFFF00 , FF00FF, 00FFFF , FFA500 , FF0000 , FF6600 , 74EE15 } }
        { pastel }  { \clist_set:Nx \l_colorcodes_clist  { 000000 , 66c5cc , f6cf71 , dcb0f2 , f89c74 , 87c55f , 9eb9f3 , fe88b1 , c9db74 , 8be0a4 } }
        { spectral }  { \clist_set:Nx \l_colorcodes_clist  { 000000 , 9e0142 , 5e4fa2 , d53e4f , 3288bd , f46d43 , 66c2a5 , fee08b , abdda4 , e6f598 } }
        { dualpolar }  { \clist_set:Nx \l_colorcodes_clist  { 000000 , a55a22 , 41b764, 5aad4e, 6da33a, 7c9829, 898d1b, 938114, 9b7414, a1671a} }
        { warning }  { \clist_set:Nx \l_colorcodes_clist  { 000000 , 750000, ffb37d, ff9160, ff6e44, ff4928, ff1407, dd0000, b90000, 960000} }
      }
      {\PackageWarning{rainbowbrackets}{Unknown~style~'#1',~using~default~style!}}
	  \int_zero:N \l_index_int
		\clist_map_inline:Nn \l_colorcodes_clist
		  {
			\definecolor{rbbcpcolor\int_use:N \l_index_int}{HTML}{##1}
			\int_incr:N \l_index_int
		  }
  }

\NewDocumentCommand{\setrbstyle}{m}
  {
    \rb_define_style_colors:n { #1 }
  }

% Bracket coloring logic
\cs_new:Npn \RB_get_modulo_max: {
  \int_eval:n { \RB@max }
}

\NewDocumentCommand{\@rbbrainbow}{m}
{%
\modswitch_fixed_counter:n {#1}%
}

\NewDocumentCommand{\@rbbrainbowbf}{m}
{%
\modswitch_fixed_counter:n {\textbf{#1}}%
}

\cs_new_protected:Npn \modswitch_fixed_counter:n #1
 {
  % Read value from counter
  \int_set:Nn \l_tmpa_int { \int_mod:nn { \value{@rbbparenscounter} } { \RB_get_modulo_max: } }

  % Perform "switch-case" logic
  \int_case:nnF { \l_tmpa_int }
   {
    { 0 } {\textcolor{rbbcpcolor1}{#1}}
    { 1 } {\textcolor{rbbcpcolor0}{#1}}
    { 2 } {\textcolor{rbbcpcolor2}{#1}}
    { 3 } {\textcolor{rbbcpcolor3}{#1}}
    { 4 } {\textcolor{rbbcpcolor4}{#1}}
	{ 5 } {\textcolor{rbbcpcolor5}{#1}}
	{ 6 } {\textcolor{rbbcpcolor6}{#1}}
	{ 7 } {\textcolor{rbbcpcolor7}{#1}}
	{ 8 } {\textcolor{rbbcpcolor8}{#1}}
	{ 9 } {\textcolor{rbbcpcolor9}{#1}}
   }
   {\textcolor{rbbcpcolor0}{#1}}
}

\ExplSyntaxOff

\newcommand{\resetrbstyle}{\expandafter\setrbstyle\expandafter{\RB@style}}
\expandafter\setrbstyle\expandafter{\RB@style}
\endinput
% End of file `rainbowbrackets.sty'.