Вставка автоматического вертикального пробела между блоками при активном \obeylines

Вставка автоматического вертикального пробела между блоками при активном \obeylines

Иногда, когда я пишу рукопись в LaTeX для выступления, мне хочется отформатировать ее части так \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быть определено? Я пробовал использовать \\, но TeX тормозит, когда это автоматически вставляется в конец пустой строки (где \parобычно вставляется), и это не завершает предыдущий абзац (потому что символ — \active, я полагаю), что я и пытаюсь сделать.

Насколько я могу судить, проблема в том, что разделение абзацев двумя или более символами возврата происходит в TeX, где я не могу внести никаких изменений, которые бы различали вертикальный пробел, который я хочу вставить там, где есть два или более символа возврата, и разрыв строки (или новый абзац), который я хочу вставить, когда есть только один.

Или есть лучший способ сделать это?

решение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}}

Связанный контент