将对象移动到右边距

将对象移动到右边距

我需要一个宏来将对象与右边缘对齐,如果在文本和对象之间留有空格,则在当前行对齐,否则在下一行对齐。在后一种情况下,其他材料不应与对象出现在同一行上。

右对齐插图

我的第一次尝试 ( \tmarksi) 似乎有效,但如果它出现在段落末尾,则会导致水平盒子未满警告(我不明白为什么)。第二次尝试 ( \tmarksii) 似乎插入了不必要的段落分隔符。因此,我在第三次尝试中尝试在本地设置\parskip为零,但这也不起作用。

这当然不应该很难;我遗漏了什么?

\documentclass{article}
\setlength\parindent{0pt}
\setlength\parskip{2cm} %For illustration purposes
%
\newcommand\tmarksi[1]{\hspace*{\fill}~\mbox{[#1]}\newline}
\newcommand\tmarksii[1]{\hspace*{\fill}~\mbox{[#1]}\vskip0pt}
\newcommand\tmarksiii[1]{\hspace*{\fill}~\mbox{[#1]}\bgroup\parskip=0pt\parindent=0pt\par\egroup}
%
\begin{document}
The quick brown fox jumps over the lazy dog. \tmarksi{1}
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over \tmarksi{1}
the lazy dog.
\end{document}

答案1

您可以使用 TeXbook 中的“Bourbaki 问题”的变体

\documentclass[convert,border=2]{standalone}

\newcommand{\tmark}[1]{%
  {{\unskip\nobreak\hfil\penalty50
  \hskip2em\vadjust{}\nobreak\hfil[#1]%
  \parfillskip=0pt \finalhyphendemerits=0 \par
  \penalty 10000 \parskip=0pt\noindent}}\ignorespaces}

\begin{document}
\begin{minipage}{150pt}\parindent=20pt\parskip=20pt
The quick brown fox jumps over the lazy dog.\tmark{1}
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over\tmark{1}
the lazy dog.

The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy \tmark{1}
the lazy dog.

The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy brown dog \tmark{1}

Another
\end{minipage}

\end{document}

这引入了段落分隔符,但也存在问题\noindent,并且\penalty 10000会阻止分页符。我还添加了\parskip=0pt以掩盖我们的踪迹。文本末尾和标记之间的最小间距为 2em,请尝试一下。

注意:\parskip在中设置minipage只是为了显示效果。还\parindent需要设置,否则为零。

在此处输入图片描述

为了在标记移至下一行时使文本右对齐,将第一个改为\hfil\hskip0pt为了使单词间距最小,请\hskip2em改为\space

以下版本实现了这一点,并且在标记移动到下一行时也避免了分页符:

\newcommand{\tmark}[1]{%
  {{\unskip\nobreak\vadjust{\nobreak}\hskip0pt\penalty50 \space
  \vadjust{}\nobreak\hfil[#1]%
  \clubpenalty=0 \widowpenalty=0 \brokenpenalty=0
  \parfillskip=0pt \finalhyphendemerits=0 \par
  \penalty 10000 \parskip=0pt\noindent}}\ignorespaces}

这是有代价的:我们对寡妇和俱乐部路线的控制较少,但正如弗兰克·米特尔巴赫在评论中所说,满足这两个必需品似乎很难。

答案2

我假设你的意思是\tmarksi如果它位于段落末尾,则会生成一个未满的水平盒子,而不是一个过满的水平盒子。出现这种情况的原因是,该\newline定义中的 总是在该段落中开始另一行,然后最后一行完全为空。这就是为什么在 LaTeX 中\\\newline被引入为行分隔符而不是行尾(尽管许多人尝试使用\\ \\来获取空行或额外空间)。

因此,这意味着您要么为这两种情况编写两个不同的命令,要么尝试这样的操作:

\newcommand\tmarksi[1]{\hspace*{\fill}~\mbox{[#1]}\penalty -9999 }

这里的不同之处在于,我使用的惩罚并不完全是“总是在这里中断”,因此段落末尾的最后一个断点将覆盖它。但是,在段落内,它通常就足够了,只要您不使用明确的\linebreak命令即可。所以请自行选择。

相关内容