\obeylines が有効な場合、ブロック間に自動的に垂直スペースを挿入する

\obeylines が有効な場合、ブロック間に自動的に垂直スペースを挿入する

講演用の原稿を LaTeX で書くとき、次のように、各行に 1 つの一貫した考えを簡潔に表現し、行間の関係を先頭のインデントで表現できるように、原稿の一部を のようにフォーマットし\obeylines\obeyspaces許可したい場合があります。

One thought introduced with a coherent phrase,
    followed by a subordinate phrase,
    and a coordinate subordinate phrase.

Then a second thought introduced ...

私が遭遇する問題は、上記の最後の行の前のように、連続する行のグループ (「段落」) の間に余分な垂直間隔を含めることです。これまでに思いついた最良のアドホック対策は、次のように各グループの末尾に追加できるパイプ記号を定義することです。... coordinate subordinate phrase.|

再定義コードは次のようになります。これを外部パッケージに配置しました。

\catcode`|=\active
\def|{\smallskip}

これはほぼ希望どおりに動作しますが、ソース テキスト全体にパイプ文字が含まれているため煩わしく、回避策が必要です。

そこで、余分なスペースのためのパイプ文字を必要とせずに、目的を達成する環境を定義しようとしました。これが、これまでのところ私が持っているものです...

\newenvironment{linewise}{%
\let\@oldpar=\par \let\par=\newpar \obeylines \let\par=\@oldpar}
{}

この方向で進めていく場合、 をどのように\newpar定義すればよいでしょうか? を使用しようとしました\\が、これが空の行の末尾 (\par通常は が挿入される場所) に自動的に挿入されると TeX が拒否し、前の段落が終了しません (文字が であるためだと\active思います)。これが私がやろうとしていることです。

私の知る限り、問題は、2 つ以上の改行文字での段落の分割が TeX の内部で行われ、2 つ以上の改行文字がある場合に挿入したい垂直スペースと、改行文字が 1 つしかない場合に挿入したい改行 (または新しい段落) を区別する調整を行うことができないことです。

それとも、これを実現するより良い方法があるのでしょうか?

答え1

\parを再定義するのではなく、 の後のアクティブな行末を再定義する必要があります\obeylines

\documentclass{article}
\newenvironment{linewise}
  {\parindent=0pt
   \obeyspaces\obeylines
   \begingroup\lccode`~=`\^^M
   \lowercase{\endgroup\def~}{\par\leavevmode}}
  {\ignorespacesafterend}

\begin{document}
\noindent X\leaders\hrule\hfill X

\begin{linewise}
One thought introduced with a coherent phrase,
    followed by a subordinate phrase,
    and a coordinate subordinate phrase.

Then a second thought introduced ...
\end{linewise}
Something after
\end{document}

ここに画像の説明を入力してください

答え2

しばらくして、私がやろうとしていたことに対するより良い解決策を見つけました。それは、 というコマンドを持つ eTeX から借用したものです\obeywhitespace。必要な定義 (明らかに機能しますが、かなり複雑に見えます) を、必要なときに使用できるパッケージにまとめました。関連するパッケージの内容を以下に記載します。

最後に というコマンドがあり\setblankskip、元の質問に示されているように「段落」間の間隔を調整できることに注意してください。

また、この動作は と呼ばれる環境内で提供されることにも注意してくださいlinewise。残る唯一の厄介な点は、linewise環境内の最後の改行が空白の出力行に反映されることです。これは、最後の改行の前に を置くことで回避できます%

\def\makeactive#1{\catcode`#1 = \active \ignorespaces}%
\def\gobble#1{}%
\newskip\blanklineskipamount
\blanklineskipamount = -.8\baselineskip
\begingroup
   \makeactive\^^M \makeactive\ % No spaces or ^^M's from here on.
\gdef\obeywhitespace{%
\makeactive\^^M\def^^M{\par\futurelet\next\@finishobeyedreturn}%
\makeactive\ \def {\ }%
\aftergroup\@removebox%
\futurelet\next\@finishobeywhitespace%
}%
\gdef\@finishobeywhitespace{{%
\ifx\next %
\aftergroup\@obeywhitespaceloop%
\else\ifx\next^^M%
\aftergroup\gobble%
\fi\fi}}%
\gdef\@finishobeyedreturn{%
\ifx\next^^M\vskip\blanklineskipamount\fi%
\indent%
}%
\endgroup
\def\@obeywhitespaceloop#1{\futurelet\next\@finishobeywhitespace}%
\def\@removebox{%
   \setbox0 = \lastbox
   \ifdim\wd0=\parindent
     \setbox2 = \hbox{\unhbox0}%
     \ifdim\wd2=0pt
       \ignorespaces
     \else
       \box2 % Put it back: it wasn't empty.
     \fi
   \else
      \box0 % Put it back: it wasn't the right width.
   \fi
}%
\newenvironment{linewise}{\begingroup\obeywhitespace}{\endgroup}%
% By default, a blank line will result in .2\baselineskip.  This allows
% other values to be set
\RequirePackage{calc}
\newcommand{\setblankskip}[1]{\setlength{\blanklineskipamount}{-\baselineskip+#1}}

関連情報