考虑以下简单的例子:
\documentclass{article}
\usepackage{xtemplate}
\ExplSyntaxOn
\DeclareObjectType { test } { 10 }
\ExplSyntaxOff
\begin{document}
oh, nose!
\end{document}
ERROR: xtemplate error: "bad-number-of-arguments" --- TeX said --- ! ! Bad number of arguments for object type 'test'. ! ! See the xtemplate documentation for further information. ! ! For immediate help type H <return>. !............................................... l.8 \DeclareObjectType { test } { 10 } --- HELP --- From the .log file... |''''''''''''''''''''''''''''''''''''''''''''''' | This is a coding error. | | An object may accept between 0 and 9 arguments. | You asked to use 10 arguments: this is not supported. |...............................................
我们知道,TeX 仅正式支持最多 9 个参数的宏:
\def\TooLong#1#2#3#4#5#6#7#8#9{haha!}
在过去有需要的时候,我们通过菊花链的方式解决这个问题:
\def\macro{\@macro@a}
\def\@macro@a#1#2#3#4#5#6#7#8{(something with 8 arguments)\@macro@b}
\def\@macro@b#1#2#3#4#5#6#7#8{(something with 8 more arguments)}
现在的使用\macro
必然会从输入流中消耗 16 个令牌。
显然,在“现代”,如此多的参数已经被键值参数的使用所取代:
% ... \usepackage{expl3} ... \ExplSyntaxOn ...
\keys_define:nn { test } {
option-1 .tl_set:N = \l_test_key_a_tl,
option-2 .tl_set:N = \l_test_key_b_tl,
option-3 .tl_set:N = \l_test_key_c_tl,
% ...
}
尽管使用此键值接口的命令只会消耗一个令牌(包含用户键值设置的组),但逻辑上的理解是它test
需要一些n
参数 - 可能所有参数都是必需的(option-n .value_required:
)。
这种对一个对象具有的逻辑理解n
用户可定义属性的逻辑理解是跨设计层面的价值。文档设计者不会在意 TeX 只能接受 9 个参数,因为宏定义有一些内在的(而且大多是任意的)限制。实际上这并不重要:这些参数将通过更合理、更易于维护的键值系统吸收。
负责的角色应该如何传达某个对象具有 9 种以上品质的想法?
如果愿意的话,我可能会在 LaTeX-L 上提出一般性问题,但如果能就“目前”要做什么提出建议,将不胜感激,并接受这个答案。:)
示例用例
我正在构建一个模块化(因此可扩展)的简历/简历解决方案,我想仿照这个奇妙的exsheets
软件包来建模。为此,我需要使用模板的想法。
考虑一个就业记录对象。根据讨论,我会注意到并非所有这些元素都是必需的。
- 职称
- 公司
- 公司名称
- 公司链接
- 场地
- 技术水平
- 开始日期
- 结束日期
- 相关技术
- ETC。
请原谅我无法想出超过 9 个“真实”元素,但我希望我能够传达这个想法。请注意,文档设计器是决定哪些参数是强制性的、哪些不是强制性的;这种选择不应受到限制(针对 LaTeX-L 的讨论)。
我想借此机会说明,强制性论证的纯粹概念——仅考虑这里的词语——并不意味着它是一个立场论证。那将可怕。但这肯定是一个讨论,而不是一个真正的问题。不过,当我不需要在公司时间这样做时,我会为 LaTeX-L 准备一个真正的问题/提案:)
答案1
这里有几件事要记住。首先,template
想法是非常实验性的:特别是,需要的是“现实生活中”对象的良好示例以及它们在不同情况下的使用方式。因此,可能需要进行调整。其次,这里的想法是将设计时决策与使用时输入分开。对象/模板的参数在使用时是“动态”的。最后,我们在这里编写基于 TeX 的代码,因此可能会出现决策反映底层系统的奇怪地方。(理想情况下,这些情况将是有限的,而不是限制)。
以常见的分段命令为例,显然有一个强制参数:分段类对象的名称。但是,还有很多其他的潜在的论点。建议的论点包括
- 运行标题简短版本
- TOC 简短版本
- 章节编号
- TOC 中的存在切换
- 编号开关
- 交叉引用标签
还有一些我现在不记得了!值得注意的是,这个列表中没有一个是绝对地在所有情况下都需要某种形式的分段概念:只有分段的名称才是至关重要的。我们可以看到,在 LaTeX2e 语法中
\section*[Name]{Full Name} % Just the full name absolutely required
以及 HTML
<h1>Full name</h1>
这表明,section 的模板可能不应该要求我建议的每个潜在选项都有一个参数
\UseInstance{sectioning}{latex2e}{<full-name>}{<TOC name>}{<header name>}...
即使使用xparse
与 LaTeX2e 提供的相同的用户界面,看起来仍然很尴尬。
这种事情表明,对象可能需要至少一个“多部分”参数来处理可能给出或可能不给出的各种运行时内容。至少可以说,按照您的建议,采用纯 keyval 可能是明智的做法,并且有一个“运行时参数”来涵盖所有内容,其中一些参数的强制性以不同的方式处理。(我怀疑您还想至少考虑一个“一次性设计更改”参数,因为这并不是一个不常见的要求。)
\UseInstance{sectioning}{latex2e}
{
full-name = <text> ,
TOC-name = ...
}
当然,还有一种中间立场,即有一个或多个“真正强制性的”参数加上一个“其他东西”:这是一种混合,但对于用户来说可能比“纯粹主义者”的所有 keyval 情况更容易。
我认为事实是,大多数“现实世界”对象类型不太可能需要超过 9 个参数。如果您考虑大多数 LaTeX 内容,9 个参数的限制很少出现在用户面前(在编写低级解析等时偶尔会出现,但这有点不同)。
回到关于代码是实验性的观点,显然存在一些悬而未决的问题。我只能描述代码目前的工作方式以及它试图探索的东西是什么。随着时间的推移,各种 LaTeX3 概念已被更改或删除,因为它们显然在“野外”无法正常工作。模板代码和接口并没有真正“经过全球测试”:很可能需要进行更改。(我试图强调的是,我可以看到这里采取不同策略的论点:一个针对 LaTeX-L 的论点。)