\foreach
包中的命令有pgffor
一个很好的特性,它可以区分括号内的参数和不带括号的单个标记参数:
\foreach \i in {1,2,3} {do some thing}
\def\myvar{1,2,3}
\foreach \i in \myvar {do other thing}
我可以使用xparse
(无需手动定义辅助宏)来定义此类命令吗:
\NewDocumentCommand \MyCommand {???} {
If (#1 is inside braces) Then
Do Some Thing
Else
Do Other Thing
End
}
以便命令接受两种类型的参数并相应地执行不同的事情?
\MyCommand {1,2,3} % do some thing
\MyCommand \myvar % do other thing
答案1
不。在文档命令层面,Lamport 的书一直很明确:不{X}
参数“始终是 N 类型”。处理和之间的语义差异X
将归结为编程层接口或自定义解析器(例如TikZ 不使用标准 LaTeX 语法,因此无法使用ltcmd
) 来实现。
答案2
该tokcycle
包可以判断事物是否被吸收到支撑组中,并且可以根据该状态做“某事”或“其他事”。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tokcycle}
\Characterdirective{%
``Do other thing'' with ``#1''\tcpush{\noexpand\endtokcycraw}%
}
\Groupdirective{%
``Do some thing'' with ``#1''\tcpush{\noexpand\endtokcycraw}%
}
\Macrodirective{%
``Do other thing'' with ``\string#1''\tcpush{\noexpand\endtokcycraw}%
}
\stripgroupingtrue
\let\mycommand\tokencyclexpress
\begin{document}
\mycommand{ab cd}.
\mycommand A.
\mycommand\macroname.
\end{document}
ps 通常,调用 后无括号空格不会成为问题\mycommand
,因为它们不会成为参数的一部分。但是,如果有人担心参数是无括号隐式空格,\Spacedirective
也可以定义 来处理这个问题。
pps 此实现在标记流仍在被吸收时执行“某些”或“其他”操作。如果要求某些/其他操作仅在参数吸收结束时发生,那么这是一个微不足道的变化……如下所示:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tokcycle}
\Characterdirective{%
\addcytoks{``Do other thing'' with ``#1''}%
\tcpush{\noexpand\endtokcycraw}%
}
\Groupdirective{%
\addcytoks{``Do some thing'' with ``#1''}%
\tcpush{\noexpand\endtokcycraw}%
}
\Macrodirective{%
\addcytoks{``Do other thing'' with ``\string#1''}%
\tcpush{\noexpand\endtokcycraw}%
}
\stripgroupingtrue
\let\mycommand\tokencyclexpress
\begin{document}
\mycommand{ab cd}.
\mycommand A.
\mycommand\macroname.
\end{document}