将 \newcommand 更改为具有可选参数会中断命令

将 \newcommand 更改为具有可选参数会中断命令

简单地说,我在使用环境时为边缘定义了一个命令tikzpicture

命令:

\newcommand{\bendangleundiredgenodes}[6]{(#3) edge [-] [bend #2=#1] node [#5] {#6} (#4)}

用法:

\bendangleundiredgenodes{30}{left}{0}{1}{above}{Test}

这工作得很好。但是,如果我尝试将第一个参数设为可选,则会出现错误。

命令:

\newcommand{\bendangleundiredgenodes}[6][30]{(#3) edge [-] [bend #2=#1] node [#5] {#6} (#4)}

用法(均失败):

\bendangleundiredgenodes{left}{0}{1}{above}{Test}
\bendangleundiredgenodes[30]{left}{0}{1}{above}{Test}

错误(两种用法相同):

Package tikz Error: Giving up on this path. Did you forget a semicolon?. \bendangleundiredgenodes
Not defining \perthousand.
Not defining \micro.

完整示例用法:

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{shapes, backgrounds, arrows, automata, positioning, decorations.markings, calc}

\newcommand{\bendangleundiredgenodes}[6]{(#3) edge [-] [bend #2=#1] node [#5] {#6} (#4)}

\newenvironment{discretegraph}[2][\Large]{
    \begin{tikzpicture}[
        ->,
        >=stealth',
        auto,
        node distance=#2cm,
        thick,
        main node/.style={circle, draw, font=\sffamily#1\bfseries},
        nolooparrow/.style={-, every loop/.append style={-}},
        double arrows/.style args={##1, ##2, ##3}{
            decorate,
            decoration={
                markings,
                mark=at position 0 with {
                    \coordinate (ta-base-1) at (0,##3pt);
                    \coordinate (ta-base-2) at (0,-##3pt);
                },
                mark=at position 1 with {
                    \draw[##1] (ta-base-1) -- (0,##3pt); \draw[##2] (ta-base-2) -- (0,-##3pt);
                }
            }
        }, every node/.style={font=\sffamily\small}]]
}
{;\end{tikzpicture}}

\begin{document}
    
    \begin{discretegraph}[\normalsize]{3}
        \node[main node] (0) [] {};
        \node[main node] (1) [right of = 0] {};
        
        \path
        \bendangleundiredgenodes{30}{left}{0}{1}{above}{Test}
        
    \end{discretegraph}
    
\end{document}

答案1

正如其他人在评论中所讨论的那样,您不能在 Ti 中使用带有可选参数的宏Z 路径。但是,在我看来,使用这个宏实际上并没有多大用处:它并不比直接输入实际路径规范更短。

相反,你应该利用pgfkeys,这就是 TiZ 绘图需要有样式。这也适用于您的discretegraph环境。以下是我处理它的方法。

  • discretegraph用一个键来替换,我将其命名为discrete graph
  • 我选择保留节点字体作为选项,discrete graph并放弃node distance。如果您需要更改node distance,请明确进行。(无论如何,显式通常比隐式更好。)
  • 您可以使用discrete graph/.default它来设置默认字体大小,但只需输入\Large定义并允许使用参数覆盖它就更简单、更清晰了,所以我这样做了。
  • 为边缘创建另一个键。我将其命名为sabdul,显然您应该将其重命名为与它们所代表的内容相对应的名称。有多种方法可以使其可配置。我遵循了 Ti 中其他地方存在的样式sabdul'Z 并制作了第二把向另一个方向弯曲的钥匙。
  • 不要使用数字作为节点名称。虽然这是合法的,但它看起来像一个不完整的坐标,容易让人混淆。
\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{arrows}

\tikzset{
  discrete graph/.style={
    ->,
    >=stealth',
    auto,
    thick,
    main node/.style={circle, draw, font={\sffamily\bfseries\Large#1}},
    nolooparrow/.style={-, every loop/.append style={-}},
    double arrows/.style args={##1, ##2, ##3}{
      decorate,
      decoration={
        markings,
        mark=at position 0 with {
          \coordinate (ta-base-1) at (0,##3pt);
          \coordinate (ta-base-2) at (0,-##3pt);
        },
        mark=at position 1 with {
          \draw[##1] (ta-base-1) -- (0,##3pt); \draw[##2] (ta-base-2) -- (0,-##3pt);
        }
      }
    },
    every node/.style={font=\sffamily\small},
  },
  @sabdul/.style 2 args={
    -,
%    bend angle=30, % is the default anyway
    bend #2=#1,
  },
  @sabdul/.default=30,
  sabdul/.style={@sabdul={#1}{left}},
  sabdul'/.style={@sabdul={#1}{right}},
}

\begin{document}

\begin{tikzpicture} [
    discrete graph=\normalsize,
    node distance=3cm,
    ]
  \node [main node] (a) {foo};
  \node [main node] (b) [right of=a] {};
  \path (a) edge [sabdul] node [above] {test} (b);
  \path (a) edge [sabdul'=60] node [below] {another test} (b);
\end{tikzpicture}

\end{document}

MWE 输出


通常最好避免使用带有多个或可选参数的键,就像我在这里做的那样。如果你真的想这样做,你应该阅读这个问题. 使用我的答案,你可以定义类似

\tikzset{
  sabdul/.style with optarg with default value={left}{-, bend #1=#2},
}

不过,我建议采用前一种方法。

相关内容