如何命名命令参数

如何命名命令参数

有没有办法给命令的参数赋予一个“名称”并在其定义中使用它们?我想要做的是能够使用“标签”而不是来获取参数的值#myargname#<number>例如,我想定义\foocommand一个

\newcommand{\foocommand}[#normal,#bold,#italics,#smallcaps,#emphasis]%
           {#normal \textbf{#bold} \textit{#italics} \textsc{#smallcaps} \emph{#emphasis}}

代替

\newcommand{\foocommand}[5]%
           {#1 \textbf{#2} \textit{#3} \textsc{#4} \emph{#5}}

答案1

你可以。这是一个概念证明。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\newparametercommand}{smO{}m}
 {
  \IfBooleanTF { #1 }
   {
    \ntakwetet_newparametercommand:Nnnn \cs_set_nopar:cV { #2 } { #3 } { #4 }
   }
   {
    \ntakwetet_newparametercommand:Nnnn \cs_set:cV { #2 } { #3 } { #4 }
   }
 }

\tl_new:N \l__ntakwetet_replacement_tl
\int_new:N \l__ntakwetet_index_int
\cs_generate_variant:Nn \cs_set:Nn { cV }
\cs_generate_variant:Nn \cs_set_nopar:Nn { cV }

\cs_new_protected:Nn \ntakwetet_newparametercommand:Nnnn
 {
  \tl_set:Nn \l__ntakwetet_replacement_tl { #4 }
  % double the #
  \regex_replace_all:nnN { \cP. } { \cP\#\cP\# } \l__ntakwetet_replacement_tl
  % index for the parameters
  \int_zero:N \l__ntakwetet_index_int
  % substitute any item in the list of parameters with #<n>
  \clist_map_inline:nn { #3 }
   {
    \int_incr:N \l__ntakwetet_index_int
    \exp_args:Nne \regex_replace_all:nnN
     { ##1 } % search
     { \exp_not:n { \cP\# } \int_eval:n { \l__ntakwetet_index_int } } % replace
     \l__ntakwetet_replacement_tl
   }
  % define a temporary macro with #1=\cs_set:cV or \cs_set_nopar:cV
  #1 {__ntakwetet_temp:\prg_replicate:nn { \l__ntakwetet_index_int } { n } } % name
   \l__ntakwetet_replacement_tl % replacement
  \cs_new_eq:Nc #2 {__ntakwetet_temp:\prg_replicate:nn { \l__ntakwetet_index_int } { n } }
 }

\ExplSyntaxOff

\newparametercommand\foo[#abc,#def]{#abc,#def}

\newparametercommand*\baz[#abc,#def]{#abc--#def}

\newparametercommand{\foocommand}[#normal,#bold,#italics,#smallcaps,#emphasis]{%
  #normal \textbf{#bold} \textit{#italics} \textsc{#smallcaps} \emph{#emphasis}%
}

\begin{document}

\foo{a}{b}

\baz{a}{b}

\foocommand{normal}{bold}{italics}{smallcaps}{emphasis}

\end{document}

在替换文本中搜索逗号分隔列表中的每个项目,并将其替换#<n>为当前索引。

限制:关键字不能以另一个关键字作为起始段。因此#a#aa不起作用。当然,也不能使用超过 9 个参数。

在此处输入图片描述

答案2

虽然不是自动的,但简单且容易。

\documentclass{article}

\newcommand{\foo}[2]% #1=\first, #2=\second
{\bgroup% make definitions local
  \def\first{#1}%
  \def\second{#2}%
  Arguments are \first{} and \second.
\egroup}

\begin{document}
\foo{A}{B}
\end{document}

可替代,但容易出错。

\documentclass{article}

\newcommand{\foo}[1]% #1 = TeX definitions
{\bgroup% make definitions local
  #1
  Arguments are \first{} and \second.
\egroup}

\begin{document}
\foo{\def\first{A}\def\second{B}}
\end{document}

答案3

经过编辑以消除先前方法的缺陷。

如果您不介意按照下列方式更改语法:

  1. 将符号参数标识符从 更改#为非 cat 6 的内容,此处完成!

  2. 用 定义新命令\symbolicnewcommand,因为\newcommand已经用不同的语法定义。

因此,语法如下:

\symbolicnewcommand{\foocommand}%
  [!normal,!bold,!italics,!smallcaps,!emphasis,!boxed]%
  {!normal{} \textbf{!bold} \textit{!italics} 
   \textsc{!smallcaps} \emph{!emphasis} \fbox{!boxed}}

与我之前的方法不同,这种方法不仅仅是模仿\newcommand行为,而且通过将符号参数转换为显式的 、 等来重新创建它#1#2不是放置在 a 内\def)。

这是 MWE。请注意,在\meaning定义的宏的中,符号参数(例如)!normal被转换为显式的#1

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{listofitems,tokcycle}
\newtoks\mytoks
\newtoks\tmptoks
\def\OPENSgroup{\OPENSgroup}% quark
\def\CLOSEgroup{\CLOSEgroup}% quark
\def\SPACEquark{\SPACEquark}% quark

\newcommand{\addtotoks}[2]{#1\expandafter{\the#1#2}}
\newcommand{\xaddtotoks}[2]{%
  \expandafter\addtotoks\expandafter#1\expandafter{#2}}

\makeatletter
\long\def\symbolicnewcommand#1[#2]#3{%
  \readlist*\arglist{#2}%
  \stripgroupingtrue%
  \tokcycle{\addcytoks{##1}}%
    {\addcytoks{\OPENSgroup}\processtoks{##1}\addcytoks{\CLOSEgroup}}%
    {\addcytoks{##1}}{\addcytoks{\SPACEquark}}{#3}%
  \mytoks\expandafter{\the\cytoks}%
  \foreachitem\z\in\arglist[]{%
    \expandafter\setsepchar\expandafter{\z}%
    \expandafter\def\expandafter\tmp\expandafter{\the\mytoks}%
    \readlist*\cmdlist{\tmp}%
    \mytoks{}%
    \foreachitem\zz\in\cmdlist[]{%
      \ifnum\zzcnt=1\relax\else%
        \tmptoks{&}%
        \xaddtotoks\tmptoks{\zcnt}%
        \xaddtotoks\mytoks{\the\tmptoks}%
      \fi%
      \xaddtotoks\mytoks{\zz}%
    }%
  }%
%
  \setsepchar{&}%
  \expandafter\readlist\expandafter\cmdlist\expandafter{\the\mytoks}%
  \mytoks{}%
  \foreachitem\z\in\cmdlist[]{%
    \ifnum\zcnt=1\relax\else\addtotoks\mytoks{####}\fi%
    \xaddtotoks\mytoks{\z}%
  }%
%
  \expandafter\addBracesSpaces\expandafter{\the\mytoks}%
%
  \def\tmp{\newcommand{#1}[\arglistlen]}%
  \expandafter\tmp\expandafter{\the\mytoks}%
}

\newcommand\addBracesSpaces[1]{\mytoks{}\fooaux#1\endfoo}
\def\fooaux#1{%
  \tctestifx{\endfoo#1}{}
  {\tctestifx{\OPENSgroup#1}{\Z}
  {\tctestifx{\SPACEquark#1}{\addtotoks\mytoks{ }}
  {\addtotoks\mytoks{#1}}\fooaux}}%
}
\makeatother

\def\Z#1\CLOSEgroup{\addtotoks\mytoks{{#1}}\fooaux}

\symbolicnewcommand{\foocommand}%
  [!normal,!bold,!italics,!smallcaps,!emphasis,!boxed]%
  {!normal{} \textbf{!bold} \textit{!italics} 
   \textsc{!smallcaps} \emph{!emphasis} \fbox{!boxed}}
\begin{document}
\meaning\foocommand

\foocommand{To be,}{or not}{to be?}{That}{is the question.}{123}
\end{document}

在此处输入图片描述

相关内容