4
votes

I'm trying to create a new environment in my LaTeX document where indentation in the next paragraph following the environment is suppressed.

I have been told (TeXbook and LaTeX source) that by setting \everypar to {\setbox0\lastbox}, the TeX typesetter will execute this at the beginning of the next paragraph and thus remove the indentation:

\everypar{\setbox0\lastbox}

So this is what I do, but to no effect (following paragraph is still indented):

\newenvironment{example}
  {\begin{list}
     {}
     {\setlength\leftmargin{2em}}}
  {\end{list}\everypar{\setbox0\lastbox}}

I have studied LaTeX's internals as well as I could manage. It seems that the \end routine says \endgroup and \par at some point, which may be the reason LaTeX ignores my \everypar setting. \global doesn't help either. I know about \noindent but want to do this automatically.

Example document fragment:

This is paragraph text. This is paragraph text, too.

\begin{example}
  \item This is the first item in the list.
  \item This is the second item in the list.
\end{example}

This is more paragraph text. I don't want this indented, please.

Internal routines and switches of interest seem to be \@endpetrue, \@endparenv and others. Thanks for your help.

9
AFAIK, the LaTeX source actually provides hooks for the problem at hand. It comments: "To suppress the paragraph indentation in text immediately following a paragraph-making environment ... [redefines \everypar and \par]" This is done in \@doendpe, which will be expanded if \@endpetrue -- but to no effect.glts

9 Answers

3
votes

I couldn't get anything to work without redefining \end, but I'm certainly no expert.

The following is quite hacky, but worked in my limited testing. Of course this will interfere with nested environments (you should be able to redefine \begin to restore the old \end if you have problems).

\newenvironment{example}{%
  \bgroup
  \let\oldend=\end
  \def\end##1{\oldend{##1}\csname @afterindentfalse\endcsname
                          \csname @afterheading\endcsname}
  \begin{list}{}
    {\setlength\leftmargin{2em}}
  }{%
  \end{list}
  \egroup
}
2
votes

Can't you avoid this by not having a blank line between your environment and the next line?

This is paragraph text. This is paragraph text, too.

\begin{example}
  \item This is the first item in the list.
  \item This is the second item in the list.
\end{example}
% (No blank line)
This is more paragraph text. I don't want this indented, please.
2
votes

Something as simple as this works for me:

\makeatletter
\newenvironment{example}{%
  \bgroup
    \list{}{}
}{%
    \endlist
    \@afterindentfalse
    \@afterheading
  \egroup
}
\makeatother

But, it doesn't work before the first \section (or \chapter, in the case of classes "book" and "report") is called. I don't know why.

1
votes

I tried the Ivan's answer, but it wasn't working for me. But I did get it working! Here's what I did:

\makeatletter
\renewenvironment{quotation}{% 
\bgroup%
\let\oldend=\end%
\def\end##1{\oldend{##1}\csname @afterindentfalse\endcsname%
                        \csname @afterheading\endcsname}%
\list{}{\listparindent 1.5em%
\itemindent    \listparindent%
\leftmargin 1.5em%               This controls the size of the indentation
\rightmargin   \leftmargin
\parsep        \z@ \@plus\p@}%      This line reduces inter-paragraph space to normal values.
\item\relax%
}{%
\endlist%%
\egroup%
}
\makeatother

The advantage to this is that it typesets your blockquotes very nicely, and removes the indentation from paragraph after the blockquote.

1
votes

You can do this without redefining \end

\makeatletter
\newenvironment{example}
   {\begin{list}
      {}
      {\setlength\leftmargin{2em}}}
   {\end{list}%
    \def\if@endpe{%
      \@doendpe
      \let\par\@@par
      \iffalse}}
\makeatother

Explanation

\end changes \everypar after expanding \endexample. To make things even more complicated it sets \par to restore \everypar{}. Appearently \@doendpe is ment to make sure that there is no indentation if the paragraph continues after the environment, but to restore normal behavior if there is a \par (or empty line) after the environment.

You may want to avoid changing \end because it would have to be changed at the begining of the environment and may therefore disturb nested environments. Luckily the definition of \end contains \expandafter\endgroup\if@endpe. We can use \if@endpe as a hook to inject our code to the outer scope. After the \endgroup \if@endpe is automatically restored.

0
votes

Include \@afterindentfalse\@afterheading at the end of your definition.

0
votes

I had the same problem. I just used this:

\noindent \newenvironment
-1
votes

You should not mess with the \everypar token list, unless you know exactly what you are doing. Use

\setlength{\parindent}{0pt}

to get rid of indenting in the whole document.

-2
votes

ending your environment with \noindent could help you