我想使用\foo
带有可选参数的命令来执行并打印根据传递的数字迭代的计数器值。
因此,例如,\foo[5]
应该逐一踩下计数器 5 次。
(!)请注意,它与 不同\stepcounter{}{5}
。
平均能量损失
\documentclass{report}
\newcounter{mycount}
\setcounter{mycount}{0}
\newcommand{\foo}{\stepcounter{mycount}counter is \textbf{\themycount}}
\begin{document}
first use: \foo
second use: \foo
now using with option to iterate: \foo[2]
\medskip
\textit{desired output from line above should be:}
\medskip
now using with option to iterate: counter is \textbf{3,4}
\end{document}
答案1
expl3
只需几行即可。
\documentclass{report}
\usepackage{xparse}
\newcounter{mycount}
\setcounter{mycount}{0}
\ExplSyntaxOn
\NewDocumentCommand{\foo}{O{1}}
{
\int_compare:nT { #1 > 0 }
{
\int_compare:nTF { #1 = 1 } {counter~is} {counters~are}~
\stepcounter{mycount}
\textbf{\themycount}
\prg_replicate:nn { #1 - 1 } {,\stepcounter{mycount}\textbf{\themycount}}
}
}
\ExplSyntaxOff
\begin{document}
first use: \foo
second use: \foo
now using with option to iterate: \foo[2]
now using with option to iterate: counters are \textbf{3,4}
\foo[5]
\end{document}
诀窍是进行第一次迭代,然后再次继续,先添加逗号。
如果传递的数字为零或更小,则什么也不会发生。
答案2
multido
以下是包含、xparse
和 的短代码etoolbox
:
\documentclass{report}
\usepackage{multido}
\usepackage{xparse, etoolbox}
\newcounter{mycount}
\setcounter{mycount}{0}
\NewDocumentCommand{\foo}{O{1}}{counter is \multido{\i=1+1}{#1}{\stepcounter{mycount}\textbf{\themycount}\ifnumless{\multidocount}{#1}{,\,}{.}}}
\begin{document}
first use: \foo
second use: \foo
now using with option to iterate: \foo[5]
\end{document}
答案3
这是一种使用的方法multido
for 循环和延迟分隔符定义:
\documentclass{article}
\usepackage{multido}
\newcounter{mycount}
\newcommand{\foo}[1][1]{%
counter%
\ifnum#1>1\relax s are\else \space is\fi
\space
% https://tex.stackexchange.com/a/89187/5764
\def\itemdelim{\unskip\space\def\itemdelim{,\space}}% Item delimiter delayed by one cycle
{\bfseries\multido{\i=1+1}{#1}{\itemdelim \stepcounter{mycount}\themycount}}%
}
\begin{document}
first use: \foo
second use: \foo
now using with option to iterate: \foo[2]
\medskip
\textit{desired output from line above should be:}
\medskip
now using with option to iterate: counters are \textbf{3, 4}
\end{document}
答案4
更多一些代码,但没有额外的软件包:
\documentclass{report}
\newcounter{mycount}
\setcounter{mycount}{0}
\newcommand\Exchange[2]{#2#1}%
\newcommand{\foo}[1][1]{\fooloop{#1}{}{counter value is}}
\makeatletter
\newcommand{\fooloop}[3]{%
\ifnum#1>0 \stepcounter{mycount}\fi
\ifnum#1>1 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\begingroup
\protected@edef\@tempa{\themycount}%
\c@mycount=#1\relax
\advance\c@mycount by -1\relax
\expandafter\endgroup
\expandafter\fooloop\expandafter
{\number\expandafter\c@mycount\expandafter}\expandafter
{\romannumeral0\expandafter\Exchange\expandafter{\@tempa}{ #2}, }%
{counter values are}%
}{%
#3 \textbf{#2\themycount}%
}%
}%
\makeatother
\begin{document}
first use: \foo
second use: \foo
now using with option to iterate: \foo[4]
\medskip
\textit{desired output from line above should be:}
\medskip
now using with option to iterate: counter values are \textbf{3, 4, 5, 6}
\medskip
now using with option to iterate 0 times---counter is unchanged and displayed: \foo[0]
\medskip
now using with option to iterate -1 times---counter is unchanged and displayed: \foo[-1]
\end{document}