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}
  • You can just copy the label code. – percusse Nov 5 '15 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. – Alberto Garcia-Raboso Nov 5 '15 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 '15 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. – Alberto Garcia-Raboso Nov 7 '15 at 3:07
  • I guess if you're sure that \parse@label etc. are unique. – cfr Nov 7 '15 at 3:36
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

  • 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 '15 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! – Alberto Garcia-Raboso Nov 7 '15 at 7:37
  • Hmmm.... That's odd. I guess it is a good thing that the style suggestion worked ;). – cfr Nov 7 '15 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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