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.

I have to highlight the grammatical categories in a sentence like this:

There is a beautiful flower in the garden.

Now, by either using balloons or arrows, I have to highlight which word belongs to which grammatical category (e.g. verb, noun, preposition, article ...).

I'm looking for a solution which is very simple and basic, as I have to use it for many more sentences in the presentation. I don't mind if it is very basic and clumsy. It is just to highlight and describe words in a sentence. The simplest and the easiest one will do for me.

Edit1: All the answers to this question have been very usefull for me. A small issue I experienced was if a sentence covers two lines then there should be balloon from the bottom side of the sentence. The answer by persusse has a solution. But, both of those (arrow and pointer) go out of margin if they are on the left side, and also if there is a bit long text inside.

share|improve this question
1  
In the TikZ/PGF manual p.453, there is a section on callout shapes library. Are those what you are looking for? –  percusse Dec 19 '11 at 18:04

3 Answers 3

up vote 21 down vote accepted

Enhanced Version:

Here is an enhanced version of the earlier solution. An optional argument is provided in order to be able to specify a vertical offset for the label. Below is what I consider the worst case scenario where each portion of the text is identified.

output of code

Notes:

  • Requires at least two runs to get proper placement.
  • The default values for yshift were chosen in the order that I created the macros, so perhaps better defaults can be chosen such that you can minimize the need to have to specify the vertical placement. Plus I wanted to make sure I tested the feature of being able to adjust the vertical placement.

Further Enhancements:

  • If the overlap is not acceptable, a way to improve this would be for \LabelText to check if the value of #4 and if it is negative place the box below the sentence. With this enhancement the cases where there are overlaps could be much further reduced, or even eliminated in most cases.
  • Perhaps incorporate \usetikzlibrary{shapes.callouts} to adjust the shapes to something other than a basic rectangle

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

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

\newcommand*{\LabelText}[4]{%
    \tikzmark{a}#1\tikzmark{b}%
    \begin{tikzpicture}[overlay,remember picture]
        \path (a.north) -- (b.north) node [yshift=#4, midway,rectangle,draw=#3,line width=1.5pt,rounded corners=2pt,inner sep=2pt,fill=-#3]  (label) {\textbf{\small #2}\strut};
        \draw [thick,-stealth,shorten >=5pt,#3] (label.south) -- ($(a.north)!0.5!(b.north)$);
    \end{tikzpicture}%
}

\newcommand*{\Noun}[2][6.0ex]{\LabelText{#2}{noun}{violet}{#1}}
\newcommand*{\Verb}[2][9.0ex]{\LabelText{#2}{verb}{green}{#1}}
\newcommand*{\Adjective}[2][12.0ex]{\LabelText{#2}{adjective}{blue}{#1}}
\newcommand*{\Pronoun}[2][15.0ex]{\LabelText{#2}{pronoun}{cyan}{#1}}
\newcommand*{\Preposition}[2][18.0ex]{\LabelText{#2}{preposition}{orange}{#1}}
\newcommand*{\Article}[2][21.0ex]{\LabelText{#2}{article}{red}{#1}}


\begin{document}
\Pronoun{There} \Verb[21.0ex]{is} \Article[7.0ex]{a} \Adjective[13.0ex]{beautiful} \Noun{flower} \Preposition{in} \Article[12.0ex]{the} \Noun{garden}.
\end{document}

Basic Version:

Here is a basic example of how you can use tikz to label parts of the text:

enter image description here

Notes:

  • Requires at least two runs to get proper placement

Further Enhancements:

  • This will have issues where every part of the text needs to be labelled as there will be overlaps. One way to adjust this would be to add an additional parameter that specifies the yshift.

Code:

\documentclass{article}
\usepackage{tikz}

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

\newcommand*{\LabelText}[3]{%
\tikzmark{a}#1\tikzmark{b}%
\begin{tikzpicture}[overlay,remember picture]
    \path (a.north) -- (b.north) node [yshift=3.0ex, midway,rectangle,draw=#3,rounded corners=2pt,inner sep=1pt,fill=-#3]  {#2\strut};
\end{tikzpicture}%
}

\newcommand*{\noun}[1]{\LabelText{#1}{noun}{red}}
\newcommand*{\adjective}[1]{\LabelText{#1}{adjective}{blue}}

\begin{document}
There is a \adjective{beautiful} \noun{flower} in the garden.
\end{document}
share|improve this answer

Here is another way. Please, be aware of the fact that there are a few subtle bugs that prevents the use of a few options in the shapes.callouts library and consider this as an esoteric option for now.


Update: The bug has been tracked down and patched by Daniel in his answer. Probably it will be included in the successor of version 2.10 of TikZ/PGF. Now one can directly put the pointers without using the inconvenient relative pointer key. One can even link this with our now-famous \tikzmark solutions (See Peter's answer and others for its wonders).


I have defined 4 alternatives which are far from optimal and in fact, pretty limited. But, again, this is just for demonstration (as usual underlining causes trouble).

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc,shapes.callouts,shapes.arrows}

\newcommand{\arrowthis}[2]{
        \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
        (#1) {\underline{#1}};
        \node[overlay,single arrow,draw=none,fill=red!50,anchor=tip,rotate=60] 
        at (#1.south) {#2};}%
    }%

\newcommand{\speechthis}[2]{
        \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
        (#1) {\underline{#1}};\node[overlay,ellipse callout,fill=blue!50] 
        at ($(#1.north)+(-.5cm,0.8cm)$) {#2};}%
    }%

\newcommand{\bubblethis}[2]{
        \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
        (#1) {\underline{#1}};\node[overlay,cloud callout,callout relative pointer={(0.2cm,-0.7cm)},%
        aspect=2.5,fill=yellow!90] at ($(#1.north)+(-0.5cm,1.6cm)$) {#2};}%
    }%

\newcommand{\pointthis}[2]{
        \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
        (#1) {\underline{#1}};\node[overlay,rectangle callout,%
        callout relative pointer={(0.2cm,0.7cm)},fill=green!50] at ($(#1.north)+(-.5cm,-1.4cm)$) {#2};}%
        }%
\begin{document}
\begin{frame}   
\arrowthis{There is}{Corot} a\speechthis{beautiful flower}%
{Van Gogh}\bubblethis{in}{Matisse}\pointthis{the garden}{Monet}.
\end{frame}
\end{document}

enter image description here

EDIT After the edit to the question, here is a simple pointthis with left and right definitions. I would strongly recommend you to play around with the positioning, the font and the colors to get your own version. These examples are only for the demonstration of the idea.

Replace the original \pointthis function with

\newcommand{\leftpointthis}[2]{
        \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
        (#1) {\underline{#1}};\node[overlay,rectangle callout,%
        callout relative pointer={(0.2cm,0.7cm)},fill=green!50] at ($(#1.north)+(-.5cm,-1.4cm)$) {#2};}%
        }%

\newcommand{\rightpointthis}[2]{
        \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
        (#1) {\underline{#1}};\node[overlay,rectangle callout,%
        callout relative pointer={(-0.3cm,0.7cm)},fill=green] at ($(#1.north)+(.5cm,-1.4cm)$) {#2};}%
        }%

Now you can try \rightpointthis{{There, is}}.

share|improve this answer
    
It fails to compile if there is a punctuation mark inside the flower brackets. Something like this: \arrowthis{There, is}{Corot} –  nixnotwin Dec 20 '11 at 13:18
    
@nixnotwin Ah, I should have noticed it. Just put an extra pair of braces as \arrowthis{{There, is}}{Corot} –  percusse Dec 20 '11 at 13:27
    
Yes it worked. Thanks. The arrow comes in from the left margin, can it be made to come in from the right margin? –  nixnotwin Dec 20 '11 at 14:19
    
@nixnotwin It can be done with adjusting the rotate option but then the text would be also rotated. I also don't know how to modify it quickly other than defining the arrow from scratch. –  percusse Dec 20 '11 at 15:01

In linguistics we would normally mark parts of speech with subscripts. This is relatively inconspicuous, but still noticeable, and it avoids the kinds of positioning problems that arise with fancier graphical methods. I've suggested three syntaxes for the commands, depending on your preference.

\documentclass{article}
\usepackage{fixltx2e}
\usepackage[svgnames]{xcolor}
\newcommand*\POS[1]{\textsubscript{\color{red}#1}} % tag with part of speech
\newcommand*\xPOS[2]{#1\POS{#2}} % or more semantically
\newcommand*\noun[1]{#1\POS{N}} % or if you only have a few categories
\begin{document}
\Huge
This\POS{Det} is some \xPOS{text}{N} in a \noun{sentence}.
\end{document}

output of code

share|improve this answer

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.