如何防止插入\parskip 胶水?

如何防止插入\parskip 胶水?

\vtop下面例子中两者的代码看起来非常相似。

不同之处在于:

  • 在情况 1 中,您有\hbox{ccc\hfill}。由于和之间\hrule没有\baselineskip插入 -glue 。TeX 不会进入水平模式。和之间没有插入 -glue 。(和之间根本没有插入垂直胶水。)bbbccc\parskipbbbcccbbbccc
  • 在情况 2 中,你有ccc。由于和之间\hrule没有\baselineskip插入 -glue 。TeX 会进入水平模式。和之间插入 -glue 。bbbccc\parskipbbbccc

现在假设一种情况,你不知道 TeX 是否会在 之后进入水平模式,\hrule但无论如何你都不想\parskip在 之后有 -glue/任何垂直粘连\hrule。无论如何你都希望它看起来像情况 1 中的那样。

有没有一种方法可以取消或防止\parskip胶水,以防材料在\hrule切换到水平模式之前不知道这种切换是否会发生?

\parindent=0ex
\parskip=4cm

\baselineskip=2cm

\hbox to\hsize{%
\vtop{\hsize=.3\hsize
  \hbox{aaa}
  \hbox{bbb}
  \hrule height 0mm depth 0mm\relax

  \hbox{ccc} %<- TeX stays in restricted vertical mode
  \par\hbox to\hsize{This is case 1\hfill}

}\hfill\vrule\hfill
\vtop{\hsize=.3\hsize
  \hbox{aaa}
  \hbox{bbb}
  \hrule height 0mm depth 0mm\relax

  ccc %<- TeX switches to horizontal mode
  \par\hbox to\hsize{This is case 2\hfill}
}%
}
\bye

在此处输入图片描述

答案1

你可以做这样的事情

在此处输入图片描述

\parindent=0ex
\parskip=4cm

\baselineskip=2cm

\hbox to\hsize{%
\vtop{\hsize=.3\hsize
  \hbox{aaa}
  \hbox{bbb}
  \hrule height 0mm depth 0mm\relax
  \everypar{\setbox0=\lastbox\endgraf\everypar{}\vskip-2\parskip}

  \hbox{ccc} %<- TeX stays in restricted vertical mode
  \par\hbox to\hsize{This is case 1\hfill}

}\hfill\vrule\hfill
\vtop{\hsize=.3\hsize
  \hbox{aaa}
  \hbox{bbb}
  \hrule height 0mm depth 0mm\relax
  \everypar{\setbox0=\lastbox\endgraf\everypar{}\vskip-2\parskip}

  ccc %<- TeX switches to horizontal mode
  \par\hbox to\hsize{This is case 2\hfill}
}%
}
\bye

答案2

这个答案是进一步发展的尝试大卫·卡莱尔的回答\everypar它针对的是每当 TeX 由于切换到水平模式而刚刚传递垂直粘合并通过插入宽度\parskip来启动水平列表时传递其标记的钩子。\hbox\parindent

由于您关注的是“的代码\vtop”而不是本身,\vtop因此我假设所需的方法也是在(非内部)垂直模式下解决,其中可能某些\begingroup.. \endgroup-thingie 可能在前面,而更多的段落可能在\hbox{ccc}// ( ccc? \noindent ccc)-thingie 之后。

也许您可以摆弄\everypar\everyhbox、、以确保不仅下一段而且通常接下来排版的内容都会取消对 的\everyvbox更改。 \everymath\everydisplay\everyar我还没有想过关于“下一步排版的东西”是否还有更模糊的情况需要考虑。

在下面的示例中,token\skiprestore\resetskiprestore永久地添加到上述每个钩子上。通常这些宏是无操作的。

\makemydamnverticalgap重新定义

  • \resetskiprestore重新定义\skiprestore并将\resetskiprestore其设为无操作。
  • \skiprestore应用重新定义\resetskiprestore并做一些负垂直跳过以取消垂直\parskip粘合,以防\noindent插入\hbox的用于启动水平列表的宽度为0pt

我决定将标记永久地添加到钩子前面,因为这样就可以重新定义这些标记,这意味着\global所需的更改将在包装成组后继续存在。

我不知道在 LaTeX 2ε 中实现这种事情的最佳方法,其中内核本身会处理所有这些\every...-hooks。

在 LaTeX 中也有这样的包一切钩子这允许您随意使用\every...-hooks。请注意,当前版本(everyhook v1.2,发布日期为 2014/11/26)有一个错误,每当执行 、、等操作时,连续哈希值的数量就会减半,例如,########减半为。####\PushPreHook\PopPreHook\PushPostHook\PopPostHook (几个月前我在该软件包的 GitHub 存储库上解决了这个问题。)

\parindent=3ex
\parskip=.5cm

\long\def\exchange#1#2{#2#1}
\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}

\newbox\mybox

\long\gdef\prependtohook#1#2{%
  #1=\expandafter{\romannumeral0\expandafter\exchange\expandafter{\the#1}{ #2}}
}%
\prependtohook\everypar{\skiprestore}
\prependtohook\everyhbox{\resetskiprestore}
\prependtohook\everyvbox{\resetskiprestore}
\prependtohook\everymath{\resetskiprestore}
\prependtohook\everydisplay{\resetskiprestore}
% I am not sure whether \resetskiprestore should be done with other hooks also.

\newbox\mybox

\gdef\skiprestore{}%
\gdef\resetskiprestore{}%
\long\def\makemydamnverticalgap#1{%
  \endgraf
  \hrule height 0mm depth 0mm\relax\nobreak
  \kern#1\nobreak
  \hrule height 0mm depth 0mm\relax
  \gdef\resetskiprestore{\gdef\skiprestore{}\gdef\resetskiprestore{}}%
  \gdef\skiprestore{%
    \resetskiprestore
    \setbox\mybox=\lastbox
    \vskip-2\parskip
    \endgraf\ifdim\wd\mybox>0pt \else\expandafter\noindent\fi
  }%
  \ignorespaces
}%


\noindent This is some paragraph.\xleaders\hbox{This is some paragraph.}\hfill This is some paragraph.
\begingroup
\makemydamnverticalgap{2cm}
\endgroup
\hbox{This does not switch to horizontal mode. There should be a vertical 2cm gap above this.}

This is another paragraph.

\noindent This is some paragraph.\xleaders\hbox{This is some paragraph.}\hfill This is some paragraph.
\begingroup
\makemydamnverticalgap{2cm}
\endgroup
\leavevmode This does switch to horizontal mode. There should be a vertical 2cm gap above this.

This is another paragraph.

\noindent This is some paragraph.\xleaders\hbox{This is some paragraph.}\hfill This is some paragraph.
\begingroup
\makemydamnverticalgap{2cm}
\endgroup
\noindent This does switch to horizontal mode. There should be a vertical 2cm gap above this.

This is another paragraph.

\xleaders\vbox{\hrule height 0pt width 0pt\par This is another paragraph.}\vfill\break

\parindent=1cm
\parskip=4cm
\baselineskip=2cm

\hbox to\hsize{%
  \vtop{\hsize=.25\hsize
    \hbox{aaa}
    \hbox{bbb}
    \makemydamnverticalgap{0cm}%

    \hbox{ccc} %<- TeX stays in restricted vertical mo\-de
    \par\vtop{\noindent This is case 1 - \TeX{} staying in restricted vertical mo\-de}
  }\hfill\vrule\hfill
  \vtop{\hsize=.25\hsize
    \hbox{aaa}
    \hbox{bbb}
    \makemydamnverticalgap{0cm}%

    ccc %<- TeX switches to horizontal mo\-de
    \par\vtop{\noindent This is case 2 - \TeX{} switching to horizontal mo\-de and inserting {\tt\string\par\-in\-dent}}
  }\hfill\vrule\hfill
  \vtop{\hsize=.25\hsize
    \hbox{aaa}
    \hbox{bbb}
    \makemydamnverticalgap{0cm}%

    \noindent ccc %<- TeX switches to horizontal mo\-de
    \par\vtop{\noindent This is case 3 - \TeX{} switching to horizontal mo\-de and not inserting {\tt\string\par\-in\-dent}}
  }
}

\bye

在此处输入图片描述

在此处输入图片描述

相关内容