\tabulary 中的 \hphantom 会产生额外的垂直空间而不是水平空间

\tabulary 中的 \hphantom 会产生额外的垂直空间而不是水平空间

在 中插入一个\hphantom缩进表格行是可行的tabular,但在tabulary中却会产生额外的垂直空间。

由于这些是左对齐的L列,我期望左边缘的空间被保留,而右侧的空间是可变的。为什么会发生这种情况?我该如何修复它?

\documentclass{article}
\usepackage{tabulary}

\newcommand{\sator}{Sator arepo tenet opera rotas}
\newcommand{\tabindent}{\hphantom{em}}

\begin{document}

\section{Tabular}

\begin{tabular}{ll}
\sator  & \sator\\
\tabindent\sator & \tabindent\sator\\
\end{tabular}

\section{Tabulary}

\begin{tabulary}{\textwidth}{LL}
\sator  & \sator\\
\tabindent\sator & \tabindent\sator\\
\end{tabulary}

\end{document}

在此处输入图片描述

答案1

\hphantom实际上并不是一个有文档记录的 LaTeX 命令,但这确实是一个讨论它的好时机。

在此更简单的文档中也可以看到该问题,该文档表明tabulary未涉及以下内容:

\documentclass{article}

\newcommand{\sator}{Sator arepo tenet opera rotas}
\newcommand{\tabindent}{\hphantom{em}}

\begin{document}

\sator

\tabindent\sator

\end{document}

在此处输入图片描述

为什么是“空白行”?因为\hphantom 没有开始一个段落,因为它本质上相当于

\hbox{...}

其中...是一些空间(然而,实际实现并非如此)。

解决方案:使用\leavevmode

\documentclass{article}

\newcommand{\sator}{Sator arepo tenet opera rotas}
\newcommand{\tabindent}{\leavevmode\hphantom{em}}

\begin{document}

\sator

\tabindent\sator

\end{document}

在此处输入图片描述

的定义\hphantom

% latex.ltx, line 4137:
\def\hphantom{\v@false\h@true\ph@nt}

\ph@nt

% latex.ltx, line 4139:
\def\ph@nt{%
  \ifmmode
    \expandafter\mathpalette\expandafter\mathph@nt
  \else
    \expandafter\makeph@nt
  \fi}

撇开这里不相关的数学模式的情况,让我们看看\makeph@nt

\def\makeph@nt#1{%
  \setbox\z@\hbox{\color@begingroup#1\color@endgroup}\finph@nt}

的参数\hphantom实际上是的参数\makeph@nt;设置一个框来包含它并\finph@nt调用它。

% latex.ltx, line 4149:
\def\finph@nt{%
  \setbox\tw@\null
  \ifv@ \ht\tw@\ht\z@ \dp\tw@\dp\z@\fi
  \ifh@ \wd\tw@\wd\z@\fi \box\tw@}

\box0通过设置的维度\makeph@nt来改变空框的维度(取决于是否调用\hphantom\vphantom\phantom,有些会改变,有些则不会)。然后 TeX 发出

\box\tw@

它传递占据指定水平或垂直空间的框的(空)内容。这样的命令永远不会改变 TeX 所处的模式,因此不会启动水平模式(段落构建)。

在 的情况下tabular,TeX 处于(受限)水平模式,因此问题不会出现。


这些宏是从 中直接获取的plain.tex;TeXbook 中对这个问题进行了很好的讨论:“phantom”的概念促使 Knuth 在TeX 中添加了\iftrue和,因此和总是或者,并且条件可以正确嵌套。\iffalse\ifv@\ifh@\iftrue\iffalse

相关内容