![仅当行末空间不足时才分段](https://linux22.com/image/312509/%E4%BB%85%E5%BD%93%E8%A1%8C%E6%9C%AB%E7%A9%BA%E9%97%B4%E4%B8%8D%E8%B6%B3%E6%97%B6%E6%89%8D%E5%88%86%E6%AE%B5.png)
我想写这样的源代码
Lorem ipsum dolor sit amet. \smallnote{Smaller.}
并使其渲染
- 如果有足够的空间容纳 a
\parindent
加上 the 的开头\smallnote
(第一个单词,或者可能到第一个连字符点,使用较小的字体),那么就会有一个\parindent
大小的空格,然后注释将出现在同一段中; - 或者,如果没有空间,注释将完全出现在新段落中(或者在换行符后,
\parindent
新行的开头有一个空格)。
下面的插图(我伪造的)说明了我的意思:
如何利用 TeX 间距来实现这一点?
答案1
您可以使用隐藏的显示数学来测量最后一行:
\documentclass{article}
\def\a{One two three four five six. }
\def\b{\a zzzzzz \a gg \a gg }
\def\smallnote#1{\xsmallnote#1 \zsmallnote}
\def\xsmallnote#1 #2\zsmallnote{%
{\abovedisplayshortskip0pt\abovedisplayskip0pt
\belowdisplayshortskip0pt\belowdisplayskip0pt
$$\global\dimen1\predisplaysize$$\par}%
\sbox0{\small#1}%
\ifdim\dimexpr\dimen1-2em+\parindent+\wd0>\linewidth
\typeout{^^J!!! not enough room on \the\inputlineno^^J}%
\vskip-\baselineskip
{\small #1 #2\par}%
\else
\nobreak
\vskip-\glueexpr\baselineskip+\parskip\relax
\typeout{^^J!!! is enough room on \the\inputlineno^^J}%
{\small\vskip-\baselineskip\hspace*{\dimen1}#1 #2\par}
\fi}
\begin{document}
\b\b\smallnote{verylongword two three four five six seven eight
AAA BBB CCC DDD EE FF GG}
\bigskip
\b\b\a zz zz\smallnote{verylongword two three four five six seven eight}
\bigskip
\b\b\smallnote{verylongword two three four five six seven eight
AAA BBB CCC DDD EE FF GG with a long multiline not \b\b}
\end{document}
答案2
这个问题让我想起了“数学评论您可以在TeXbook(第二段双重危险弯道):事实上,\predisplaysize
我不会使用不必要的复杂且最重要的是本质上不安全的测试,而是会使用这种方法,因为它更加直接和可靠。
\predisplaysize
188 页第二段(双重危险弯曲)解释了为什么不能信任 的值测试。特别是,对于 e-TeX,只需激活该\lastlinefit
功能就会导致此测试失败。
在下面的代码中,\cleverparindentspace
定义了一个名为的命令:您可以使用此命令在当前段落中插入一个宽度为 的空格,\parindent
这个空格非常“聪明”,因为它会在空格后面的文本无法完全容纳在同一行的剩余部分时开始一个新行 - 如果我理解得没错的话,这正是您所问的。无论如何,一旦您掌握了大致的概念,您就可以根据需要微调此命令;特别是,您可以通过更改 的值来校准 TeX 选择“新行”替代方案的倾向\penalty
。代码还演示了\predisplaysize
测试的不可靠性。
\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\newcommand*{\cleverparindentspace}{%
\unskip
\nobreak \hfil \penalty1000 \hfilneg \indent
}
\lastlinefit = 750
\begin{document}
One two three four five six seven eight. Some words. Some more words. How
long is this going to last? One two three four five six seven eight. This is
incredibly boring, isn't it? (That was actually a quotation from \textsl{The
\TeX book}.) One two three four five six seven eight.\cleverparindentspace
{\footnotesize\bfseries Here it is!}
One two three four five six seven eight. Some words. Some more words. How
long is this going to last? One two three four five six seven eight. This is
incredibly boring, isn't it? (That was actually a quotation from \textsl{The
\TeX book}.) One two three four five six seven eight. With a few words
added.\cleverparindentspace {\footnotesize\bfseries Here it is!}
One two three four five six seven eight. Some words. Some more words. How
long is this going to last? One two three four five six seven eight. This is
incredibly boring, isn't it? (That was actually a quotation from \textsl{The
\TeX book}.) One two three four five six seven eight. With some more words
added.\cleverparindentspace {\footnotesize\bfseries Here it is!}
One two three four five six seven eight. Some words. Some more words. How
long is this going to last? One two three four five six seven eight. This is
incredibly boring, isn't it? (That was actually a quotation from \textsl{The
\TeX book}.) One two three four five six seven eight. This one is just a tiny
bit longer:~a.\cleverparindentspace {\footnotesize\bfseries Here it is!}
% But consider the following:
One two three four five six seven eight. Some words. Some more words. How
long is this going to last? One two three four five six seven eight. This is
incredibly boring, isn't it? (That was actually a quotation from \textsl{The
\TeX book}.) One two three four five six seven eight. This one is just a tiny
bit longer: a.\cleverparindentspace {\footnotesize\bfseries Here it is!}
% You shouldn't trust \predisplaysize:
One two three four five six seven eight. Some words. Some more words. How
long is this going to last? One two three four five six seven eight. This is
incredibly boring, isn't it? (That was actually a quotation from \textsl{The
\TeX book}.) The pre-display line.
$$\verb"\predisplaysize"=\mbox{\the\predisplaysize}$$
\end{document}
输出:
答案3
如果不在内部进行测量,就不可能真正可靠地测量段落的最后一行\vbox
。
这是一个带有环境的解决方案。
\documentclass{article}
\newenvironment{addsmallnote}
{\par\edef\tpd{\the\prevdepth}\setbox0=\vbox\bgroup\prevdepth=\tpd}
{}
\makeatletter
\newcommand{\smallnote}[1]{\unskip\do@smallnote#1 \@nil}
\def\do@smallnote#1 #2\@nil{%
\par
\setbox2=\lastbox
\setbox2=\hbox{\unhbox2\unskip}% remove the \parfillskip glue
\setbox4=\hbox{\itshape#1\/}%
\ifdim\dimexpr\wd2+\wd4+\parindent>\hsize
\nointerlineskip\box2
\nobreak
{\interlinepenalty=\@M \footnotesize\itshape #1 #2\par}
\else
\parindent=\dimexpr\parindent+\wd2
\nointerlineskip\box2
\nobreak
{\interlinepenalty=\@M \footnotesize\itshape #1\vadjust pre{\vskip-\baselineskip} #2\par}
\fi
\egroup
\unvbox0
}
\makeatother
\begin{document}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test.
\begin{addsmallnote}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test.
\smallnote{Here is a small note}
\end{addsmallnote}
\begin{addsmallnote}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. A test.
\smallnote{Here is a small note}
\end{addsmallnote}
\begin{addsmallnote}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test.
\smallnote{Here is a small note that runs over and over in order to
fill much more than just the rest of a line and part of the next
line, I hope this is sufficient.}
\end{addsmallnote}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test.
\end{document}
最后一行被拆分、重新装箱并测量。然后根据其长度和注释中第一个单词的长度做出决定。如果第一个单词(加上 parindent)不适合,则在 处正常设置一个新段落\footnotesize
,否则注释的 parindent 等于正常 parindent 加上最后一行的宽度;\baselineskip
插入一个等于 的负跳过来掩盖我们的踪迹。
段落和注释之间不能有分页符,直到注释本身完成为止。
答案4
在这里,我将\kern
大小\parindent
和小纸条的第一个单词放入一个框中(以将它们放在一起),然后跟上纸条的其余部分。\kern
如果需要,我还会在之前留出一个停顿。
我做了一张小纸条\bfseries
只是为了帮助解决它。
根据 Gustavo 的评论进行编辑,\hfil
在 之前插入一个\allowbreak
,这样换行符会导致小注释之前出现不规则的结尾。
\documentclass{article}
\newcommand\smallnote[1]{\smallnotehelp\expandafter\kern\the\parindent#1\relax}
\def\smallnotehelp#1#2\relax{\hfil\allowbreak%
{\bfseries\small\mbox{#1}#2}}
\begin{document}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a big test.%
\smallnote{here is the small note}
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. This is a test.
This is a test. This is a test. This is a test. A test.%
\smallnote{here is the small note}
\end{document}