# How to create an overhanging label for parts of a sentence?

Reference image attached. I also want to be able to change the colour of there arrows and label text, etc.

EDIT: A newer version with more functionality is here as an answer to a follow up question.

I have written a command \mylabel which takes the inline text as first mandatory argument and the label text as second mandatory argument. You can customize the appearance globally (for the current group) with \setmylabel or locally (for this one usage) with an optional argument.

\documentclass{article}
\usepackage{blindtext}

\usepackage{tikz}
\usetikzlibrary{positioning}

% --------------- def options ---------------

\pgfqkeys{/mylabel}{%
% geometry
shift x/.initial = 1.5em,
shift y/.initial = .2em,
slope width/.initial = .3em,
text xsep/.initial  = .1em,
text ysep/.initial  = .1em,
label xsep/.initial = .3333em,
label ysep/.initial = .3333em,
%
% colors
line color/.initial  = black,
text color/.initial  = black,
label color/.initial = black,
color/.style = {line color=#1, label color=#1},
%
% label positions
/mylabel/pos/.is choice,
/mylabel/pos/above/.style = {pos=above right},
/mylabel/pos/below/.style = {pos=below right},
/mylabel/pos/below right/.style = {%
_anchor label  = north west,
_direction     = below,
_line pos      = south,
},
/mylabel/pos/above right/.style = {%
_anchor label  = south west,
_direction     = above,
_line pos      = north,
},
%
% internal
_anchor label/.initial,
_direction/.initial,
_line pos/.initial,
%
% struts
inline strut/.initial=\vphantom{Ap},
label strut/.initial=\strut,
}

\newcommand{\setmylabel}[1]{%
\pgfqkeys{/mylabel}{#1}%
}

% --------------- init options ---------------

\setmylabel{%
pos = below,
}

% --------------- \mylabel command ---------------

\newcommand{\mylabel}[3][]{% [#1: options], #2: inline text, #3: label text
\begin{tikzpicture}[baseline=(inline.base)]
% process options
\setmylabel{#1}

% draw text
\node[%
inner ysep = \pgfkeysvalueof{/mylabel/text xsep},
inner xsep = \pgfkeysvalueof{/mylabel/text ysep},
text = \pgfkeysvalueof{/mylabel/text color},
] (inline) {\pgfkeysvalueof{/mylabel/inline strut}#2};
\node (label) [
\pgfkeysvalueof{/mylabel/_direction} = \pgfkeysvalueof{/mylabel/shift y} of inline,
xshift = \pgfkeysvalueof{/mylabel/shift x},
anchor = \pgfkeysvalueof{/mylabel/_anchor label},
inner xsep = \pgfkeysvalueof{/mylabel/label xsep},
inner ysep = \pgfkeysvalueof{/mylabel/label ysep},
text = \pgfkeysvalueof{/mylabel/label color},
] {\pgfkeysvalueof{/mylabel/label strut}#3};

% draw lines
\draw[draw=\pgfkeysvalueof{/mylabel/line color}]
(inline.\pgfkeysvalueof{/mylabel/_line pos} west) -- (inline.\pgfkeysvalueof{/mylabel/_line pos} east)
(inline.\pgfkeysvalueof{/mylabel/_line pos}) -- ([xshift=\pgfkeysvalueof{/mylabel/slope width}] inline.\pgfkeysvalueof{/mylabel/_line pos} |- label) -- (label);
;

% set bounding box
\pgfresetboundingbox
\useasboundingbox
(inline.south west) rectangle (inline.north east)
(inline |- label.south) rectangle (inline |- label.north)
;
\end{tikzpicture}%
}

% --------------- test document ---------------

\setmylabel{%
line color  = orange,
text color  = blue,
label color = green,
}

\begin{document}
\blindtext
text \mylabel[pos=above]{part}{label~1} of a \mylabel{sentence}{label~2}
\blindtext
\end{document}


I recommend to put def options, init options and \mylabel command in a separate file mylabel.tex in a subdirectory preamble and include it with \input{preamble/mylabel}.

EDIT: For even more customization you can add another pgfkey

line/.initial =,


and replace the first line of the code "draw lines" with

\pgfkeys{/mylabel/line/.get=\tmpLineStyle}%
\expandafter \draw \expandafter [\tmpLineStyle, draw=\pgfkeysvalueof{/mylabel/line color}]


then you have another option called line to which you can pass values like dotted, dashed, double, thick, thin, line width=2pt and so on (see TikZ documentation section 15.3 Drawing a Path). You can combine several values by joining them with a comma. If the value contains a comma or an equals sign it must be surrounded by braces.

For example:

line = {thick, dashed},


• Is it possible to modify your solution in a way that doesn't affect the space between lines? Obv in this case labels overlap with text but it's not a problem since I want to use it in drafts. If you want I can ask a separate question for this. – gvgramazio May 3 '18 at 10:03
• I added a separate question here – gvgramazio May 3 '18 at 10:26
• @giusva yes, that's easy. Just remove (inline |- label.south) rectangle (inline |- label.north) from \useasboundingbox. (Depending on the text ysep option it may still add a little space, though.) – jakun May 3 '18 at 18:19
• Thanks, can you please check my question. I've added just a small request: how to position the labels with a fixed offset wrt the page instead of a fixed offset wrt the part of the sentence one is referring to. – gvgramazio May 3 '18 at 18:42
• @giusva yes, I have read the question and I have started working on an update. I hope I can finish it tomorrow. – jakun May 3 '18 at 20:34