收集计数器的命令值

收集计数器的命令值

我正在尝试将其收集到一个名为“调用 TikZ 的\drawtasks一系列\drawtask命令”的命令中。每次我调用时\wptask,该命令都应增加一个计数器,并将当前值计数器附加到\drawtasks对的调用中\drawtask。不幸的是,当我最终调用时\drawtasks,我总是得到最后一个计数器值。我已经尝试过此处类似问题中提出的解决方案(例如,这里,但它就是不起作用:似乎我的问题不同,因为我想附加对另一个不应扩展的命令的调用。以下是一个例子:

\documentclass{article}
\usepackage{tikz}

\newcommand{\drawtask}[4]{
    \node[anchor=west] at (-2,-0.5 * #1 - 0.25) {Task #2} ;
    \filldraw[fill=green!20,draw=green!50!black] (#3 / 3,-0.5 * #1 - 0.15) rectangle (#4 / 3,-0.5 * #1 - 0.35) ;

}
\newcounter{wptaskcounter}
\setcounter{wptaskcounter}{0}
\newcommand{\drawtasks}{}
\makeatletter
\newcommand{\appendwptask}[4]{%
    \protected@edef\@tempa{#1}%
    \expandafter\g@addto@macro\expandafter\drawtasks\expandafter{%
        \drawtask{\@tempa}{#2}{#3}{#4}%
    }%
}
\makeatother
\newcommand{\wptask}[3]{%
    \appendwptask{\thewptaskcounter}{#1}{#2}{#3}%
    \stepcounter{wptaskcounter}%
}

\wptask{1.1}{0}{3}
\wptask{1.2}{3}{6}
\wptask{1.3}{6}{9}

\begin{document}

\begin{tikzpicture}
    \drawtasks
\end{tikzpicture}

\end{document}

我对 LaTeX 的扩展规则感到很困惑,非常希望得到一些帮助!提前致谢。

答案1

根据 egreg 对您在问题中链接的答案的评论,您可以这样做。

我总是读到\expandafter<token 1><token 2>这样的意思<token 1>扩展后再返回并扩展<token 2>即,在紧接着的事物之后扩展下一个事物。

然而,这似乎意味着展开<token 2>下一步然后返回<token 1>即,在下一个事物之后扩展该事物。

在这种情况下,您希望TeX在查看 之后才\drawtasks考虑。因此您可以尝试\drawtask\@tempa

\expandafter\drawtask\expandafter{\@tempa ...

意思是只有在扩展之后才查看(只有在扩展之后才\drawtask查看)。\{\@tempa

……呃,我想是的。然而,我几乎肯定是错的。

尽管如此,

\newcommand{\appendwptask}[4]{%
    \protected@edef\@tempa{#1}%
    \expandafter\g@addto@macro\expandafter\drawtasks\expandafter{%
        \expandafter\drawtask\expandafter{\@tempa}{#2}{#3}{#4}%
    }%
}

我觉得这似乎有效。

累积任务

\documentclass{article}
\usepackage{tikz}

\newcommand{\drawtask}[4]{
    \node[anchor=west] at (-2,-0.5 * #1 - 0.25) {Task #2} ;
    \filldraw[fill=green!20,draw=green!50!black] (#3 / 3,-0.5 * #1 - 0.15) rectangle (#4 / 3,-0.5 * #1 - 0.35) ;

}
\newcounter{wptaskcounter}
\setcounter{wptaskcounter}{0}
\newcommand{\drawtasks}{}
\makeatletter
\newcommand{\appendwptask}[4]{%
    \protected@edef\@tempa{#1}%
    \expandafter\g@addto@macro\expandafter\drawtasks\expandafter{%
        \expandafter\drawtask\expandafter{\@tempa}{#2}{#3}{#4}%
    }%
}
\makeatother
\newcommand{\wptask}[3]{%
    \appendwptask{\thewptaskcounter}{#1}{#2}{#3}%
    \stepcounter{wptaskcounter}%
}

\wptask{1.1}{0}{3}
\wptask{1.2}{3}{6}
\wptask{1.3}{6}{9}

\begin{document}
\begin{tikzpicture}
    \drawtasks
\end{tikzpicture}
\end{document}

答案2

我不会这样做,而是\wptask生成一个逗号分隔的列表,然后\drawtasks使用循环遍历列表tikz/pgf\foreach命令。

通过这种方式,你的 MWE 会产生:

在此处输入图片描述

代码如下:

\documentclass{article}
\usepackage{tikz}

\let\wptasklist\relax% will become a comma separate list of the task parameters
\newcommand{\wptask}[3]{%  \addtask might be a better name:)
   \ifx\wptasklist\relax\def\wptasklist{#1/#2/#3}% first task
   \else\xdef\wptasklist{\wptasklist,#1/#2/#3}% add a task
   \fi%
}

\newcommand\drawtasks{% loop over \wptasklist and draw the tasks
  \begin{tikzpicture}
     \foreach \a/\b/\c [count=\n] in \wptasklist {% loop over task list
        \node[anchor=west] at (-2,-0.5 * \n - 0.25) {Task \a};
        \filldraw[fill=green!20,draw=green!50!black] 
                 (\b/3,-0.5*\n-0.15) rectangle (\c/3,-0.5*\n-0.35);
     }
  \end{tikzpicture}
}

\wptask{1.1}{0}{3}
\wptask{1.2}{3}{6}
\wptask{1.3}{6}{9}

\begin{document}

    \drawtasks

\end{document}

希望代码相当清晰易懂。请注意,除了使用\xdef添加到任务列表之外,没有扩展问题,并且不需要计数器,因为您可以将其用作循环[count=\n]的一部分\foreach来确定“任务编号”。

有一个警告,它似乎不适用于您的用例:任何包含\wptask斜杠的参数/都需要放在括号内{.../...}

编辑

这是第二个更接近 OP 的 MWE 的解决方案。它使用\eappto电子工具箱\appendwptask包,它是问题中宏的强大且通用的实现,以及\noexpand。至少对我来说,这提供了一种更直观的方式来应对这些扩展问题。输出与上面相同。

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}

\newcommand{\drawtask}[4]{
    \node[anchor=west] at (-2,-0.5 * #1 - 0.25) {Task #2} ;
    \filldraw[fill=green!20,draw=green!50!black] (#3 / 3,-0.5 * #1 - 0.15) rectangle (#4 / 3,-0.5 * #1 - 0.35) ;

}
\newcounter{wptaskcounter}% set to 0 by default
\newcommand{\drawtasks}{}
\newcommand{\wptask}[3]{%
    \eappto\drawtasks{\noexpand\drawtask{\thewptaskcounter}{#1}{#2}{#3}}% append to \drawtasks
    \stepcounter{wptaskcounter}%
}

\wptask{1.1}{0}{3}
\wptask{1.2}{3}{6}
\wptask{1.3}{6}{9}

\begin{document}
  \begin{tikzpicture}
    \drawtasks
  \end{tikzpicture}
\end{document}

如果你想“积累很多东西”,那么使用像这样的 key-val 系统鍵盤可能是更好的选择...嗯,除了最初的学习曲线:)

答案3

您可以使用\unexpanded

\documentclass{article}
\usepackage{tikz}

\providecommand{\expandonce}[1]{%
  \unexpanded\expandafter{#1}%
} % etoolbox already provides this

\newcommand{\drawtask}[4]{
  \node[anchor=west] at (-2,-0.5 * #1 - 0.25) {Task #2} ;
  \filldraw[fill=green!20,draw=green!50!black]
    (#3 / 3,-0.5 * #1 - 0.15) rectangle (#4 / 3,-0.5 * #1 - 0.35) ;
}
\newcounter{wptaskcounter}
\setcounter{wptaskcounter}{0}
\newcommand{\drawtasks}{}

\newcommand{\appendwptask}[4]{%
  \edef\drawtasks{%
    \expandonce{\drawtasks}%
    \expandonce{\drawtask{#1}{#2}{#3}{#4}}%
  }%
}
\newcommand{\wptask}[3]{%
  \expandafter\appendwptask\expandafter{\the\value{wptaskcounter}}{#1}{#2}{#3}%
  \stepcounter{wptaskcounter}%
}

\wptask{1.1}{0}{3}
\wptask{1.2}{3}{6}
\wptask{1.3}{6}{9}

\begin{document}

\begin{tikzpicture}
\drawtasks
\end{tikzpicture}

\end{document}

这样,\expandonce{\drawtasks}只会扩展一次\drawtasks,从而获取其先前的值;同样,\expandonce{\drawtask{...}{...}{...}{...}}将执行 的第一级扩展\drawtask,留下替换文本(将参数替换为参数)。您还需要扩展计数器的值。

在此处输入图片描述

expl3通过使用(通过xparse接口)可以获得更简洁的版本:

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

\newcommand{\drawtask}[4]{
  \node[anchor=west] at (-2,-0.5 * #1 - 0.25) {Task #2} ;
  \filldraw[fill=green!20,draw=green!50!black]
    (#3 / 3,-0.5 * #1 - 0.15) rectangle (#4 / 3,-0.5 * #1 - 0.35) ;
}

\ExplSyntaxOn
\tl_new:N \g_boris_drawtasks_tl
\int_new:N \g_boris_wptask_int

\NewDocumentCommand{\drawtasks}{}
 {
  \tl_use:N \g_boris_drawtasks_tl
 }

\NewDocumentCommand{\wptask}{mmm}
 {
  \boris_append_wptask:fnnn
    { \int_to_arabic:n { \g_boris_wptask_int } }
    { #1 }
    { #2 }
    { #3 }
  \int_gincr:N \g_boris_wptask_int
 }

\cs_new_protected:Nn \boris_append_wptask:nnnn
 {
  \tl_gput_right:No \g_boris_drawtasks_tl
   {
    \drawtask{#1}{#2}{#3}{#4}
   }
 }
\cs_generate_variant:Nn \boris_append_wptask:nnnn { f }
\ExplSyntaxOff

\wptask{1.1}{0}{3}
\wptask{1.2}{3}{6}
\wptask{1.3}{6}{9}

\begin{document}

\begin{tikzpicture}
\drawtasks
\end{tikzpicture}

\end{document}

f我们通过定义变量(完全扩展)来获取计数器值的扩展版本。

相关内容