如何从宏参数中删除前导和尾随空格?

如何从宏参数中删除前导和尾随空格?

考虑这个最小的工作示例:

\documentclass[a4paper]{amsart}

\usepackage{tikz}

\tikzset{graph/.style = {every node/.style = { draw,
                                               shape = circle,
                                               fill = black,
                                               minimum size = 0.8mm,
                                               inner sep = 0mm,
                                               label distance = 0.8mm
                                               }}}

\newcommand{\circumferencenode}[4][]{\node (#1#2) at (#4: #3) [label = #4: $#2$] {};}

\newlength{\gr} % graph radius
\setlength{\gr}{15mm}

\begin{document}
    \begin{tikzpicture}[graph]
        \circumferencenode{0}{\gr}{ 90}
        \circumferencenode{1}{\gr}{ 30}
        \circumferencenode{2}{\gr}{330}
        \circumferencenode{3}{\gr}{270}
        \circumferencenode{4}{\gr}{210}
        \circumferencenode{5}{\gr}{150}
        \draw (0) -- (1) -- (2) -- (3) -- (4) -- (5) -- (0);
    \end{tikzpicture}

    \vspace*{10mm}

    \begin{tikzpicture}[graph]
        \circumferencenode{02}{\gr}{ 90}
        \circumferencenode{ 3}{\gr}{  0}
        \circumferencenode{ 4}{\gr}{270}
        \circumferencenode{15}{\gr}{180}
        \draw (02) -- (3) -- (4) -- (15) -- (02);
    \end{tikzpicture}
\end{document}

输出结果如下:

如您所见,第二个示例看起来很奇怪。节点的放置出了问题。我本想问为什么会发生这种情况,但一些实验表明,如果将第二张图片更改为以下内容:

\begin{tikzpicture}[graph]
    \circumferencenode{02}{\gr}{90}
    \circumferencenode{3}{\gr}{0}
    \circumferencenode{4}{\gr}{270}
    \circumferencenode{15}{\gr}{180}
    \draw (02) -- (3) -- (4) -- (15) -- (02);
\end{tikzpicture}

或者甚至是这样的:

\begin{tikzpicture}[graph]
    \circumferencenode{02}{\gr} {90}
    \circumferencenode {3}{\gr}  {0}
    \circumferencenode {4}{\gr}{270}
    \circumferencenode{15}{\gr}{180}
    \draw (02) -- (3) -- (4) -- (15) -- (02);
\end{tikzpicture}

那么问题就消失了,第二张图表就如人们预期的那样出现了。

因此问题显然是宏参数中的前导空格。我可以去掉它们,这样就没问题了。但是,我很高兴按照\circumferencenode我原来的方式安排对宏的调用,这样数字和括号组就可以垂直对齐。因此,更好的解决方案是找出如何从宏参数中删除前导和尾随空格。

  • 为何原来的例子不能正常工作?
  • 如何从我定义的宏的参数中删除前导和尾随空格?

答案1

使用内核宏修剪空格可能很困难;这时 LaTeX3 可以提供帮助:

\documentclass[a4paper]{amsart}

\usepackage{tikz,xparse}

\tikzset{graph/.style = {every node/.style = { draw,
                                               shape = circle,
                                               fill = black,
                                               minimum size = 0.8mm,
                                               inner sep = 0mm,
                                               label distance = 0.8mm
                                               }}}

%%% We need a "classical" definition, because of the colons in the replacement text
\newcommand{\circumferencenodeinner}[4]{\node (#1#2) at (#4: #3) [label = #4: $#2$] {};}
%%% Now we go with LaTeX3
\ExplSyntaxOn
\NewDocumentCommand{\circumferencenode}{ O{} m m m }
 {
  \hammerite_circumference_node:nxnx
   { #1 }
   { \tl_trim_spaces:n { #2 } }
   { #3 }
   { \tl_trim_spaces:n { #4 } }
 }
\cs_set_eq:NN \hammerite_circumference_node:nnnn \circumferencenodeinner
\cs_generate_variant:Nn \hammerite_circumference_node:nnnn { nxnx }
\ExplSyntaxOff

\newlength{\gr} % graph radius
\setlength{\gr}{15mm}

\begin{document}

\noindent\begin{minipage}{.4\textwidth}
%%% Just to give an example we use the old definition
\newcommand{\circumferencenodeold}[4][]{\node (#1#2) at (#4: #3) [label = #4: $#2$] {};}

\textbf{Old}

    \begin{tikzpicture}[graph]
        \circumferencenodeold{0}{\gr}{ 90}
        \circumferencenodeold{1}{\gr}{ 30}
        \circumferencenodeold{2}{\gr}{330}
        \circumferencenodeold{3}{\gr}{270}
        \circumferencenodeold{4}{\gr}{210}
        \circumferencenodeold{5}{\gr}{150}
        \draw (0) -- (1) -- (2) -- (3) -- (4) -- (5) -- (0);
    \end{tikzpicture}

    \vspace*{10mm}

    \begin{tikzpicture}[graph]
        \circumferencenodeold{02}{\gr}{ 90}
        \circumferencenodeold{ 3}{\gr}{  0}
        \circumferencenodeold{ 4}{\gr}{270}
        \circumferencenodeold{15}{\gr}{180}
        \draw (02) -- (3) -- (4) -- (15) -- (02);
    \end{tikzpicture}
\end{minipage}\vrule\qquad
\noindent\begin{minipage}{.4\textwidth}
\textbf{New}

    \begin{tikzpicture}[graph]
        \circumferencenode{0}{\gr}{ 90}
        \circumferencenode{1}{\gr}{ 30}
        \circumferencenode{2}{\gr}{330}
        \circumferencenode{3}{\gr}{270}
        \circumferencenode{4}{\gr}{210}
        \circumferencenode{5}{\gr}{150}
        \draw (0) -- (1) -- (2) -- (3) -- (4) -- (5) -- (0);
    \end{tikzpicture}

    \vspace*{10mm}

    \begin{tikzpicture}[graph]
        \circumferencenode{02}{\gr}{ 90}
        \circumferencenode{ 3}{\gr}{  0}
        \circumferencenode{ 4}{\gr}{270}
        \circumferencenode{15}{\gr}{180}
        \draw (02) -- (3) -- (4) -- (15) -- (02);
    \end{tikzpicture}
\end{minipage}
\end{document}

由于替换文本中有冒号,因此该命令\circumferencenodeinner以标准方式定义;请注意指定了可选参数;它只是一个辅助宏,将转换为\let具有 LaTeX3 名称的宏,以便nxnx可以创建带后缀的变体;这x意味着相应的参数已完全展开。实际上,当我们最终调用它时,参数#2#4被传递给\tl_trim_spaces:n它,它的工作正是修剪前导和尾随空格,然后按原样传递其余部分。

在此处输入图片描述

答案2

正如 Peter Grill 所说,命令定义的节点名称\circumferencenode与绘制图形时使用的节点名称之间存在冲突。那么第一个问题的答案是,您正在定义节点" 3"(注意前导空格)并使用(3)没有前导空格的节点。

这是应与提供的定义一起使用的绘制命令:

 \draw (02) -- ({ 3}) -- ({ 4}) -- (15) -- (02);

我不知道第二个问题的简单答案:(。

相关内容