![\setlength 的奇怪行为](https://linux22.com/image/471362/%5Csetlength%20%E7%9A%84%E5%A5%87%E6%80%AA%E8%A1%8C%E4%B8%BA.png)
我希望使用下面的代码来获取单词列表的最大长度。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{calc}
\begin{document}
\begin{tikzpicture}
\def\words{%
xxx,
xxxxxx,
xxxxxxxxx%
}
\newlength{\mywidth}
\setlength\mywidth{0pt}
\foreach \word in \words {%
\setlength\mywidth{\maxof{\mywidth}{\widthof{word}}}
\message{showinfo1 \word -> \the\mywidth};
}
\message{showinfo2 \the\mywidth};
\end{tikzpicture}
\end{document}
但输出结果看起来很奇怪:
showinfo1 xxx-> 21.4167pt
showinfo1 xxxxxx-> 21.4167pt
showinfo1 xxxxxxxxx-> 21.4167pt
showinfo2 0.0pt
- showinfo1应该随着字长的增加而逐个增加,但实际输出的值相同
- showinfo2 应该是最后一个有效值,但它显示为 0。
我应该使用任何全球版本吗?
答案1
您总是会得到相同的结果,因为您测量的是“单词”而不是(的扩展)\word
。
但是主要问题是\foreach
循环的每一步都是按组执行的,因此设置会\mywidth
被遗忘,最终结果为零。您需要一个不使用分组的循环。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\settomaxwidth}{mm}
{% #1 = length parameter
% #2 = list of words
\lucky_settomaxwidth:Nn #1 { #2 }
}
\dim_new:N \l__lucky_tempwd_dim
\cs_new_protected:Nn \lucky_settomaxwidth:Nn
{
% start by setting the width to zero
\dim_zero:N \l__lucky_tempwd_dim
% map the given list
\clist_map_inline:nn { #2 }
{
% set the current word in a box
\hbox_set:Nn \l_tmpa_box { ##1 }
% set the temporary length to the max of the two
\dim_set:Nn \l__lucky_tempwd_dim
{
\dim_max:nn { \box_wd:N \l_tmpa_box } { \l__lucky_tempwd_dim }
}
}
% finalize
\dim_set_eq:NN #1 \l__lucky_tempwd_dim
}
\ExplSyntaxOff
\newlength{\mywidth}
\settomaxwidth{\mywidth}{
xxx,
xxxxxx,
xxxxxxxxx
}
\typeout{Max width: \the\mywidth}
\settomaxwidth{\mywidth}{xxx,xxxxxx,xxxxxxxxx}
\typeout{Max width: \the\mywidth}
\end{document}
这两个例子表明逗号周围的空格被忽略。
Max width: 47.50021pt
Max width: 47.50021pt
答案2
word
另一个答案中提到了关于相反的错误以及TikZ 在组中运行其主体的\word
事实。\foreach
此处的 egerg 的答案显示了基于 expl3 的解决方案。我还可以显示另外两个答案:
基于 TeX 基元:
\newdimen\mywidth
\def\measureword #1,{%
\ifx \end#1 \relax \else
\setbox0 = \hbox{\ignorespaces #1}%
\ifdim\wd0>\mywidth \mywidth=\wd0 \fi
\expandafter \measureword \fi
}
\def\words{%
xxx,
xxxxxx,
xxxxxxxxx%
}
\expandafter\measureword \words,\end,
\message{Result: \the\mywidth}
在 OpTeX 中:
\def\words{%
xxx,
xxxxxx,
xxxxxxxxx%
}
\replstring\words{, }{,}
\ea\foreach \words,\do #1,{\setbox0=\hbox{#1}\ifdim\wd0>\mywidth \mywidth=\wd0 \fi}
\message{Result: \the\mywidth}
\bye