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?
1 Answer
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.
-
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 :-) Oct 13, 2011 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 :) Oct 13, 2011 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 Oct 13, 2011 at 13:54
-
1When you want characters to behave as if they were active in math mode, set their
\mathcode
to"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}
. Oct 13, 2011 at 16:10 -
1@Tobias:
\lowercase
is 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 tex.stackexchange.com/questions/15744/… and tex.stackexchange.com/questions/28581/… Oct 14, 2011 at 22:01
breqn
package (which is aware of nesting since it makes that affect the badness of line-breaks), or into thenath
package (which IIRC changes every(
to\left(
: then hook to add a test on the\currentgrouplevel
to each left and right delimiter), or a more down-to-earth approach by setting the\mathcode
of(
etc. to be"8000
, and defining an active(
to produce the right color and increment a nesting counter.