Say I have an expressions like $(\sin(x-3(z^{(x-2)^2}))+1)^2$ with many nested expressions. To better visualize this in the output (and to help finding missing delimiters when proof-reading) I'd like to have nested expressions and their delimiter show up in a different color than its surrounding. Is there a package for that purpose?
Asked
Active
Viewed 290 times
10
Tobias Kienzler
- 1,232
1 Answers
6
I am not aware of any packages that do this. A relatively easy way is to redefine ( and ) as command sequences that keep count of the level and change the colour accordingly. That would look like this:
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\let\dotlessi\i
\catcode`(=\active
\catcode`)=\active
\newcounter{nestlvl}
\setcounter{nestlvl}{1}
\newcounter{temp}
\newcommand{\colorlst}{black,blue,red,green,yellow,brown}
\def({%
\setcounter{temp}{0}%
\addtocounter{nestlvl}{1}%
\@for\i:=\colorlst\do{%
\stepcounter{temp}%
\ifnum\arabic{temp}<\arabic{nestlvl}%
\color{\i}%
\fi%
}%
\char`(%
}
\def){%
\setcounter{temp}{0}%
\addtocounter{nestlvl}{-1}%
\ifnum\arabic{nestlvl}<0%
\message{nesting error}%
\fi%
\char`)%
\@for\i:=\colorlst\do{%
\stepcounter{temp}%
\ifnum\arabic{temp}<\arabic{nestlvl}%
\color{\i}%
\fi%
}%
}
\let\i\dotlessi
\makeatother
\begin{document}
(test(multi(levels)colors)like this)
\end{document}
The amount of colors specified this way is limited, I couldn't think of something more elegant right now. Perhaps somebody has a suggestion how colors can be picked in a better way.
The result:

And your example:

Note the exponents have the colour of the parentheses group they are in, this might not be what you actually want. It would require a bit of additional code to fix this. I think it looks horrible, but that is mainly due to the poor choice of colours on my end.
Roelof Spijker
- 17,663
- 5
- 55
- 63
-
this looks good, thank you! I guess with a second counter one could even extend this to make sure neighbouring nested expressions like
(this (one (is)) (a neighbour))have different colors. Another extension would be including brackets ([]) and braces ({}), but then one could go even further and add a delimiter matching algorithm and... erm, I stop here and just accept your answer :-) – Tobias Kienzler Oct 13 '11 at 13:43 -
If you really want to you can take this quite far. This is just a basic working example to show (one of) the mechanism(s) you can use to achieve this kind of thing. If you are going to extend it into something more powerful, please let me know, I'd be interested to see how far it can be extended. Although I am unsure of how much demand there is for something like this :) – Roelof Spijker Oct 13 '11 at 13:48
-
true. But you're probably right concerning the lack of demand, it appears to work fine the way you wrote it, so unless someone else feels the desire for improvements I'd call YAGNI :-7 But I guess the exponential's color can be adapted the easiest by making sub- and superscripts raise the color nesting level as well – Tobias Kienzler Oct 13 '11 at 13:54
-
1When you want characters to behave as if they were active in math mode, set their
\mathcodeto"8000, and define them for instance using\begingroup\lccode`~=`(\lowercase{\endgroup\def~}instead of\def(. Then they will still behave as expected outside math mode, an still be usable in arguments such as for\begin{picture}. – Bruno Le Floch Oct 13 '11 at 16:10 -
@Bruno good point, but what does
\lowercasehave to do with this? – Tobias Kienzler Oct 14 '11 at 11:45 -
1@Tobias:
\lowercaseis just there to make it easier to define an active character: in this precise case, it converts the active~into an active(. See for instance egreg's answers http://tex.stackexchange.com/questions/15744/can-pdflatex-recognize-text-strings-and-replace-expand-them/15761#15761 and http://tex.stackexchange.com/questions/28581/active-characters-after-begindocument/28625#28625 – Bruno Le Floch Oct 14 '11 at 22:01 -
@Bruno thanks, I see there's a lot about I don't know about TeX... – Tobias Kienzler Oct 15 '11 at 07:42
breqnpackage (which is aware of nesting since it makes that affect the badness of line-breaks), or into thenathpackage (which IIRC changes every(to\left(: then hook to add a test on the\currentgrouplevelto each left and right delimiter), or a more down-to-earth approach by setting the\mathcodeof(etc. to be"8000, and defining an active(to produce the right color and increment a nesting counter. – Bruno Le Floch Oct 13 '11 at 12:03breqntreat mismatching delimiters such as(]? – Tobias Kienzler Oct 13 '11 at 12:14