可以修改宏内的参数吗?

可以修改宏内的参数吗?

我希望在一系列参数为空时为其赋予默认值。我可以在参数使用之前进行测试,并在每次使用之前修改该值。我甚至可以创建一个宏来执行此操作。我可以构建一个宏来封装将“处理”参数的初始宏。更优雅的方式是在宏的开头修改参数。这可能吗?

我希望我可以改变中的值#1,例如\def#1{...}

\def\DisplayNumber#1{
\def#1{\ifx&#1& 0\else#1\fi} % if argument empty, make #1 equal to 0
Result is : #1}

答案1

最简单的方法是在使用时添加条件:

\def\DisplayNumber#1{%
  Result is: \ifx&#1&0\else#1\fi
}

除了\ifx&#1&测试空性之外,您还可以使用

\if\relax\detokenize{#1}\relax

只要您启用了 e-TeX 扩展。

您还可以定义一个实用程序宏:

\def\printifempty#1#2{\ifx&#2&#1\else#2\fi}

你的宏可以是

\def\DisplayNumber#1{%
  Result is: \printifempty{0}{#1}%
}

改变参数的“通用”策略是定义一个“外部”和一个“内部”宏。借助expl3可以避免编写包含大量\expandafter和的繁琐代码\romannumeral

\input expl3-generic

\ExplSyntaxOn

\cs_new:Nn \test_internal_macro:nnnnnn
 {
  \internalmacro{#1}{#2}{#3}{#4}{#5}{#6}
 }
\cs_generate_variant:Nn \test_internal_macro:nnnnnn { ffffff }

\cs_new:Nn \test_external_macro:nnnnnn
 {
  \test_internal_macro:ffffff
   { \tl_if_blank:nTF { #1 } { 0 } { #1 } }
   { \tl_if_blank:nTF { #2 } { 0 } { #2 } }
   { \tl_if_blank:nTF { #3 } { 0 } { #3 } }
   { \tl_if_blank:nTF { #4 } { 0 } { #4 } }
   { \tl_if_blank:nTF { #5 } { 0 } { #5 } }
   { \tl_if_blank:nTF { #6 } { 0 } { #6 } }
 }

\cs_new_eq:NN \externalmacro \test_external_macro:nnnnnn

\ExplSyntaxOff

\def\internalmacro#1#2#3#4#5#6{%
  \bigskip Calling {\tt\string\externalmacro}\par
  This is arg \#1: #1\par
  This is arg \#2: #2\par
  This is arg \#3: #3\par
  This is arg \#4: #4\par
  This is arg \#5: #5\par
  This is arg \#6: #6\par
}

\externalmacro{A}{B}{C}{D}{E}{F}

\externalmacro{A}{}{}{D}{E}{F}

\externalmacro{}{}{}{}{}{}

\bye

\externalmacro命令被定义为\internalmacro使用“规范化”参数进行调用:如果其中一个为空,0则替换。

这将调用\test_internal_macro:ffffff,它是\internalmacro您给出“真实”定义的包装器。

在此处输入图片描述

相关内容