假设我们希望将属性设置为右对齐,并且如果有足够的空间(至少多出 2em),则将其放在同一行。如果没有,则应将它们设置在下一行,也右对齐。如何编写一个宏来\whence
处理这个问题?我下面的尝试无法确定是否有空间,并且需要手动\\
。
\documentclass{article}
\usepackage{showframe}
\textwidth=1.5in
\newcommand\whence[1]{\unskip\mbox{}\hskip2em\hfill#1}
\begin{document}
% attribution to the right, same line
all is water
\whence{thales}
% no room!
sum res cogitans
\whence{descartes}
% take new line
sum res cogitans\\
\whence{descartes}
\end{document}
答案1
这进球线包提供了\linegoal
,即行的剩余长度。将要放置在剩余行中的内容的宽度(通过\settowidth
)与行的剩余长度进行比较可以决定是否需要换行。(我不认为 2em 规则是必要的,但无论如何还是实现了它。)text\whence{ text}
您也可以使用text \whence{text}
,只要确保不要将其texttext
作为输出即可。
\documentclass{article}
\usepackage{showframe}
\usepackage{linegoal}
\newdimen\remaininglength
\newlength\stuffwidth
\textwidth=1.5in
\newcommand\whence[1]{%
\setlength\remaininglength\linegoal%
\settowidth\stuffwidth{#1}%
\ifdim\stuffwidth<2em\relax%
\setlength\stuffwidth{2em}%
\fi%
\ifdim\stuffwidth>\remaininglength\relax%
\\ \unskip\mbox{}\hskip2em\hfill#1%
\else%
\unskip\mbox{}\hskip2em\hfill#1%
\fi%
}
\begin{document}
% attribution to the right, same line
all is water\whence{ thales}
% no room!
sum res cogitans\whence{ descartes}
% take new line
sum res cogitans\\
\whence{ descartes}
\end{document}
答案2
您可以通过以下宏来执行此操作:
\def\whence #1\par{\unskip
\nobreak\hfill\penalty71\hskip2em\hbox{}\nobreak\hfill \hbox{#1}\par}
如果 whence 文本无法放进同一行,则该行将在 处换行\penalty71
。前一行必须\nobreak\hfill
填充空格,下一行有\hbox{}\nobreak\hfill \hbox{text}
。这会将文本移至右边距,因为\parfillskip
只有\hfil
(有一个 el,没有双 el)。
如果 whence 文本 +2em 适合同一行,则此行有
\nobreak\hfill\penalty71\hskip2em\hbox{}\nobreak\hfill\hbox{text}
\hfill
由于这里有两个“s”,因此文本会移到右边距。
答案3
该类memoir
有一个,如果行上有足够的空间,则\sourceatright[<length>]{<text>}
使用时会将其排版为右对齐,否则将其排版为下一行的右对齐。可选(默认为 2em)是 之前的最小空间。如果我没记错的话,它基于 Knuth 的代码<text>
<space>
<text>
TeXbook. 它相当于您的\whence
。
% whenceprob.tex SE 586319
\documentclass{article}
\usepackage{showframe}
\textwidth=1.5in
% \newcommand\whence[1]{\unskip\mbox{}\hskip2em\hfill#1}
% from the memoir class
\makeatletter
\newcommand*{\sourceatright}[2][2em]{{%
\unskip\nobreak\hfil\penalty50
\hskip#1\hbox{}\nobreak\hfil{#2}
\parfillskip\z@\finalhyphendemerits=0\par}}
\makeatother
\let\whence\sourceatright
\begin{document}
% attribution to the right, same line
all is water
\whence{thales}
% no room!
sum res cogitans
\whence{descartes}
% take new line
sum res cogitans\\
\whence{descartes}
\end{document}