我的论文格式要求多行章节标题的最大宽度为 4.5 英寸,并且任何后续行都会被换行,使得它们依次变短,形成一个倒金字塔。我发现\parshape
我使用的 TeX 命令可以自动执行此操作。但是,它并不总是有效,因为对于居中的文本,在某些情况下,换行发生在行实际填满之前。
我读了一些 TeX 的换行算法,并尝试了一些惩罚,但我搞不清楚它在居中模式下是如何工作的。有人知道如何让 TeX 在居中模式下填满行吗?如能提供任何线索我将不胜感激。
下面是一个最小工作示例,展示了居中模式和非居中模式下的行为差异:
\documentclass{book}
\newcommand{\headingparshape}%
{%
\parshape=6 % account for a maximum of six lines - thereafter all will have the final width
0.75in 4.5in
1.00in 4.0in
1.25in 3.5in
1.50in 3.0in
1.75in 2.5in
2.00in 2.0in
}
\begin{document}
In a centered mode:
\begin{center}
\huge\bfseries\headingparshape
Here is a title that needs to wrap over several lines and has short words
\end{center}
In normal (justified) mode:
{\huge\bfseries\headingparshape{}Here is a title that needs to wrap over several lines and has short words\par}
\end{document}
在居中模式下,换行符结束于此处(弄乱了倒金字塔布局):
这是一个需要换行
且单词较短的标题
在正常模式下,换行符结束于此处(倒金字塔正确):
这是一个需要
换行且
单词较短的标题
~
因此,“这是一个需要的标题”这几个字都放在第一行,但我不知道如何在居中版本中实现这一点,而不必使用和命令进行一堆令人反感的手动格式化\\
。
答案1
根据 egreg 的回答,这里有一个不需要识别最后一行的方法。这个技巧来自TeX 按主题分类。
\documentclass{article}
\newcommand\stupid[1]{%
\vbox{%
\hsize=4.5in
\parindent=0pt
\leftskip=0pt plus.5fil
\rightskip=0pt plus-0.5fil
\parfillskip=0pt plus1fil
\emergencystretch=1in
\parshape6
0.00in 4.50in
0.25in 4.00in
0.50in 3.50in
0.75in 3.00in
1.00in 2.50in
1.25in 2.00in
\huge
\bfseries
\strut
#1%
}%
}
\begin{document}
\stupid{Here is a title that needs to wrap over several lines and has
short words}
\end{document}
答案2
\newcommand{\invpyr}[1]{\vbox{\hsize=4.5in \parindent=0pt \emergencystretch=1in
\parshape 6
0.00in 4.50in
0.25in 4.00in
0.50in 3.50in
0.75in 3.00in
1.00in 2.50in
1.25in 2.00in
\leftskip=0pt plus 1fil \rightskip=0pt plus -1fil
\parfillskip=0pt plus 2fil
#1\par}}
\invpyr{\huge\bfseries
Here is a title that needs to wrap over several lines and
has short words}
然后您可以将其居中\vbox
或执行您想要的操作。
\leftskip
注意。我曾在某处见过使用和\rightskip
的技巧\parfillskip
,但我不记得在哪里了。
论文评审委员会是否会互相竞争,看谁能找到更荒谬的规则?
答案3
最终解决方案
根据 TH 的建议以及我从 Martin 的建议下从 ragged2e 包文档中了解到的内容,下面是我实现此命令的方式:
\newlength{\@headingTextWidth}
\newcommand{\centeredHeadingPar}[1]%
{%
\leavevmode\vbox{%
\hsize=4.5in
\parindent=0pt
\parfillskip=0pt
\emergencystretch=2em
%
\pretolerance=500
\tolerance=1000
\hyphenpenalty=100
\linepenalty=0
%
\settowidth{\@headingTextWidth}{#1}%
\ifdim\@headingTextWidth<4.5in%
% True case - the heading will be only one line.
% Add fils to the [left/right]skips to avoid distracting underful hbox complaints.
\leftskip=0pt plus 0.5fil
\rightskip=0pt plus 0.5fil
\else%
% False case - multiline heading.
% Match the rubber in the [left/right]skips to the pyramid steps to ensure that each
% successive line is shorter than the previous.
\leftskip=0pt plus 0.25in
\rightskip=0pt plus 0.25in
\fi%
%
#1%
%
\parshape=6 % account for a maximum of six lines - thereafter all will have the final width
0.00in 4.5in
0.25in 4.0in
0.50in 3.5in
0.75in 3.0in
1.00in 2.5in
1.25in 2.0in
}% \vbox
}% \centeredHeadingPar
我省略了格式化命令,以便应用有效的命令。这样,我就可以将其用于具有不同字体大小的不同级别的标题。通过将\leftskip
和\rightskip
橡皮擦与金字塔每个级别的台阶相匹配,可以确保每行都比下一行短,而无需潜在的巨大单词间空间。由于\parbox
现在的宽度与顶行的长度相匹配,因此该命令现在旨在用于居中环境。
现在只有两种情况会出现问题:(1)TeX 根本找不到合适的地方换行,而让一行悬在边缘处;(2)单个单词最终出现在最后一行,而左/右跳跃不能提供足够的延伸来填充整行,从而导致水平盒子不足。
如果整个练习的前提不是那么愚蠢(很难证明投入的时间是合理的),我相信可以解决上面提到的第二个问题,并摆脱所有硬编码的长度,这样金字塔步长和其他值就成为参数了。不过,我已经浪费了足够多的时间来完成这个丑陋的格式,所以我会克制自己。
答案4
\usepackage[newcommands]{ragged2e}