foreach 中的 xstring 宏

foreach 中的 xstring 宏

我真的不明白这里的问题是什么,但我猜这与扩展和脆弱的宏有关,因为当我在外面做同样的事情时,它是有效的\path

代码:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{arrows,calc}
\usepackage{xstring}

\newcommand{\aw}{10pt}
\newcommand{\bbw}{20pt}
\newcommand{\cw}{30pt}

\newcommand{\width}[1]{%
  \StrBefore{#1}{'}[\notprimed]
  \IfEndWith{#1}{'}
  { \csname \notprimed w\endcsname }
  { \csname #1w\endcsname }
}

\begin{document}

\foreach \name in {a,bb,c,a'}
{ ++(\width{\name},0pt) node {\name} };

\begin{tikzpicture}
  % \draw (0pt,0pt) node {s}
  %   ++(\aw,0pt) node {a}
  %   ++(\bbw,0pt) node {bb}
  %   ++(\cw,0pt) node {c}
  %   ++(\aw,0pt) node {a'};

  \draw (0pt,0pt) node {s}
    \foreach \name in {a,bb,c,a'}
    { ++(\width{\name},0pt) node {\name} };
\end{tikzpicture}


\end{document}

我认为它与也有关,因为当我从它的定义中xstring删除\StrBefore和时,它也能起作用。\IfEndWith\width

有任何想法吗?

答案1

您需要将宏的使用移到xstring坐标之外,因为它们不是完全可扩展的,并且不会简单地导致\csname #1w\endcsname

使用\pgfextra{<stuff>}或者\pgfextra <stuff> \endpgfextra您可以执行<stuff>不属于路径的操作。

在我看来,你只是想去掉尾随的部分',所以你可以简单地这样做:

\makeatletter
\newcommand{\width}[1]{%
    \StrSubstitute{#1}{'}{}[\qrr@width]%
    \expandafter\let\expandafter\widthresult\csname\qrr@width w\endcsname}
\makeatother

并使用它

  \foreach \name in {a,bb,c,a'}{
    \pgfextra{\width{\name}}
    ++ (\widthresult,0pt) node {\name}
  }

以下解决方案删除第一个之后的所有内容',并且即使在坐标内也能工作(由于其简单性)。

参考

代码

\documentclass{article}
\usepackage{tikz}
\newcommand{\aw}{10pt}
\newcommand{\bbw}{20pt}
\newcommand{\cw}{30pt}
\makeatletter
\def\strip@upquote#1'#2\@strip@upquote{#1}
\newcommand{\width}[1]{\csname\expandafter\strip@upquote#1'\@strip@upquote w\endcsname}
\makeatother
\begin{document}
\begin{tikzpicture}
  \draw (0pt,0pt) node {s}
  \foreach \name in {a,bb,c,a'}{
    ++ (\width{\name},0pt) node {\name}
  };
\end{tikzpicture}
\end{document}

相关内容