# Highlighting text through stacked colored underlines

I have sentences in which characters have been "marked" by some people and not by others. I'd like to present the markings simultaneously. Stacked colored underlining (in which a line represents each person's marks) seems like the best solution. However, I'm struggling to make that happen. How can I present multiple markings simultaneously?

## Code That Fails

Because } closes the most recent {, the following code only works for a subset of examples (it fails on the goal example):

\documentclass{article}
\usepackage{xcolor}
\newcommand{\rul}[1]{\textcolor{red}{\underline{\textcolor{black}{#1}}}}
\newcommand{\bul}[1]{\textcolor{blue}{\underline{\textcolor{black}{#1}}}}

\begin{document}
\rul{sample \bul{with blue embedded} and continuing red}
\end{document}


I've experimented a bit with \lefteqn and \phantom. Using these commands resolves the bracket mismatching, but it has two other problems: it's text in math mode, and there isn't a vertical gap between the two underlining colors:

$\lefteqn{\rul{\phantom{overlapping high}}}overlapping \bul{highlighting}$


## Other Considerations

I need to make many pages of this sort of text. For readability, the solution should have the following properties:

• Underlining automatically wraps across lines.
• Underlining of a single color stays on the same horizontal level throughout the document (e.g., blue is always n units below baseline).
• Scales up to ~10 stacked underlines in a document section.

Because of the amount of this text, a readable/maintainable solution would be aces.

-
Welcome to TeX.SX! – Paul Gessler Apr 2 '14 at 19:16
– Steven B. Segletes Apr 2 '14 at 19:35
While soul is a consideration, it cannot be nested... – Werner Apr 2 '14 at 20:23
My suspicion is that any solution will not will not be fun or even remotely easy to type; and the resulting markup will be well-nigh impossible to read. I would consider typesetting the document sans coloured underlines but with a large enough value for baselinestretch and then use a raphics program (e.g., GIMP) to manually draw these lines. It will surely be quicker to do it this way, and surely much easier to maintain. Not as 'fun' a solution, probably, but easier to do! – jon Apr 2 '14 at 20:33
@PaulGessler Thanks for the welcome. – plt Apr 2 '14 at 21:05

This answer will NOT wrap. Nonethless, proceeding...

Here, I introduce \nunderline[]{}{}. The optional argument is the under-level for rule placement (relative to the prior placement). The first argument is the text, and the second argument is the color. The rule thickness is set with \rulethick and th relative spacing with \lunderset.

Nesting is used to obtain multiple lines under a given phrase. To take you through it, line by line:

1. underline "overlap" in red%

2. underline "ping " in red and then, 2 levels below that, in cyan%

3. underline "high" in red, then blue, then cyan%

4. underline "light" at the 2nd level in blue, and below that, in cyan%

5. underline "ing" at the 3rd level in cyan.

\documentclass{article}
\usepackage{stackengine}
\usepackage{xcolor}
\newlength\lunderset
\newlength\rulethick
\lunderset=1.5pt\relax
\rulethick=.8pt\relax
\def\stackalignment{l}
\newcommand\nunderline[3][1]{\setbox0=\hbox{#2}%
\stackunder[#1\lunderset-\rulethick]{\strut#2}{\color{#3}\rule{\wd0}{\rulethick}}}
\begin{document}
\nunderline{overlap}{red}%
\nunderline[2]{\nunderline{ping }{red}}{cyan}%
\nunderline{\nunderline{\nunderline{high}{red}}{blue}}{cyan}%
\nunderline{\nunderline[2]{light}{blue}}{cyan}%
\nunderline[3]{ing}{cyan}
\end{document}


-
This is really neat -- thank you for the links and answers! The command is beyond what I'm familiar with, so I'd like to follow up on it. Is the TeX manual the right place to learn to follow more than the outlines of the command definition? And is the reason I can successfully remove \relax and \def\stackalignment{l} that I'm in a LaTeX editor? – plt Apr 2 '14 at 23:04
@PamelaToman Once you edit code, I guess that makes you an editor. The stackalignment, either l, c, or r refers to the horizontal alignment of the stacked item [the rule] relative to the (in this case overlying) anchor [the word]. While I chose left, in this case it is irrelevant because the rule is the exact width of the overlying text to which it is set. In such a case, any alignment is indistinguishable from the other. The \relax is good habit when specifying lengths with an = sign, as it stops subsequent text from bein accidentally accounted as part of the length specified. – Steven B. Segletes Apr 3 '14 at 0:29
@PamelaToman While Knuth's TeX manual is great for advanced learning, Lamport's LaTeX manual is a great place to start out. As far learning the logic that I use here, you will find if you hang out on the site a bit, that I tend to use stackengine package a lot, having written it. So, the stackengine manual on ctan.org would clue you in on those matters, and any other packages of interest. – Steven B. Segletes Apr 3 '14 at 0:47

Here's a completely different approach that DOES allow line-wrapping, but not paragraph or page breaks. It is also forced to turn off hyphenation. It uses the censor package to create the underlining (by setting \censorruleheight and \censorruledepth), and it uses a \Longunderstack to stack the different threads at the proper spacing (based on result at Possible to wrap multiple rows within a column at one time?).

The first \thread is the unadulterated text, whereas subsequent threads in the stack (note the index on the first argument) use \whiteout and \blackout to denote text to be left alone and text to be underlined with the color associated with that thread. The downside is that the complete text must appear once for each thread in your input file, which can make for large inputs.

If too many threads cause lines to run together, \baselinemag may be increased from its current 1.2 setting. I've also set the thread width to 3in, which can be changed.

Note: \blackout and \whiteout cannot end its argument on a space.

\documentclass{article}
\usepackage[none]{hyphenat}
\usepackage{censor}
\censorruleheight=.7pt
\usepackage{xcolor}
\usepackage{stackengine}
\setstackgap{L}{0pt}
\newlength\ruleskip\newlength\rulebase
%%YOU CAN PLAY WITH THESE
\setlength\rulebase{-1.9ex}
\setlength\ruleskip{-.3ex}
\def\baselinemag{1.2}
%%%%%%%%%%
\def\stacktype{L}
\def\stackalignment{l}
\setlength\censorruledepth{\rulebase+#1\ruleskip}\color{#2}#3}}
\def\whiteout#1{\textcolor{white}{\blackout{#1}}}
\begin{document}
\raisebox{7pt}{\Longunderstack{%
\thread{0}{black}{The censor package allows a convenient redaction/censor capability to be
employed, for those who need to protect restricted information, as well as for those
who are forced to work in a more inefficient environment when dealing with
restricted information.
}\\
\whiteout{%
The censor package allows a convenient redaction/censor capability to be
employed, for those who need to protect}%
\blackout{ restricted information,}%
\whiteout{ as well as for those
who are forced to work in a more inefficient environment when dealing with
restricted information.}}\\
\whiteout{%
The censor package allows a convenient redaction/censor capability to be
employed, for those who need to protect restricted}%
\blackout{ information, as well as for those
who are forced}%
\whiteout{ to work in a more inefficient environment when dealing with
restricted information.}}\\
\whiteout{%
The censor package allows a convenient redaction/censor capability to be
employed, for those who need to pro}%
\blackout{tect restricted inform}%
\whiteout{ation, as well as for those
who are forced to work in a more inefficient environment when dealing with
restricted information.}}
}}
\end{document}


-
Blown away by your creativity and willingness to help. I really like this solution from a readability standpoint, but since it can't mark spaces/punctuation, I don't think I can use it.... \xblackout gets part of the way, but if I shrink \lletterlap/\rletterlap to the point that only the indicated characters are highlighted, then the spaces between words get (wrongly) excluded -- and if I leave them large enough to cover the spaces, then extra (wrong) characters are highlighted at the beginning and ending of the phrase. – plt Apr 2 '14 at 23:32
@PamelaToman, Yes, spaces are the weak point of censor. And, as you note, while \xblackout can help with the spaces, it makes the underlining less precise. Thanks for looking into the logic, which validates the effort. – Steven B. Segletes Apr 3 '14 at 0:42