使用 pgfkeys 处理复杂的标签类表达式

使用 pgfkeys 处理复杂的标签类表达式

我想用来pgfkeys处理类似

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

(通常作为节点中的标签出现),并根据模式从中提取三个参数[#1]#2:#3。我还想使#1和成为#2可选的(再次作为节点中的标签),以便像#2:#3[#1]#3和这样的内容#3成为有效的模式。

更新:我一直在阅读tikz执行此解析的代码,并想出了适用于许多情况的代码(它甚至允许#3可选)。代码附在下面(这是一个工作示例,但远非最简单:抱歉!)。

那么,到底是什么不起作用呢?嗯,是选项(参数#1)。如果我只指定一个值(例如label={[blue]above:hola}),它就可以正常工作。但如果我尝试将其变成列表(label={[blue,thick]above:hola})或键值对(label={[scale=.8]above:hola}),代码就会中断(我收到类似这样的错误I do not know the key /tikz/scale=.8)。我必须修改什么才能使其正常工作?

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

答案1

也许这有帮助:

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

节点

相关内容