我有一个计算平均字符宽度的函数。该函数按预期计算宽度,但我无法在 setlength 中使用它。我尝试过各种方法,也尝试过我在 Google 上搜索的解决方案,但还是无法让它工作。
\documentclass[12pt]{scrartcl}
\usepackage{fontspec}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\tl_const:Nn \c_typo_alphabet_tl {abcdefghijklmnopqrstuvwxyz}
\cs_new:Npn \typo_avg_charwidth:n #1 {
\hbox_set:Nn \l_tmpa_box { #1 \c_typo_alphabet_tl }
\dim_eval:n { \dim_eval:n { \box_wd:N \l_tmpa_box } / \tl_count:N \c_typo_alphabet_tl }
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\typo_avg_charwidth:n {} % works, but only with braces!!
\par
\typo_avg_charwidth:n {\textit} % works
\newlength{\charwidth}
\setlength{\charwidth}{\typo_avg_charwidth:n {} } % error: missing number
\ExplSyntaxOff
\end{document}
我收到的最持久的错误是! Missing number, treated as zero.
\cs_show:N \typo_avg_charwidth:n
生产
> \typo_avg_charwidth:n=\long macro:#1->\hbox_set:Nn \l_tmpa_box
{#1\c_typo_alphabet_tl }\dim_eval:n {\dim_eval:n {\box_wd:N \l_tmpa_box
}/\tl_count:N \c_typo_alphabet_tl }.
<recently read> }
l.23 \cs_show:N \typo_avg_charwidth:n
谁能帮我吗?
答案1
您可以执行框分配,然后在分配中使用它,而不是在分配中使用宏。这要求您的宏具有不同的语法,但允许您执行您想要执行的操作:
\documentclass[12pt]{scrartcl}
\ExplSyntaxOn
\tl_const:Nn \c_alexber_typo_alphabet_tl {abcdefghijklmnopqrstuvwxyz}
\cs_new_protected:Npn \alexber_set_avg_wd:Nn #1#2
{
\group_begin:
\hbox_set:Nn \l_tmpa_box { #2 \c_alexber_typo_alphabet_tl }
\exp_args:NNNe
\group_end:
\dim_set:Nn #1 { \dim_eval:n { \box_wd:N \l_tmpa_box } / 26 }
}
\NewDocumentCommand\settoavgwd{O{} m} { \alexber_set_avg_wd:Nn #2 {#1} }
\exp_args_generate:n {NNe}
\ExplSyntaxOff
\newlength\charwidth
\begin{document}
\settoavgwd\charwidth
\the\charwidth
\settoavgwd[\bfseries]\charwidth
\the\charwidth
\end{document}
答案2
我们可以在 OpTeX 中做什么:
\fontfam[lm]
\typosize[12/14.4]
\def\settoavgwd#1{\tmpdim=0pt
\foreach abcdefghijklmnopqrstuvwxyz \do {\setbox0=\hbox{##1}\advance\tmpdim by\wd0}
\divide\tmpdim by26
\global #1=\tmpdim
}
\newdimen\charwidth
\settoavgwd\charwidth
\the\charwidth % result: 5.74014pt
{\bf \settoavgwd\charwidth}
\the\charwidth % result: 6.60599pt
\bye