在纯 TeX 中是否有与 roff 的 .ns (无空格模式) 等效的东西?

在纯 TeX 中是否有与 roff 的 .ns (无空格模式) 等效的东西?

有没有类似 roff 的.ns纯 TeX 功能(或者更好的功能)?例如,一条命令表示vskip忽略紧随其后的 s,或者(附加的)一个特殊的“ vskip”,使所有相邻的vskips 变为零?

答案1

LaTeX 有这个宏\addvspace;也许这不是你真正想要的,因为它会增加比较两个连续的空格所产生的更大空间,这通常是你想要的。例如,假设一个列表前面总是有一些垂直空间;如果它跟在章节标题后面,那么章节标题后面的空间可能比列表前面的空间大。相反,如果列表跟在后面\smallskip,那么更大的跳跃将是列表的跳跃。所以列表将以 开头,\addvspace或者,对于我下面建议的普通 TeX 宏,以 开头\addvskip

% latex.ltx, line 1462:
\def\addvspace#1{%
  \ifvmode
     \if@minipage\else
       \ifdim \lastskip =\z@
         \vskip #1\relax
       \else
       \@tempskipb#1\relax
         \@xaddvskip
       \fi
     \fi
  \else
    \@noitemerr
  \fi}

补充\@xaddvskip

% latex.ltx, line 1448:
\def\@xaddvskip{%
  \ifdim\lastskip<\@tempskipb
    \vskip-\lastskip
    \vskip\@tempskipb
  \else
    \ifdim\@tempskipb<\z@
      \ifdim\lastskip<\z@
      \else
        \advance\@tempskipb\lastskip
        \vskip-\lastskip
        \vskip \@tempskipb
      \fi
    \fi
  \fi}

在纯 TeX 中您不需要处理小页面,因此这可以简化。

如果未在垂直模式下调用,宏将会发出一条错误消息(错误的消息,但团队在 LaTeX2e 发布时遇到内存限制,因此他们只选择了一条可能有帮助的消息)。

它做什么?在 minipage 中什么也不做,所以让我们看看其他情况。它用于\lastskip检索最后一个跳过的数量(如果最后一个项不是跳过,则返回零);如果返回零,则发出指定的跳过并结束其工作。否则,它会用指定的数量加载暂存跳过寄存器并调用\@xaddvskip

此宏依次检查是否\lastskip小于规定金额;在这种情况下,它会发出\vskip-\lastskip终止指令并发出所需的跳过指令。否则,它会查看规定的跳过是否为负数,如果也是\lastskip负数,则不执行任何操作;否则,它会添加\lastskip到规定的金额,\lastskip像以前一样终止并发出总和。

Plain TeX 的实现如下:

\catcode`@=11
\newskip\@addvskiptemp
\def\addvskip{\afterassignment\@addvskip\@addvskiptemp=}
\def\@addvskip{%
  \par % \vskip implies \par
  \ifdim\lastskip=\z@
    \vskip\@addvskiptemp
  \else
    \@addvsk@p
  \fi
}
\def\@addvsk@p{%
  \ifdim\lastskip<\@addvskiptemp
    \vskip-\lastskip
    \vskip\@addvskiptemp
  \else
    \ifdim\@addvskiptemp<\z@
      \ifdim\lastskip<\z@
      \else
        \advance\@addvskiptemp\lastskip
        \vskip-\lastskip
        \vskip\@addvskiptemp
      \fi
    \fi
  \fi
}
\catcode`@=12

测试文件(在开头添加上面的代码):

abc\smash{\vrule depth 2.9\baselineskip}
\vskip2\baselineskip
abc\smash{\vrule depth 2.9\baselineskip}
\vskip\baselineskip
\addvskip2\baselineskip
abc

\bye

这些规则是为了显示空间是相同的。

在此处输入图片描述

请注意,Plain TeX 已经有了\removelastskip,简化版本可以是

\catcode`@=11
\newskip\@addvskiptemp
\def\addvskip{\afterassignment\@addvskip\@addvskiptemp=}
\def\@addvskip{%
  \par % \vskip implies \par
  \ifdim\lastskip<\@addvskiptemp
    \removelastskip
    \vskip\@addvskiptemp
  \fi
}
\catcode`@=12

如果你不打算出现负面跳过的话。

答案2

您可以准备\vvskip仅在第一次使用时执行 vskip 的宏(在文档中的某个位置):

\let\orivskip=\vskip
\def\vvskip{\par \ifdim\lastskip=0pt \expandafter\orivskip
                 \else \bgroup \afterassignment\egroup \dimen0=\fi
}

您还可以设置\let\vskip=\vvskip以将此行为应用于所有\vskips。但是此解决方案无法对文档中的所有 vskips 进行绝对控制,因为有许多 vskips 不是由\vskip原始函数创建的:来自\parskip、显示数学等。

相关内容