在 中插入一个\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