我写了一个运算符表\advance
。如果行太长,我想要一个中断,并且第二行向右对齐。我试图从\signed
TeXbook 第 106 页中介绍的宏中获得灵感。
\parindent=0pt
\obeylines
\def\signed #1{{\penalty50\hskip0pt plus-1fill\hbox{}\hfill\ #1}}
{\tt -1pt} advanced by {\tt 1pt} =\signed {\tt 0.0pt.}
{\tt 0pt plus -1pt minus -1pt} advanced by {\tt 1pt plus -1pt minus -1pt} =\signed {\tt 1.0pt plus -2.0pt minus -2.0pt.}
第一条语句很短,一行一个空格。很好。
第二条语句有点长。它在“=”后中断。但是这里,第二行停留在左边。为什么?
答案1
您必须插入一些\nobreak
宏。
\parindent=0pt
\def\signed #1{{%
\unskip % in case there is space preceding \signed
\nobreak\hskip 0pt plus -1fill % no break here
\penalty50 % possible break here
\hbox{}% something not discardable
\nobreak\hfill % no break at this skip
\ % a normal space
#1% the text to typeset
}}
X\dotfill X
{\tt -1pt} advanced by {\tt 1pt} =\signed {\tt 0.0pt.}
{\tt 0pt plus -1pt minus -1pt} advanced by {\tt 1pt plus -1pt minus -1pt}
= \signed {\tt 1.0pt plus -2.0pt minus -2.0pt.}
\bye
如果在惩罚时没有休息,则两个无限跳跃将相互抵消。否则第一个无限跳跃将不产生任何作用。
答案2
与 TeXbook 不同,你的\signed
宏在\nobreak
之前缺少\hfill
。为了避免\penalty50
,行将在 之前断开\hfill
(使\hfill
消失)。
答案3
@egreg 的答案很好。(谢谢!)
然而,我对此并不完全满意,因为我不明白为什么第一次无限跳过在中断时什么也不做。
我终于找到了一个我更理解的可行的解决方案。
\def\signed #1{{%
\nobreak\hfil% infinite glue at end of first line if break
\penalty50%
\hfilneg\hskip0pt plus-1fill% compensates for infinite glues if no break, else discarded
\hbox{}%
\nobreak\hfill% infinite glue at beginning of second line,
% with 2 'l's because of the hfil at end of paragraph
\ #1%
}}