在 \def 宏中使用括号不起作用

在 \def 宏中使用括号不起作用

我正在使用 TikZ 绘制一些图形(带有节点和有向边/路径)。我有两个节点和一个从一个节点指向另一个节点的箭头。我制作了一个名为的宏,\pathedge以便可以重复使用这些箭头,但它给我带来了一些麻烦。每当我在 \draw 命令上的任何节点前放置一个xshift或一个yshift选项时,它都会给我一个错误。我很确定这与在宏中使用括号“[' ']”有关,\def但我不知道如何修复它。这是最小的代码示例:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{tikz}

\def\conn{\draw[arrows=->, black!50, thick]}
\newcommand{\pathedge}[4]{
  \def\startn{#1}
  \def\endn{#2}
  \def\startnopts{}
  \def\endnopts{}

  \ifstrequal{#4}{NE_TO_SW} {
    \def\startn{[yshift=-1ex]#1.west} 
    \def\endn{[xshift=1ex]#2.north}
  } {}

  \conn (\startn) to node[shape=circle, fill=white, inner sep=0.5pt, font=\sffamily\footnotesize]{#3} (\endn);
}

\begin{document}
\begin{tikzpicture}[scale=1,innode/.style={draw, shape=circle,ultra thick,black}]
\node[innode] (1) at (2,2) {1};
\node[innode] (2) at (4,4) {2};

\pathedge{2}{1}{A}{NE_TO_SW}
\end{tikzpicture}
\end{document}

答案1

如果我理解正确的话(错误信息也表明了这一点),你想要一条来自 的路径([yshift=-1ex]#1.west) to ([xshift=1ex]#2.north)。错误信息如下:

! Package pgf Error: No shape named [yshift=-1ex]2 is known.
! Package pgf Error: No shape named [xshift=1ex]1 is known.

问题在于 TikZ 进行了扩展但为时已晚。TikZ 路径解析器需要查看一个[可以解决起始坐标的文字\expandafter(\startn),但这不适用于目标节点(因为 TikZ 只允许节点、坐标cycleplot之后--以及坐标)。

不过,你可以这样做

\newcommand{\pathedge}[4]{
  \def\startn{#1}
  \def\endn{#2}
  \def\startnopts{}
  \def\endnopts{}

  \ifstrequal{#4}{NE_TO_SW} {
    \def\startn{#1.west} 
    \def\endn{#2.north}
    \def\startnopts{yshift=-1ex}
    \def\endnopts{xshift=1ex}
  } {}
  \conn ([style/.expand once=\startnopts]\startn)
    to node[shape=circle, fill=white, inner sep=0.5pt, font=\sffamily\footnotesize]{#3}
      ([style/.expand once=\endnopts]\endn);
}

(为什么不直接使用.north east.south west锚点?)

但说实话,我会采取完全不同的方式来做这件事。

代码

\documentclass[tikz]{standalone}
\tikzset{
  conn/.style={arrows=->, black!50, thick,
    every to/.append style={edge node={
      node[shape=circle, fill=white, inner sep=0.5pt, font=\sffamily\footnotesize]{#1}}}},
  ne to sw/.style={
    to path={([yshift=-1ex]\tikztostart.west) --
             ([xshift=1ex]\tikztotarget.north)\tikztonodes}}}
\makeatletter
\tikzset{% from CVS version
  edge node/.code={\expandafter\def\expandafter\tikz@tonodes\expandafter{\tikz@tonodes #1}}}
\makeatother
\begin{document}
\begin{tikzpicture}[innode/.style={draw,shape=circle,ultra thick}]
\node[innode] (1) at (2,2) {1};
\node[innode] (2) at (4,4) {2};
\draw[conn=A] (2) to (1);
\end{tikzpicture}

\begin{tikzpicture}[innode/.style={draw,shape=circle,ultra thick}]
\node[innode] (1) at (2,2) {1};
\node[innode] (2) at (4,4) {2};
\draw[conn=A, ne to sw] (2) to (1);
\end{tikzpicture}
\end{document}

相关内容