Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is there an elegant way to draw red squigglies under text, to emulate what a [source] code editor does when it detects errors (either spelling mistakes, syntactical errors or semantic errors)?

enter image description here

Here is now the sguiggly looks in a very popular editor zoomed in. As you can see it's not actually a wave.

enter image description here

share|improve this question
    
I've added an extra screenshot to show how the sguiggly actually looks zoomed-in. I don't know if that's the normal look but that's how it looks in one of the most popular code editors. –  Bent Rasmussen Nov 4 '12 at 19:26
    
\tikz anyone? –  Peter Grill Nov 4 '12 at 19:36
1  
the twelfth edition of chicago (1979) specifies "Wavy underlining is used to indicate boldface type." red and other colors are recommended for indicating other alphabet styles, and the wavy underline for boldface is assumed to be black. obviously, adjustments are in order for screen usage; however, "wavy" traditionally means wavy. the more zig-zag appearance of the underlining in the screen shot appears to me to be taking an easy way out. –  barbara beeton Nov 4 '12 at 20:25
    
@barbarabeeton I don't know how appropriate the style is but in zoomed-in mode I find it looks better, subjectively speaking. Whether the developers choose this style to "cut corners" (excuse the pun) or not is an interesting question in and of itself. I don't have an answer for that. –  Bent Rasmussen Nov 4 '12 at 21:04
add comment

3 Answers

up vote 6 down vote accepted

Here's a variation using the soul package, tikz and the ubiquitous \tikzmark. The main command is \MarkText and uses a zigzag decoration; the syntax is:

\MarkText[<color>][<amplitude>][<segment length>]{<text>}

so the attributes for the decoration can be customized. The code:

\documentclass{article}
\usepackage{xparse}
\usepackage{marginnote}
\usepackage{soul}
\usepackage{lipsum}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathmorphing}

\newlength\LineWidth
\newlength\Amplitude
\newlength\SegLength

\setlength\LineWidth{0.4pt}
\setlength\Amplitude{1pt}
\setlength\SegLength{5pt}

\definecolor{HLcolor}{RGB}{240,0,0}

% The following code contains a variation of the great code by Antal S-Z
% in his answer to http://tex.stackexchange.com/a/6029/3954
%in TeX.SX

\newcommand\tikzmark[1]{%
  \tikz[overlay,remember picture] \node (#1) {};}

\makeatletter
\newcommand{\highlight@DoHighlight}{
  \draw[HLcolor,line width=\LineWidth,decorate,decoration={zigzag,amplitude=\Amplitude,segment length=\SegLength}]  ($(begin highlight)+(0,-2pt)$) -- ($(end highlight)+(0,-2pt)$) ;
}

\newcommand{\highlight@BeginHighlight}{
  \coordinate (begin highlight) at (0,0) ;
}

\newcommand{\highlight@EndHighlight}{
  \coordinate (end highlight) at (0,0) ;
}

\newdimen\highlight@previous
\newdimen\highlight@current

\DeclareRobustCommand*\highlight[1][]{%
  \SOUL@setup
  %
  \def\SOUL@preamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@BeginHighlight
      \highlight@EndHighlight
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@postamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@EndHighlight
      \highlight@DoHighlight
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@everyhyphen{%
    \discretionary{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
      \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everyexhyphen##1{%
    \SOUL@setkern\SOUL@hyphkern
    \hbox{##1}%
    \discretionary{%
      \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everysyllable{%
    \begin{tikzpicture}[overlay, remember picture]
      \path let \p0 = (begin highlight), \p1 = (0,0) in \pgfextra
        \global\highlight@previous=\y0
        \global\highlight@current =\y1
      \endpgfextra (0,0) ;
      \ifdim\highlight@current < \highlight@previous
        \highlight@DoHighlight
        \highlight@BeginHighlight
      \fi
    \end{tikzpicture}%
    \the\SOUL@syllable
    \tikz[overlay, remember picture] \highlight@EndHighlight ;%
  }%
  \SOUL@
}
\makeatother

\DeclareDocumentCommand\MarkText{O{red}O{1pt}O{5pt}m}{%
  \colorlet{HLcolor}{#1}
  \setlength\Amplitude{#2}%
  \setlength\SegLength{#3}%
  \tikzmark{endquote}\tikzmark{beginquote}\highlight{#4}%
}

\begin{document}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
mauris.\MarkText{Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.} Aenean
faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Cur-
abitur auctor semper nulla.\MarkText[olive][1pt][2pt]{Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim} rutrum.

Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi
auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ultricies et,
tellus. Donec aliquet, tortor sed accumsan bibendum, erat ligula aliquet magna,
vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse
ut massa. Cras nec ante. Pellentesque a nulla.\MarkText[cyan!60!black][2pt][15pt]{Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.} Aliquam tincidunt urna. Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus mauris.

\MarkText{Model}

\end{document}

The result:

enter image description here

A zoom to the last word:

enter image description here

The code needs two or three runs to stabilize. Unfortunately, \MarkText won't work well if a page break occurs inside the text to which it is applied.

share|improve this answer
    
Thanks. This is the best answer so far. The only thing missing is that the path-segment join style is different. The peaks are cut off. This makes the sguiggly look more smooth, if you will. –  Bent Rasmussen Nov 4 '12 at 20:07
add comment

The package ulem has a macro that does the job.

\usepackage[normalem]{ulem} % [normalem] to set \emph{} to default behaviour (italic instead of underlining)
...
\uwave{to be underlined in a squiggly way}

How to get a red (or any other coloured) line is explained at: How to color just the wave produced by the ulem package

Here’s what Yiannis Lazarides suggested:

\documentclass[11pt]{article} 
\usepackage{xcolor}
\usepackage{ulem}
\makeatletter
\def\uwave{\bgroup \markoverwith{\lower3.5\p@\hbox{\sixly \textcolor{red}{\char58}}}\ULon}
\font\sixly=lasy6 % does not re-load if already loaded, so no memory problem.
\makeatother
\begin{document}
  \uwave{This is a long test}
\end{document}
share|improve this answer
    
Thanks! I've added a zoomed-in screenshot to show the sguiggly in great detail. It's actually not quite a wave. –  Bent Rasmussen Nov 4 '12 at 19:36
    
@BentRasmussen After some googling I couldn’t find anything. I must admit, though, that I didn’t know what to search for, exactly. I guess it’s possible to have “jags” instead of the wave pattern but I wouldn’t know how (besides maybe using TikZ …) –  PattaFeuFeu Nov 4 '12 at 19:46
add comment
\documentclass{article}
\usepackage[normalem]{ulem}
\usepackage{xcolor}
\makeatletter
\def\squiggly{\bgroup \markoverwith{\textcolor{red}{\lower3.5\p@\hbox{\sixly \char58}}}\ULon}
\makeatother

\begin{document}

\squiggly{words}

\end{document}

enter image description here

share|improve this answer
1  
The wave looks misaligned with the test. It starts before the serif of the w, and ends before the right edge of the ascender of the d. –  Timtro Nov 4 '12 at 15:49
    
Thanks Harish! I've added a zoomed-in screenshot to show the sguiggly in great detail. It's actually not quite a wave. –  Bent Rasmussen Nov 4 '12 at 19:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.