我使用 ConcProg 课程为学生的独奏会制作音乐会节目单。所播放的歌曲有很多重复,所以我想创建一个速记程序。
因此,与其这样
\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
\end{composition}
像这样。
\newcommand{\twinkle}{{Folk Song}{}{Twinkle Twinkle Little Star}}
\newcommand{\studentname}{{Student Name}}
\begin{composition}\twinkle\studentname
\end{composition}
但是,\newcommand 似乎只喜欢在特定新命令的参数中使用多组括号。据我所知,它会忽略独立括号{即与特定 \newcommand 的参数或 \newcommand 内的命令无关的括号}。在此自定义环境的实例中,它会抛出错误。
下面是另一个示例(不使用自定义环境)。
%standard input
\newcommand{\wbalTwo}[2] {
This is the Wikibook about LaTeX
supported by #1 and #2}
\item \wbalTwo{John Doe}{Anthea Smith}
%trying to use new command to input args. In this instance, it seems to ignore the internal braces and treats both internally-braced items as a single text string.
\newcommand{\wbalTwo}[2] {
This is the Wikibook about LaTeX
supported by #1 and #2}
\newcommand{\passargs}
那么有没有简单的方法可以让它们具有相同的输出?
答案1
从您目前告诉我们的情况来看,我们无法重现该问题,因此追踪/追踪问题的根源在某种程度上需要靠猜测。
首先是一些一般性的评论——我希望我的猜测是正确的,并且我的评论是有用的:
- 在从标记流中收集宏或环境的参数时,扩展是不是被啟動。
- 如果存在,(La)TeX 将删除包围全部的在扩展期间将该参数插入到替换文本中的参数。
在 CTAN 上“挖出” ConcProg 级之后(https://ctan.org/pkg/concprog),我发现环境composition
处理四个参数:
- ⟨作者⟩
- ⟨出生(和死亡)年份⟩
- ⟨作品标题⟩
- ⟨可选描述⟩
因此
\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
⟨whatsoever environment-body⟩
\end{composition}
- -environment的第一个参数
composition
将是:Folk Song
, - -environment的第二个参数
composition
将为空, - -environment的第三个参数
composition
将是:Twinkle Twinkle Little Star
, - -environment的第四个参数
composition
将是:Student Name
,
同时
\begin{composition}\twinkle\studentname
\end{composition}
- -environment的第一个参数
composition
将是:\twinkle
, - 环境的第二个参数
composition
是\studentname
, - -environment的第三个参数
composition
将是:\end
, - -environment的第四个参数
composition
将是:composition
。
这是因为扩展不是当 LaTeX 收集宏或环境的参数时触发。
根据 LaTeX 执行/扩展环境所依据的宏时参数的插入方式composition
,这种获取参数的方式可能会导致各种奇怪/错误/有问题的行为。
我可以提供一个定制的composition
环境变体,称为mycomposition
,它负责扩展:
实际上,环境根本不处理任何参数。相反,它会检查其环境主体中的下一个标记是否可扩展。如果是,则会进行扩展,直到找到不可扩展的标记。(请注意,花括号{
不是可扩展的标记。;-))然后它会抓取一个参数。它执行此操作四次以抓取 4 个参数。然后它在内部将这四个参数传递给环境底层的宏composition
:
\documentclass{ConcProg}
\makeatletter
\newcommand\UD@CheckWhetherNextExpandable[2]{%
\def\UD@reserved@a{#1}%
\def\UD@reserved@b{#2}%
\UD@@CheckWhetherNextExpandable
}%
\newcommand\UD@@CheckWhetherNextExpandable{%
\futurelet\UD@reserved@c\UD@@@CheckWhetherNextExpandable
}%
\newcommand\UD@@@CheckWhetherNextExpandable{%
\ifx\UD@reserved@c\@sptoken\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\afterassignment\UD@@CheckWhetherNextExpandable\let\UD@reserved@c= }%
{%
\expandafter\ifx\noexpand\UD@reserved@c\UD@reserved@c
\expandafter\UD@reserved@b
\else
\expandafter\UD@reserved@a
\fi
}%
}%
\newcommand\UD@ExpandUntilFirstUnexpandableAndAddToUD@reserved@d[1]{%
\ifx\relax#1\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\expandafter\endgroup\UD@reserved@d}%
{\UD@CheckWhetherNextExpandable
{\expandafter\UD@@CheckWhetherNextExpandable}%
{\expandafter\UD@AddNextTo\expandafter{\@gobble#1}\UD@reserved@d}%
}%
}%
\newcommand\UD@AddNextTo[3]{%
% \edef..\the\toks@-route prevents halving of hashes.
\toks@\expandafter{#2{#3}}%
\edef#2{\the\toks@}%
\UD@ExpandUntilFirstUnexpandableAndAddToUD@reserved@d{#1}%
}%
\newcommand\UD@ExpandAndAccumulateKArgsAndPassTo[2]{%
\begingroup
\def\UD@reserved@d{#2}%
\expandafter\UD@ExpandUntilFirstUnexpandableAndAddToUD@reserved@d
\expandafter{\romannumeral\number\number#1 000}%
}%
\newenvironment{mycomposition}%
{\UD@ExpandAndAccumulateKArgsAndPassTo{4}{\composition}}%
{\endcomposition}%
\makeatother
\newcommand{\twinkle}{{Folk Song}{}{Twinkle Twinkle Little Star}}
\newcommand{\studentname}{{Student Name}}
\begin{document}
\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}%
environment body
\end{composition}
\begin{mycomposition} \twinkle\studentname
environment body
\end{mycomposition}
\begin{mycomposition} \twinkle {Student Name}
environment body
\end{mycomposition}
\begin{mycomposition} {Folk Song}{}{Twinkle Twinkle Little Star} \studentname
environment body
\end{mycomposition}
\begin{mycomposition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
environment body
\end{mycomposition}
\end{document}