如何检测 tikz \foreach 语句中的“空”元素

如何检测 tikz \foreach 语句中的“空”元素

我想定义一个宏,将其内容输入到 tikz\foreach语句中,例如:

\newcommand\Macro[1]{ \foreach \x in {#1} {x=\x.} }

然后将其用作\Macro{1,2,3,4}。有时,我想给它“空”参数,例如\Macro{,,,4,5,5}。我希望能够检测到“空”参数并在这种情况下执行不同的操作。我认为类似下面的操作会起作用:

\newcommand\Macro[1]{%
  \foreach \x in {#1} {
    \if\relax\detokenize{\x}\relax Empty!
    \else x=\x.
    \fi 
  }
}

但由于某种原因,这不能检测到空参数,而是产生:

在此处输入图片描述

我尝试了许多其他方法,例如\x先扩展,但我还没有找到任何有效的方法。

有人能找到这样做的方法吗?

[我的真实代码正在生成一个tikzpicture环境,所以我真的想\foreach从`tikz`中使用。]

答案1

像这样吗?

\documentclass{article}
\usepackage{tikz}
\newcommand\Macro[1]{%
  \foreach \x in {#1} {
    \ifx\x\empty\relax Empty!
    \else x=\x.
    \fi 
  }
}
\begin{document}
\Macro{,,,4,5,5}
\end{document}

在此处输入图片描述

答案2

这个问题在宏中源于问题:

\newcommand\Macro[1]{%
  \foreach \x in {#1} {
    \if\relax\detokenize{\x}\relax Empty!
    \else x=\x.
    \fi 
  }
}

\detokenize不展开其参数并返回两个标记\x。通过添加可以解决这个问题\expandafter

\detokenize\expandafter{\x}

完整宏:

\newcommand\Macro[1]{%
  \foreach \x in {#1} {
    \if\relax\detokenize\expandafter{\x}\relax Empty!
    \else x=\x.
    \fi 
  }
}

答案3

强制性expl3答案(注意到之后将\detokenize\expandafter{\x}是解决方案):

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\blankTF}{mmm}
 {% #1 = text to test, #2 = blank case, #3 = non blank case
  \str_if_eq_x:nnTF { #1 } { } { #2 } { #3 }
 }
\NewDocumentCommand{\lforeach}{O{,}mm}
 {% #1 = delimiter, #2 = list, #3 = code
  \seq_set_split:Nnn \l_andrew_foreach_seq { #1 } { #2 }
  \seq_map_inline:Nn \l_andrew_foreach_seq { #3 }
 }
\ExplSyntaxOff

\newcommand\Macro[1]{%
  \lforeach{#1}{%
    \blankTF{##1}{Empty!}{$|$##1$|$.}
  }
}

\begin{document}

\lforeach[-]{a-b--\texttt{c}}{%
    \blankTF{#1}{Empty!}{$|$#1$|$.}
  }

\lforeach{, ,,4, 5 ,5}{%
    \blankTF{#1}{Empty!}{$|$#1$|$.}
  }

\Macro{, ,,4, 5 ,5}

\end{document}

在此处输入图片描述

循环中的当前项用 表示(在 的定义中#1必须变成)。##1\Macro

相关内容