6

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

2

1 Answer 1

17
+50

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}.

enter image description here


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},

enter image description here

5
  • 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
    Commented May 3, 2018 at 10:03
  • I added a separate question here
    – gvgramazio
    Commented May 3, 2018 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
    Commented May 3, 2018 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
    Commented May 3, 2018 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
    Commented May 3, 2018 at 20:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .