% 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'.