分析

分析

如何确定“多线”的高度和深度\ooalign

\ooalign{\relax\cr%
         \noalign{\vskip-2ex}X\cr%
         \noalign{\vskip+2ex}\cr%
         \noalign{\vskip+1ex}X\cr%
         \noalign{\vskip-1ex}%
        }%

答案是深度和高度混淆我似乎只得到了下部的尺寸\ooalign

答案1

分析

\ooalign使用\vtop。如果第一个元素是框,则其高度为 的高度\ooalign,否则高度为 0 pt。\noalign如果开头没有\ooalign,则第一个元素是第一行,则\ooalign具有第一行的高度。在这种情况下,行为空(\relax),因此高度为 0 pt。

\vtop深度更复杂。TeX 首先在 中设置 的内容\vbox。然后 TeX 如上所述获取高度并相应地移动参考点。因此深度是 总高度\vbox减去上方的高度。

由于段落参数设置,中的行\ooalign不会移动其参考点,因此行会覆盖前几行。因此,只有最后一行的深度和的贡献总和\noalign对整体深度有影响。在这种情况下,贡献总和\noalign{\vskip...}为 0 pt,最后一行的深度也是如此。因此的深度\ooalign为 0 pt。

微距\charsovereachother(无\noalign

当用户希望 中所有行的高度和深度最大时,可以使用以下宏\charsovereachother代替。(仅在没有通过 手动移动的情况下才有意义)。\ooalign\ooalign\noalign{\vskip...}

测试文件是为纯 TeX 编写的,但该宏也可以在 LaTeX 中使用:

\edef\RestoreAtCatcode{\catcode`\noexpand\@=\the\catcode`\@\relax}
\catcode`\@=11
\newdimen\COEO@height
\newdimen\COEO@depth
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname protected\endcsname\relax
\else
  \expandafter\protected
\fi 
\def\charsovereachother#1{%
  \leavevmode
  \begingroup
    \setbox0\vtop{%
      \baselineskip0pt\relax
      \lineskip0pt\relax
      \lineskiplimit=-16383.99999pt\relax
      \gdef\COEO@height{0pt}%
      \gdef\COEO@depth{0pt}%
      \everycr{}\tabskip0pt\halign{%
        % the cell contents is measured and
        % the maximum values for height and depth are remembered
        \setbox0\hbox{##}%
        \ifdim\COEO@height<\ht0 %
          \xdef\COEO@height{\the\ht0}%
        \fi
        \ifdim\COEO@depth<\dp0 %
          \xdef\COEO@depth{\the\dp0}%
        \fi
        \unhcopy0 %
        \crcr
        #1%
        \crcr
      }%
    }%  
    \vtop{%
      % update the height if necessary
      \ifdim\COEO@height>\ht0 %
        \hrule width0pt height\COEO@height depth0pt %
        \kern-\ht0 %
      \fi
      \unvcopy0 %
      % update the depth if necessary
      \ifdim\COEO@depth>\dp0 %
        \kern-\dp0 %
        \kern\COEO@depth
      \fi   
    }%
  \endgroup
}%
\RestoreAtCatcode

% Test

\hrule

\ooalign{a. row$_{\hbox{(1st line)}}$\hfill\cr
  \kern10em last row$^{\hbox{(2nd line)}}$}

\hrule

\bigskip

\hrule  

\charsovereachother{a. row$_{\hbox{(1st line)}}$\hfill\cr
  \kern10em last row$^{\hbox{(2nd line)}}$}

\hrule

\bye

结果

答案2

可以通过从包中\charsovereachother正确配置来直接模拟Heiko 。 \Longstackstackengine

\documentclass{article}
\usepackage{stackengine}
\setstackEOL{\cr}\setstackgap{L}{0pt}\def\stackalignment{l}
\begin{document}
\hrule  

\Longstack{a. row$_{\hbox{(1st line)}}$\hfill\cr
  \kern10em last row$^{\hbox{(2nd line)}}$}

\hrule
\end{document}

在此处输入图片描述

请注意,\hfill可以从论点中消除,但我将其保留在那里以匹配 Heiko 使用的论点。

还要注意,\vskip堆叠参数中不允许使用 s,但可以根据问题以其他方式模拟。例如,OP 的 MWE 很容易用堆栈执行。如你所见,边界线可以正确捕获堆栈的高度和深度\hrule

\documentclass{article}
\usepackage{stackengine}
\begin{document}
\hrule

\ooalign{\relax\cr%
         \noalign{\vskip-2ex}Q\cr%
         \noalign{\vskip+2ex}\cr%
         \noalign{\vskip+1ex}X\cr%
         \noalign{\vskip-1ex}%
        }%
\def\stacktype{L}
\stackunder[1ex]{\stackon[2ex]{}{Q}}{X}

\hrule
\end{document}

在此处输入图片描述

答案3

看完之后Heiko Oberdiek 的回答之后,我理解了(至少部分)原始代码的含义。

看完之后Steven B. Segletes 的回答,我可以将原始代码简化为

\Longstack{%
           \raisebox{+2ex}{X}\cr%
           \raisebox{-1ex}{X}\cr%
           }

(包装和配置与 Steven B. Segletes 的回答一致)。

为了得到这个的高度和深度,还测量了替换

\raisebox{+2ex}{X}
\raisebox{-1ex}{X}

作品,即

\newlength\myHeight
\newlength\myDepth

\settoheight{\myHeight}{%
  \raisebox{+2ex}{\vphantom{X}}%
  \raisebox{-1ex}\vphantom{{X}}% this line only needed when this "lower X" 
                               % would reach higher than the "upper X"
}%

\settodepth{\myDepth}{%
  \raisebox{+2ex}{\vphantom{X}}% this line only needed when this "higher X"
                               % would reach deeper than the "lower X"
  \raisebox{-1ex}{\vphantom{X}}%
}%

其中我添加了\vphantoms 来表示“XX”比……更宽的情况\textwidth(但“更高 X”和“更低 X”都不宽)。

然后

\hbox{\vrule\@height\myHeight%
                    \@depth\myDepth%
                    \@width\z@}

具有的高度和深度\ooalign{...}(且宽度为零)。

梅威瑟:

\documentclass{article}

\newlength\myHeight
\newlength\myDepth

\begin{document}
\makeatletter

\hrule
\ooalign{\relax\cr%
         \noalign{\vskip-2ex}{X}\cr%
         \noalign{\vskip+2ex}\cr%
         \noalign{\vskip+1ex}{X}\cr%
         \noalign{\vskip-1ex}%
        }% 
%
\settoheight{\myHeight}{%
  \raisebox{+2ex}{\vphantom{X}}%
  \raisebox{-1ex}\vphantom{{X}}% 
 }%
\settodepth{\myDepth}{%
  \raisebox{+2ex}{\vphantom{X}}%
  \raisebox{-1ex}{\vphantom{X}}%
 }%
\hbox{\vrule\@height\myHeight%
            \@depth\myDepth%
            \@width\z@}%
\hrule 

\makeatother 
\end{document}

得到以下输出:

结果

(如果没有另外两个答案我永远也不会想到这一点 - 谢谢!)。

相关内容