Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Sometimes as I write a manuscript in LaTeX for speaking, I want to format parts of it as \obeylines and \obeyspaces permit, so that a single coherent thought is expressed compactly on each line, and relationships between lines can be expressed with leading indentation, like this:

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

Then a second thought introduced ...

The problem I run into is including the extra vertical spacing between groups of contiguous lines ("paragraphs"), as before the last line above. The best ad-hoc measure I have come up with so far is to define the pipe symbol, which can be added to the end of each group, like this: ... coordinate subordinate phrase.|

The redefinition code looks like this, which I have placed into an external package.

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

This works more or less as desired, but the pipe characters throughout my source text are irritating, and obviously a work-around.

So I have been trying to define an environment that accomplishes what I want, without requiring the pipe character for the extra spacing. This is what I have so far...

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

If I proceed in this direction, how should \newpar be defined? I have tried using \\, but TeX balks when this is inserted automatically at the end of an empty line (where \par is normally inserted), and it does not end the previous paragraph (because the character is \active, I presume), which is what I'm trying to do.

As far as I can tell, the problem is that the division between paragraphs at two or more return characters takes place in TeX's mouth, where I can't make any adjustments that would distinguish between the vertical space I want to insert where there are two or more return characters, and the line break (or new paragraph) I want to insert when there is only one.

Or is there a better way to accomplish this?

share|improve this question
    
Welcome to TeX.sx! –  texenthusiast Apr 5 '13 at 18:49
1  
is there any reason why a line \begin{verbatim} above the block and \end{verbatim} just after the block won't suffice? that does exactly what you describe, obeying both spaces and line endings, including those for blank lines. –  barbara beeton Apr 5 '13 at 19:20
1  
Yes, the verbatim environment does a lot more than I really want to do when it suppresses the normal meaning of other LaTeX commands. –  ben y'akov Apr 7 '13 at 0:44

2 Answers 2

You shouldn't redefine \par, but the active end-of-line after \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}

enter image description here

share|improve this answer
    
Amazing. It works perfectly, but I don't understand how. It reassigns and uses only the lower case value (\lccode) of the tilde (~). Is that the active end-of-line? –  ben y'akov Apr 7 '13 at 0:49
    
I also don't understand why \begingroup and \endgroup are needed. And it appears that \def~ is not isolated from the assigned value because the closing brace (}) from the argument of \lowercase is not a group delimiter, as distinguished in the TeXbook on the middle of p. 20. Is that right? –  ben y'akov Apr 7 '13 at 0:59
    
@beny'akov The \begingroup with \endgroup trick is used to give a meaning to the active end-of-line without needing to activate it at definition time. You can find it in many answers in the site. For instance in this answer of mine –  egreg Apr 7 '13 at 9:05
up vote 0 down vote accepted

After some time, I found a better solution to what I was trying to do. It borrows from eTeX, which has the command \obeywhitespace. I've put the needed definitions (which clearly work, though some look quite involved) into a package I can use when needed. I'll include the relevant package contents below.

Note that there's a command at the end called \setblankskip, which allows an adjustment to the spacing between "paragraphs" as shown in the original question.

Note also that this behavior is provided within an environment called linewise. The only remaining irritation is that the final newline within the linewise environment will be reflected in a blank output line. This can be avoided by preceding that final newline with a %.

\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}}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.