所以我编写了代码,我认为这是一种 hack,但在我的测试中它似乎到目前为止是有效的。我设置了一个expl3
设置 dimen 变量的新函数。如果 dimen 表达式的输入不包含 TeX 已知的单位,则单位默认为pt
。
我见过非expl3
包有接口,用户可以在其中设置 dimen 变量并将单位默认为pt
。例如,fontsize
包有一个包选项fontsize=<fontsize>
,如果未指定 的单位<fontsize>
,则会自动将其设置为pt
。
我的问题是:在编写类或包时,是否有更好、更正式的方法将默认单位(pt
、bp
pc
等)设置为无单位表达式expl3
?
下面我提供了我的最小工作示例。
\documentclass{article}
\ExplSyntaxOn
\prg_generate_conditional_variant:Nnn \regex_match:Nn { NV } { TF }
\tl_new:N \l__module_tmpa_tl
\dim_new:N \l__module_tmpa_dim
% Checks if the input contains any unit known to TeX.
% This regex is based off the regex given in section 8.1.1 of interface3.pdf.
\regex_const:Nn \c_module_contains_any_unit_regex
{ (?i)pt|in|[cem]m|ex|[bs]p|[dn]d|[pcn]c }
\cs_new:Nn \__module_dim_set_with_default_unit:Nn
{
\tl_set:Nx \l__module_tmpa_tl { #2 }
\regex_match:NVTF
\c_module_contains_any_unit_regex \l__module_tmpa_tl
{ \dim_set:Nn #1 { \l__module_tmpa_tl } }
{ \dim_set:Nn #1 { \fp_eval:n { \l__module_tmpa_tl } pt } }
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn % only for testing purposes
\__module_dim_set_with_default_unit:Nn \l__module_tmpa_dim { 10 } % without unit
\dim_use:N \l__module_tmpa_dim % the unit defaults to pt
\newline
\__module_dim_set_with_default_unit:Nn \l__module_tmpa_dim { 10bp } % with unit
\dim_use:N \l__module_tmpa_dim
\ExplSyntaxOff
\end{document}
答案1
\textwidth
在这里使用正则表达式很慢,并且会说出需要一个单位的值。
LaTeX 已经提供了\@defaultunitsset
使用 wipet 显示的方法
\@defaultunitsset dimen value default
其中default
可以是单位或长度,例如\unitlength
在图片模式中使用的。
你可以直接使用它,或者更自然地在 expl3 中给它一个 L3 名称,这样就可以生成变体,所以
\ExplSyntaxOn
\dim_new:N \l__module_tmpa_dim
\cs_new_eq:Nc \__module_dim_set_with_default_unit:Nnn {@defaultunitsset}
\cs_new_protected:Npn \__module_dim_set_with_default_unit:Nn #1#2
{
\__module_dim_set_with_default_unit:Nnn #1 { #2 }{ pt }
}
\__module_dim_set_with_default_unit:Nn \l__module_tmpa_dim { 10 }
\dim_show:N \l__module_tmpa_dim
\__module_dim_set_with_default_unit:Nn \l__module_tmpa_dim { 10 bp}
\dim_show:N \l__module_tmpa_dim
\stop
生产
> \l__module_tmpa_dim=10.0pt.
<recently read> }
l.13 \dim_show:N \l__module_tmpa_dim
?
> \l__module_tmpa_dim=10.03749pt.
<recently read> }
l.17 \dim_show:N \l__module_tmpa_dim
?
答案2
我看不懂你的代码,因为expl3
对我来说太复杂了,但你可以比较一下如何使用 TeX 原语解决你的任务\afterassignment
。它似乎更简单、更直接。
\def\setdimen#1#2{%
\afterassignment\setdimenA
#1=#2pt\relax
}
\def\setdimenA#1\relax{}
%% test:
\newdimen\tmpdim
\setdimen\tmpdim {20} \the\tmpdim % prints: 20.0pt
\setdimen\tmpdim {4em} \the\tmpdim % prints: 40.0pt