\setlength 的奇怪行为

\setlength 的奇怪行为

我希望使用下面的代码来获取单词列表的最大长度。

\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
  1. showinfo1应该随着字长的增加而逐个增加,但实际输出的值相同
  2. 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

相关内容