
Иногда, когда я пишу рукопись в 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}}