在 ConTeXt 中 \def 和 \define 相同吗?

在 ConTeXt 中 \def 和 \define 相同吗?

当使用 定义变量时,使用\def和 使用之间有什么区别吗\define?当使用方括号内没有数字时,例如\def\somecommand{\percent}\define\somecommand{\percent}?我可以在可以使用 的\define地方始终使用 吗?\def

答案1

供参考:有两个定义\define:第一个在 系统辅助文件显示了 Egreg 在他的评论中提到的行为:如果宏已经定义,则保留原样。(配套的宏 \redefine允许您覆盖宏的当前定义,而不管它是否正在使用。)具有讽刺意味的是,一旦格式加载,这个初步定义就会被毫无保留地覆盖 核心系统.mkiv(而\redefine永远存在)。

实际定义 用户界面提供的宏\define不仅检查先前定义的同名控制序列,而且还作为强制参数的某种简短符号。它具有以下方案

\define [<digit>] <macro> {<definition>}

其中第一个参数是一个数字,指定新宏将接受的参数数量。显然,这可以缩短定义。相比之下,选择器

\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7}
\starttext
\sevenofnine abcdefghi\par
\stoptext

使用宏需要更少的输入\define

\define[9]\sevenofnine{#7}

因此这些定义可能会产生更易读的代码 —— 这在编写 TEX 时始终是一件好事。

不幸的是,\define包装器剥夺了普通的表达能力\def。在 Context 中,你会注意到,宏采用了可选参数就用户界面而言,这是很常见的。例如,您根本无法 \def使用以下代码片段中的第二个声明替换为等效表达式 \define

\unprotect
\def\myfoo{\dosingleempty\do_my_foo}
\def\do_my_foo[#1]#2{%
  \iffirstargument{\bf\WORD#1}\fi
  #2\par%
}
\protect

\starttext
  \myfoo{bar}
  \myfoo[foo]{bar}
\stoptext

这是因为\define您无法指定参数分隔符(此处:括号)是可选参数所必需的,因此基本上您的宏仅限于采用强制(带括号)参数。出于同样的原因,\{start|stop}something也没有办法定义廉价环境:

\let\stopfoo\relax
\def\startfoo#1\stopfoo{\bgroup\bold#1\egroup}
%%%            ^^^^^^^^ not possible
\starttext
\startfoo
  bar
\stopfoo
\stoptext

(其用户界面是\definestartstop(参见 核心系统.mkiv), 无论如何。)

最后,如今最重要的缺点\define是它不允许韓國式参数。根本没有办法通过其姓名如果你一开始就不能给它分配一个。

% macros=mkvi
\unprotect
\def\foo{\dosingleempty\do_foo}
\def\do_foo[#optional]#mandatory{%
  \bgroup\sansbold#optional\space\egroup
  #mandatory\par%
}
\protect

\starttext
  \foo{bar}
  \foo[foo]{bar}
\stoptext

因此,如果您想进行一些严肃的宏编写,您很快就会学会避免\define,因为它对于不太复杂的任务来说是安全的。

相关内容