expl3 / 将长度设置为平均字符宽度

expl3 / 将长度设置为平均字符宽度

我有一个计算平均字符宽度的函数。该函数按预期计算宽度,但我无法在 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

相关内容