我必须存储非二进制状态,哪种 LaTeX3 方式更符合习惯?例如,假设有 3 种可能的格式手稿:长/短/中。在 LaTeX3 中最好的方法是什么?
我能想到多种可能性:
定义一堆
int_const
常量(固定为 1、2、3 等)来命名可能的状态,然后使用全局整数int_new
来存储当前状态。这看起来很简单,但也非常昂贵。如果我的理解正确的话,在当前的 LaTeX3 设计中,每个整数常量都占用一个计数器寄存器。
使用标记来表示可能的状态。在这种情况下,为了便于阅读,我希望在代码中使用之前声明用于可能状态的标记。因此,可以有一个
tl_const
(对于每个可能的状态,等于 1、2、3 等),然后使用全局标记列表变量来保存当前状态。这看起来更有效,甚至可能更直接,但我不喜欢将我的“枚举”标签命名为,
c_xxx_xxx_tl
因为我认为将它们命名为标记列表会降低代码的可读性。
对此事有什么想法吗?
答案1
这是评论中提到的方法的一个例子。
<foo>
对于枚举的每个值,我们定义一个新函数\c_<foo>_manuscript
,该函数具有\c_<foo>_manuscript_undefined:
替换文本。(真正的夸克式方法是将其扩展为\c_<foo>_manuscript
自身,但根据我的经验,将其扩展为未定义的控制序列同样有效,并且在函数意外扩展的情况下更容易调试。)
因此“枚举”看起来像
\cs_new_protected:Npn \c_short_manuscript { \c_short_manuscript_undefined: }
\cs_new_protected:Npn \c_medium_manuscript { \c_medium_manuscript_undefined: }
\cs_new_protected:Npn \c_long_manuscript { \c_long_manuscript_undefined: }
存储其中一个值是通过\let
将控制序列分配给相应的常量来实现的:
\cs_set_eq:NN \g__callegar_cur_manuscript \c_medium_manuscript
最后,为了根据某个常数检查当前值,我们使用
\cs_if_eq:NNTF \g__callegar_cur_manuscript \c_medium_manuscript { true } { false }
完整示例文档:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% The "enumeration" values
\cs_new_protected:Npn \c_short_manuscript { \c_short_manuscript_undefined: }
\cs_new_protected:Npn \c_medium_manuscript { \c_medium_manuscript_undefined: }
\cs_new_protected:Npn \c_long_manuscript { \c_long_manuscript_undefined: }
% CS holding the current manuscript type value
\cs_set_eq:NN \g__callegar_cur_manuscript \c_medium_manuscript
% Set current manuscript type
\NewDocumentCommand \SetManuscriptType { m } {
\cs_if_exist:cTF { c_#1_manuscript }
{ \cs_set_eq:Nc \g__callegar_cur_manuscript { c_#1_manuscript } }
{ \PackageError { callegar } { Manuscript~type~`#1'~not~defined } { } }
}
% Switch over the current manuscript type
\NewDocumentCommand \SwitchManuscriptType { +m+m+m } {
\cs_if_eq:NNTF \g__callegar_cur_manuscript \c_short_manuscript { #1 } {
\cs_if_eq:NNTF \g__callegar_cur_manuscript \c_medium_manuscript { #2 } {
\cs_if_eq:NNTF \g__callegar_cur_manuscript \c_long_manuscript { #3 }
{ \PackageError { callegar } { Unknown~manuscript~type~set } { } }
}
}
}
\ExplSyntaxOff
\begin{document}
Current manuscript type: \SwitchManuscriptType{short}{medium}{long}
\SetManuscriptType{short}
Current manuscript type: \SwitchManuscriptType{short}{medium}{long}
\SetManuscriptType{long}
Current manuscript type: \SwitchManuscriptType{short}{medium}{long}
%\SetManuscriptType{extralong}
\end{document}