2

I would like to use pgfkeys to process expressions like

label={[scale=.8,pos=.9]above right:$-2\pi i$}

(which typically appear as labels in nodes), and extract from them three parameters according to the pattern [#1]#2:#3. I would also like to make #1 and #2 optional (again, as labels in nodes), so that things like #2:#3, [#1]#3 and #3 are valid patterns.

Update: I've been reading the tikz code that does this parsing, and have come up with code that works for many cases (it even allows for #3 being optional). The code is attached below (it is a working example, but is far from minimal: sorry!).

So what is it that doesn't work? Well, the options (argument #1). If I just specify a value (e.g. label={[blue]above:hola}), it works. But if I try to make it into a list (label={[blue,thick]above:hola}) or a key-value pair (label={[scale=.8]above:hola}), the code breaks (I get an error like I do not know the key /tikz/scale=.8). What do I have to modify to get that working?

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{arrows.meta,shapes.misc,decorations.pathmorphing,calc,bending}

\pgfdeclarelayer{top}
\pgfsetlayers{main,top}

\tikzset{
  branch point/.style={cross out,draw=black,fill=none,minimum size=2*(#1-\pgflinewidth),inner sep=0pt,outer sep=0pt}, 
  branch point/.default=5,
  branch cut/.style={
    decorate,decoration=snake
  }
}

\makeatletter
\catcode`\$=11\relax%
\gdef\parse@label[#1]#2:#3\empty{%
  % Extract options
  \if\relax\detokenize{#1}\relax
    \relax%
  \else
    \pgfkeyssetvalue{/branch cut jump/label/options}{#1}%
  \fi%
  % Do we have an angle?
  \if\relax\detokenize{#3}\relax
    % Nope!
    \if\relax\detokenize{#2}\relax
      % We also don't have a label text
      \relax%
    \else
      % But we do have a label text, so let's extract it
       \pgfkeyssetvalue{/branch cut jump/label/text}{#2}%
    \fi%
  \else
    % Yup!
    \parse@@label#2:#3\empty%
  \fi%
}
\gdef\parse@@label#1:#2:\empty{%
  % Do we have an angle?
  \if\relax\detokenize{#1}\relax
    \relax%
  \else
    \pgfkeyssetvalue{/branch cut jump/label/angle}{#1}%
  \fi%
  % Do we have a label text?
  \if\relax\detokenize{#2}\relax
    \relax%
  \else
    \pgfkeyssetvalue{/branch cut jump/label/text}{#2}%
  \fi%
}
\catcode`\$=3\relax%
\pgfkeys{/branch cut jump/.cd,
  pos/.initial = .8,
  amplitude/.initial = 10,
  color/.initial = green!60!black,
  label/.code    = {
    \@ifnextchar[%
      {\parse@label}%
      {\parse@label[]}#1:\empty%
    },
  label/options/.initial = green!60!black,
  label/angle/.initial   = above right,
  label/text/.initial    = $-2\pi i$
}
\tikzset{
  place arrow/.style={
    to path={
      (\tikztostart) -- (\tikztotarget) \tikztonodes
    },
    execute at begin to={
      \coordinate (A) at ($(\tikztostart)!\pgfkeysvalueof{/branch cut jump/pos}!-\pgfkeysvalueof{/branch cut jump/amplitude}:(\tikztotarget)$);
      \coordinate (B) at ($(\tikztostart)!\pgfkeysvalueof{/branch cut jump/pos}!\pgfkeysvalueof{/branch cut jump/amplitude}:(\tikztotarget)$);
      \coordinate (AB/3) at ($(A)!1/3!(B)$);
      \coordinate (2AB/3) at ($(A)!2/3!(B)$);
      \coordinate (C) at ($(AB/3)!2/(3*sqrt(3))!-90:(B)$);
      \coordinate (D) at ($(2AB/3)!4/(3*sqrt(3))!-90:(B)$);
      \begin{pgfonlayer}{top}
        \draw[thick,\pgfkeysvalueof{/branch cut jump/color},-{Stealth[]}] (A) .. controls (C) and (D) .. (B) node[\pgfkeysvalueof{/branch cut jump/label/options},\pgfkeysvalueof{/branch cut jump/label/angle}]{\pgfkeysvalueof{/branch cut jump/label/text}};
      \end{pgfonlayer}
    }
  },
  branch cut jump/.style={
    /branch cut jump/.cd,#1,
    /tikz/.cd,place arrow
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}[x=90pt,y=90pt]
\begin{scope}
  % Axes
  \draw[thin,gray,->] (-1,0) -- (1,0) node[right] {$x$};
  \draw[thin,gray,->] (0,-1) -- (0,1) node[above] {$y$};
  % Branch point
  \draw[thick] (0,0) node[branch point,draw=red,thick] {};
  % Branch cut
  \draw[thick,red,branch cut,branch cut jump] (0,0) to (0:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={hola}}] (0,0) to (30:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={:}}] (0,0) to (60:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={:adios}}] (0,0) to (90:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={left:}}] (0,0) to (120:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={below:$\times (-1)$}}] (0,0) to (150:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={[blue]hola}}] (0,0) to (180:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={[blue]:}}] (0,0) to (210:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={[blue]:adios}}] (0,0) to (240:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={[blue]left:}}] (0,0) to (270:1.2);
  \draw[thick,red,branch cut,branch cut jump={label={[blue]below:$\times (-1)$}}] (0,0) to (300:1.2);
\end{scope}
\end{tikzpicture}

\end{document}
14
  • You can just copy the label code.
    – percusse
    Nov 5, 2015 at 17:06
  • @percusse: I'm looking at the code right now. It does way more than just extract the three values I want. Also, I find it very difficult to understand. I don't think I have the knowledge to isolate what I need from the rest. Nov 5, 2015 at 17:10
  • You are currently overwriting TikZ's definitions of things. This seems like a Bad Idea. It would be better to use something like xabel={[scale=.8,pos=.9]above right:$-2\pi i$}. Apart from anything else, you can then pass it onto label if you actually want a label.
    – cfr
    Nov 7, 2015 at 2:31
  • @cfr: I don't think I'm overwriting TikZ definitions, am I? I have label inside /branch cut jump. Also, I do want something that acts as a label, but it is, in fact, a node: see the code inside the execute at begin to block. Nov 7, 2015 at 3:07
  • I guess if you're sure that \parse@label etc. are unique.
    – cfr
    Nov 7, 2015 at 3:36

1 Answer 1

2

Maybe this helps:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{arrows.meta,shapes.misc,decorations.pathmorphing,calc,bending}

\pgfdeclarelayer{top}
\pgfsetlayers{main,top}

\tikzset{
  branch point/.style={cross out,draw=black,fill=none,minimum size=2*(#1-\pgflinewidth),inner sep=0pt,outer sep=0pt},
  branch point/.default=5,
  branch cut/.style={
    decorate,decoration=snake
  }
}

\makeatletter
\catcode`\$=11\relax%
\gdef\parse@label[#1]#2:#3\empty{%
  % Extract options
  \if\relax\detokenize{#1}\relax
    \relax%
  \else
    \tikzset{/branch cut jump/label/options=#1}%
  \fi%
  % Do we have an angle?
  \if\relax\detokenize{#3}\relax
    % Nope!
    \if\relax\detokenize{#2}\relax
      % We also don't have a label text
      \relax%
    \else
      % But we do have a label text, so let's extract it
       \pgfkeyssetvalue{/branch cut jump/label/text}{#2}%
    \fi%
  \else
    % Yup!
    \parse@@label#2:#3\empty%
  \fi%
}
\gdef\parse@@label#1:#2:\empty{%
  % Do we have an angle?
  \if\relax\detokenize{#1}\relax
    \relax%
  \else
    \pgfkeyssetvalue{/branch cut jump/label/angle}{#1}%
  \fi%
  % Do we have a label text?
  \if\relax\detokenize{#2}\relax
    \relax%
  \else
    \pgfkeyssetvalue{/branch cut jump/label/text}{#2}%
  \fi%
}
\catcode`\$=3\relax%
\pgfkeys{/branch cut jump/.cd,
  pos/.initial = .8,
  amplitude/.initial = 10,
  color/.initial = green!60!black,
  label/.code    = {
    \@ifnextchar[%
      {\parse@label}%
      {\parse@label[]}#1:\empty%
    },
  label/options/.store in = \branch@label@options,
  label/options=green!60!black,
  label/angle/.initial   = above right,
  label/text/.initial    = $-2\pi i$
}
\tikzset{
  place arrow/.style={
    to path={
      (\tikztostart) -- (\tikztotarget) \tikztonodes
    },
    execute at begin to={
      \coordinate (A) at ($(\tikztostart)!\pgfkeysvalueof{/branch cut jump/pos}!-\pgfkeysvalueof{/branch cut jump/amplitude}:(\tikztotarget)$);
      \coordinate (B) at ($(\tikztostart)!\pgfkeysvalueof{/branch cut jump/pos}!\pgfkeysvalueof{/branch cut jump/amplitude}:(\tikztotarget)$);
      \coordinate (AB/3) at ($(A)!1/3!(B)$);
      \coordinate (2AB/3) at ($(A)!2/3!(B)$);
      \coordinate (C) at ($(AB/3)!2/(3*sqrt(3))!-90:(B)$);
      \coordinate (D) at ($(2AB/3)!4/(3*sqrt(3))!-90:(B)$);
      \begin{pgfonlayer}{top}
        \draw[thick,\pgfkeysvalueof{/branch cut jump/color},-{Stealth[]}] (A) .. controls (C) and (D) .. (B) node[\branch@label@options,\pgfkeysvalueof{/branch cut jump/label/angle}]{\pgfkeysvalueof{/branch cut jump/label/text}};
      \end{pgfonlayer}
    }
  },
  branch cut jump/.style={
    /branch cut jump/.cd,#1,
    /tikz/.cd,place arrow
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}
  \draw[thick,red,branch cut,branch cut jump={label={[blue,thick]above:hola}}] (0,0) to (30:1.2);
\end{tikzpicture}

\end{document}

node

3
  • Not that the thick makes a difference here since it is a node which is not drawn but it doesn't produce an error....
    – cfr
    Nov 7, 2015 at 4:06
  • Not exactly sure why, but these leaks styles up to the whole tikzpicture: change thick to scale=3 and the whole tikzpicture expands! Nov 7, 2015 at 7:37
  • Hmmm.... That's odd. I guess it is a good thing that the style suggestion worked ;).
    – cfr
    Nov 7, 2015 at 13:42

You must log in to answer this question.

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