\expandafter, \expandbefor :还有什么?

\expandafter, \expandbefor :还有什么?

我有一个宏可以准确打印我想要的内容,但我无法将其嵌套在另一个宏中。据我所知,这是因为第一个宏没有完全执行,并且第一个宏的命令与第二个宏的命令混合在一起。

如何进行 ?

在此处输入图片描述

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.9}

\makeatletter
\def\L@ste#1#2{
    \count255 = 1
    \loop   
    \def\n{\the\count255}%
    #1%
    \advance\count255 by 1
    \ifnum\count255>#2
    \else
    ,%
    \repeat
    }
\def\Liste#1#2{\L@ste{#1}{#2}}
\makeatother

\begin{document}

\verb+\Liste{\n-\n/(6-\n)*x}{5}+

Prints exactly what I need :

\Liste{\n-\n/(6-\n)*x}{5}

\bigskip    

But I can't use it directly :

\verb+max(\Liste{\n-\n/(6-\n)*x}{5})+

produces errors ...

\bigskip    

\begin{tikzpicture}

\begin{axis}[xmin=0,xmax=5,ymax=7]
  \addplot[color=black,smooth,samples=400] 
  {
% can't use it here, Why ?
    %max(\Liste{\n-\n/(6-\n)*x}{5})
max(1-1/(6-1)*x,2-2/(6-2)*x,3-3/(6-3)*x,4-4/(6-4)*x,5-5/(6-5)*x)
  };
\end{axis}
\end{tikzpicture}
\end{document}

答案1

循环 via\loop不可扩展,因为它包含赋值。出于同样的原因\def\n{\the\count255 }(顺便说一句,请注意空格),它与推进计数器 via 一样不可扩展\advance

\Liste可以以可扩展的方式实现:

  • intcalc有助于以可扩展的方式增加,
  • \n需要通过可扩展的方式通过数字进行交换。

但构造一个包含扩展列表的宏(也是令牌寄存器)要容易得多。在下面的例子中,\Liste生成列表并将结果存储在宏中\ListeResult。后者可用于max

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.9}

\makeatletter
\newcommand*{\Liste}[2]{%
  \count@ = 1 %
  \let\ListeResult\@empty
  \loop
    \def\n{\the\count@}%
    \edef\ListeResult{\ListeResult#1}%
    \advance\count@ by 1 %
  \ifnum#2<\count@
  \else
    \edef\ListeResult{\ListeResult,}%
  \repeat
}
\makeatother

\begin{document}

Prints exactly what I need :

\Liste{\n-\n/(6-\n)*x}{5}
\ListeResult

\bigskip

\begin{tikzpicture}

\begin{axis}[xmin=0,xmax=5,ymax=7]
  \Liste{\n-\n/(6-\n)*x}{5}
  \addplot[color=black,smooth,samples=400] {max(\ListeResult)};
\end{axis}
\end{tikzpicture}
\end{document}

结果

答案2

您无法将其提供\Listemax,因为它需要语法正确的函数列表,而不是印刷他们。

这是一个可行的实现;您必须首先计算替换并定义一个宏来包含列表。然后您可以在的参数中使用此宏\max

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=newest}

\makeatletter
\newcommand\Liste[3][]{%
  \def\Liste@temp{\@gobble}%
  \count@=\z@
  \loop\ifnum\count@<#3\relax
  \advance\count@ by \@ne
  \begingroup\edef\n{\the\count@}%
  \edef\x{\endgroup\def\noexpand\Liste@temp{\Liste@temp,#2}}\x%
  \repeat
  \if\relax\detokenize{#1}\relax
    \Liste@temp
  \else
    \let#1=\Liste@temp
  \fi
}
\makeatother

\begin{document}

\Liste{\n-\n/(6-\n)*x}{5}

\bigskip    

\begin{tikzpicture}

\begin{axis}[xmin=0,xmax=5,ymax=7]
   \Liste[\foo]{\n-\n/(6-\n)*x}{5}
  \addplot[color=black,smooth,samples=400] 
  {
    max(\foo)
  };
\end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

采用 的新实现expl3

\documentclass{article}
\usepackage{geometry}
\usepackage{xparse}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=newest}

\ExplSyntaxOn
\NewDocumentCommand{\addplotlist}{smO{1}mmO{}}
 {% #1 = * if printing
  % #2 = function to apply to the list
  % #3 = starting point, default 1
  % #4 = end point
  % #5 = list building function
  % #6 = options for addplot
  \cs_set:Nn \__tarass_process:n { ,#5 }
  \clist_set:Nx \l__tarass_process_clist
   {
    \int_step_function:nnnN { #3 } { 1 } { #4 } \__tarass_process:n
   }
  \IfBooleanTF{#1}
   {
    $\use:c{#2}(\clist_use:Nn \l__tarass_process_clist { ,~ })$
   }
   {
    \addplot[#6]{ #2(\l__tarass_process_clist) }
   }
 }
\clist_new:N \l__tarass_process_clist
\ExplSyntaxOff

\begin{document}

\addplotlist*{max}{5}{#1-#1/(6-#1)*x}

\addplotlist*{min}{5}{#1+#1/(6-#1)*x}

\bigskip

\begin{tikzpicture}
\begin{axis}[xmin=0,xmax=5,ymax=7]
  \addplotlist{max}{5}{#1-#1/(6-#1)*x}[color=black,smooth,samples=400];
  \addplotlist{min}{5}{#1+#1/(6-#1)*x}[color=red,smooth,samples=400];
\end{axis}
\end{tikzpicture}
\end{document}

变量参数用 表示#1*版本打印获取的列表。

在此处输入图片描述

相关内容