使用 \ifdim 出现意外的条件分支

使用 \ifdim 出现意外的条件分支

我对以下代码有疑问:

\newtoks\sectoks
\sectoks={\noindent}

\newtoks\subsubjectstyle
\subsubjectstyle={\emitsectglue 1\the\sectoks}

\newtoks\postsectoks
\postsectoks={\par\smallskip\noindent\kern-1sp\hskip1sp}

\long\def\subsubject#1\par{%
  {\the\subsubjectstyle#1}\the\postsectoks}

\def\emitsectglue#1{%
  \ifdim\lastskip=1sp
    \nobreak
  \else
    \vskip0pt plus#1\baselineskip
    \penalty-\numexpr#1*100+50\relax
    \vskip0pt plus-#1\baselineskip
    \vskip#1\baselineskip
  \fi}

\long\def\blockquote#1\eol{%
  \emitsectglue 1
  \begingroup
    \raggedright\narrower\noindent #1
    \smallskip
  \endgroup\noindent}

\tracingall

\subsubject
  The following subsubject will choose the first if's true-branch.

\subsubject
  But the following blockquote will not. Why is that?

\blockquote
  Be conservative in what you send, liberal in what you receive
\eol

\bye

当使用该\subsubject命令后跟另一个命令时\subsubject,宏将按预期工作并且不会添加垂直粘贴和负惩罚。

但是,当使用另一个命令使用完全相同的代码时,突然\if没有选择正确的分支。我不明白为什么会这样。

答案1

\relax在之后添加\hskip1sp:TeX 在寻找跳过规范时会扩展标记,并且在\blockquote跟随时,规范尚未完成,因此扩展会\ifdim在插入跳过之前进行评估。

如果\subsubject如下,则没有问题,因为替换文本中的第一个标记是{停止扩展的标记。

我会支持这一论点,\emitsecglue并消除几个可能的虚假空间源:

\newtoks\sectoks
\sectoks={\noindent}

\newtoks\subsubjectstyle
\subsubjectstyle={\emitsectglue{1}\the\sectoks}

\newtoks\postsectoks
\postsectoks={\par\smallskip\noindent\kern-1sp\hskip1sp\relax}

\def\subsubject#1\par{%
  {\the\subsubjectstyle#1}\the\postsectoks}

\def\emitsectglue#1{%
  \ifdim\lastskip=1sp
    \nobreak
  \else
    \vskip0pt plus#1\baselineskip
    \penalty-\numexpr#1*100+50\relax
    \vskip0pt plus-#1\baselineskip
    \vskip#1\baselineskip
  \fi}

\long\def\blockquote#1\eol{%
  \emitsectglue{1}%
  \begingroup
    \raggedright\narrower\noindent #1%
    \smallskip
  \endgroup\noindent}

\subsubject
  The following subsubject will choose the first if's true-branch.

\subsubject
  But the following blockquote will not. Why is that?

\blockquote
  Be conservative in what you send, liberal in what you receive
\eol

\bye

相关内容