将段落的最后一个单词右对齐,并且 \obeylines

将段落的最后一个单词右对齐,并且 \obeylines

我正在使用的代码TeXBook将部分文本对齐到段落最后一行的右侧,或者如果段落最后一行没有空间,则对齐到下一行的右侧。(请参阅第 14 章第 106 页以及下面的实现。)

它工作得很好,除了当我在环境中使用 时有一段文本的情况\obeylines。这会把事情搞乱,因为\obeylines在每行(包括最后一行)的末尾插入一个段落分隔符,并且要右对齐的文本总是单独出现在一行上,即使前一行有空间。

\obeylines我可以通过在行末使用 来抑制该部分最后一行的段落分隔符来解决此问题%

但我想要一种不需要我这样做的自动化方法。

这是一个可以玩的 MWE。

zzsection和环境olsection模拟我在文档结构中使用的环境。我只想修改这两个环境中的代码,而不是环境中的文本。 可能olsection出现在其上方或下方的普通文本中。即,唯一需要解决的情况是当zzsection以 结尾时olsection环境结尾时。填充文本长度和内容都是任意的。希望这有意义……

在这个例子中,第三段是需要修改的。

\documentclass{article}

\usepackage{lipsum}

\newcommand{\zz}{%
  {\unskip\nobreak\hfil\penalty50
   \hskip2em\hbox{}\nobreak\hfil\textbf{Filler text}%
   \parfillskip=0pt \finalhyphendemerits=0 \par}}

\newenvironment{zzsection}{}{\zz}
\newenvironment{olsection}{\obeylines}{}

\begin{document}

\begin{zzsection}
  \lipsum[1]
\end{zzsection}

\begin{zzsection}
  \lipsum[5]
\end{zzsection}

\begin{zzsection}
  \begin{olsection}
    \lipsum[1]
  \end{olsection}
\end{zzsection}

\begin{zzsection}
  \begin{olsection}
    \lipsum[5]
  \end{olsection}
\end{zzsection}

\end{document}

更新

Henri Menke 的代码对我来说几乎是完美的。

我的实际文档\leftskip 1cmolsection环境中有一个。他的答案的最后一行没有考虑到这一点。即,这失败了:

\begin{zzsection}
  \begin{olsection}
    \leftskip 1cm
    Some text.
    Some text.
    Some text.
  \end{olsection}
\end{zzsection}

答案1

只需让 obelines 提前查看即可\end

如果前面可能有多个空行,则\end可能需要递归跳过这些空行。这很慢,因为它会逐个吸收标记。

\documentclass{article}

\usepackage{lipsum}

\newcommand{\zz}{%
  {\unskip\nobreak\hfil\penalty50
   \hskip2em\hbox{}\nobreak\hfil\textbf{Filler text}%
   \parfillskip=0pt \finalhyphendemerits=0 \par}}

% Loosely adapted from ConTeXt
%
% Two stage indirection via \obeylineshandler is such that we can change
% \obeyedline at some later stage.
\newcommand*\obeyedline{\par}
\newcommand*\obeylineshandler{\obeyedline}
{\catcode`\^^M=\active % these lines must end with %
  \protected\gdef\obeylines{\catcode`\^^M\active \let^^M\obeylineshandler}%
  \global\let^^M\obeylineshandler} % this is in case ^^M appears in a \write

% Look ahead for \end and skip any ^^M on the way there
\makeatletter
{\catcode`\^^M=\active % these lines must end with %
\gdef\obeylineend{%
    \@ifnextchar\end{}{%
        \@ifnextchar^^M{%
            \expandafter\obeylineend\@gobble}{\par}}}}
\makeatother

\newenvironment{zzsection}{}{\zz}
\newenvironment{olsection}{\let\obeyedline\obeylineend\obeylines}{}

\begin{document}

\begin{zzsection}
  \lipsum[1]
\end{zzsection}

\begin{zzsection}
  \lipsum[5]
\end{zzsection}

\begin{zzsection}
  \begin{olsection}
    \lipsum[1]

  \end{olsection}
\end{zzsection}

\begin{zzsection}
  \begin{olsection}
    \lipsum[5]
  \end{olsection}
\end{zzsection}

\end{document}

相关内容