41

This question led to a new package:
noindentafter

There are a number of environments which I never want to follow up with an indented paragraph. itemize, enumerate, theorem, definition, etc. I know there are people who think this is bad style. But it's a personal preference. Those environments basically always end a paragraph for me, so the visual clue is not needed in my case.

I've found several similar questions, but none of them do what I need:

That third one was actually most useful, but appears to be unreliable for patching existing environments with. It doesn't seem to be working in my memoir document.

To be clear, I don't want to remove the actual paragraph break. That's a semantic concept. I just want to patch the document style so that paragraphs following certain environments remain unindented.

I've tried the following two 'solutions' (which use etoolbox for patching):

\newcommand*{\noindentnext}{\everypar{{\setbox\z@\lastbox}\everypar{}}}
\newcommand*{\NoIndentAfterEnv}[1]{\AfterEndEnvironment{#1}{\noindentnext}}
\newcommand*{\NoIndentAfterCmd}[1]{\apptocmd{#1}{\noindentnext}{}{}}

\NoIndentAfterEnv{itemize}
\NoIndentAfterEnv{theorem}
...

This one is loosely based on the third post from the list above. It sometimes works. It sometimes does nothing. I'm unable to predict when it will fail. The second:

\let\old@par\par
\newcommand*{\noindentnextpar}{\def\par{\let\par\old@par\par\noindent}}
\newcommand*{\NoParIndentAfterEnv}[1]{\AfterEndEnvironment{#1}{\noindentnextpar}}
\newcommand*{\NoParIndentAfterCmd}[1]{\apptocmd{#1}{\noindentnextpar}{}{}}

I invented this one myself. It breaks when the patched environment is not followed by a paragraph. It has also shown itself to inexplicably fail in other situations.

Once and for all, I'd like to have a reliable way to do this.

Let me give an example of what I need, just to be clear:

\NoIndentAfterEnv{itemize}

\begin{itemize}
    \item ...
\end{itemize}

This starts a new paragraph. Note the empty line. But it should not be indented.

But this paragraph \emph{should} be indented.
6
  • Sorry my first attempt was a big flaw. I tried \newcommand*{\noindentnext}{\def\par{\@@par\noindent\let\par\@@par}} but you have the same. What do you mean it breaks? May 4, 2013 at 17:05
  • Well, I'm not exactly sure. But I remember that I had to be careful in a lot of situations or I'd get errors. An example: I get a missing \item error if a proof environment ends while the augmented \par is still in effect. I also remember getting errors if several augmented environments followed each other without a paragraph inbetween, but I can't seem to reproduce this right now.
    – mhelvens
    May 4, 2013 at 17:19
  • I've made the following rather invasive patch to fix these errors: \let\@old@end\end\renewcommand{\end}[1]{\let\par\@@par\@old@end{#1}}. Seems like I shouldn't be able to get away with it, but I did.
    – mhelvens
    May 4, 2013 at 17:41
  • 3
    FWIW, ConTeXt provides an indentnext key to control the indentation after an environment. See this article on ConTeXt wiki for details. This is an old feature that works with MkII (pdftex/xetex) as well as MkIV (luatex).
    – Aditya
    Aug 2, 2013 at 14:51
  • The noindentafter package is broken with the latest latex version (may 2021), seems it has been broken since nov 2019. See this github issue and this SE TeX question for details and potential solutions.
    – Carl
    May 11, 2021 at 18:13

2 Answers 2

29
+200

You could make the following paragraph believe that it follows a heading where there's also no indent by appending \@afterindentfalse\@afterheading after the end of the environment. Package etoolbox provides the handy \AfterEndEnvironment which makes this an easy task. \@afterheading also temporarily sets \clubpenalty to \@M (10000), though. If you don't want this after the patched environment one could insert an adapted version of \@afterheading instead.

\documentclass{article}
% environment hooks and patching:
\usepackage{etoolbox}

\makeatletter
% uncomment the following if you don't want \clubpenalty\@M ...
% \let\nearly@afterheading\@afterheading
% \patchcmd\nearly@afterheading
%   {\@M}% original temporary setting for \clubpenalty replaced by ...
%   {\@clubpenalty}% ... or whichever value you deem right
%   {}{}
% ... and use \nearly@afterheading instead of \@afterheading here:
\newcommand*\NoIndentAfterEnv[1]{%
  \AfterEndEnvironment{#1}{\par\@afterindentfalse\@afterheading}}
\makeatother

\NoIndentAfterEnv{itemize}
% treat other environments you want to patch accordingly

% dummy text:
\usepackage{lipsum}
\begin{document}
\lipsum[1]

\begin{itemize}
  \item foo
  \item bar
\end{itemize}

\lipsum[1-2]
\end{document}

enter image description here

16
  • 1
    Wow. Pretty short! :-) It seems to work as expected in all cases that I could come up with. Furthermore, page breaks still seem to be allowed at the point of patching (why did you think they wouldn't be?) --- If there's one thing that keeps this solution from being perfect, it's the fact that the semantic distinction of paragraph breaks is now lost. A paragraph break is now applied even where I don't insert an empty line. This might affect documents that do other stuff at paragraph breaks. --- But that's just nitpicking. This solution will be just fine!
    – mhelvens
    Aug 2, 2013 at 16:02
  • 1
    »A paragraph break is now applied even where I don't insert an empty line.« -- But didn't you say Those environments basically always end a paragraph for me, anyway? ;)
    – cgnieder
    Aug 2, 2013 at 16:10
  • 2
    @lockstep that's funny... well, badges, who knows what they're good for, anyway ;)
    – cgnieder
    Aug 2, 2013 at 16:22
  • 2
    There, package finished. Until it is available on CTAN, you can find the code here.
    – mhelvens
    Aug 2, 2013 at 19:50
  • 3
    I think this is not quite robust as it changes the spacing if the \end{itemize} is immediately followed with a new section/subsection.
    – Jörg
    Apr 30, 2014 at 14:44
10

The correct way to unconditionally remove indentation after list environments (note that quotes and theorems are also based on list) seems to be to change the definition of \@doendpe, specifically, to remove the code where "\par is redefined to restore \everypar" (source2e). See What exactly does \@doendpe do? for details.

\documentclass{article}

\newtheorem{theorem}{Theorem}

\newcommand*{\sometext}{Hello, here is some text without a meaning. This
    text should show, how a printed text will look like at this place.
    If you read this text, you will get no information.}

\makeatletter
\def\@doendpe{%
  \@endpetrue
%  \def\par{% REMOVED
%    \@restorepar% REMOVED
%    \everypar{}% REMOVED
%    \par% REMOVED
%    \@endpefalse% REMOVED
%  }% REMOVED
  \everypar{%
    {\setbox\z@\lastbox}%
    \everypar{}%
    \@endpefalse
  }%
}
\makeatother

\begin{document}

\sometext

\begin{itemize}
\item \sometext
\end{itemize}

\sometext

\begin{quote}
\sometext
\end{quote}

\sometext

\begin{theorem}
\sometext
\end{theorem}

\sometext

\end{document}

enter image description here

Should you want to remove indentation only after specific list-based (!) environments, you can incorporate a new \noindentafter switch into \@doendpe and use etoolbox' \BeforeBeginEnvironment to set the switch to true for the respective environments.

\documentclass{article}

\newcommand*{\sometext}{Hello, here is some text without a meaning. This
    text should show, how a printed text will look like at this place.
    If you read this text, you will get no information.}

\newif\ifnoindentafter
\noindentafterfalse

\makeatletter
\def\@doendpe{%
  \@endpetrue
  \ifnoindentafter% ADDED
  \else% ADDED
    \def\par{%
      \@restorepar
      \everypar{}
      \par
      \@endpefalse
      \noindentafterfalse% ADDED
    }%
  \fi% ADDED
  \everypar{%
    {\setbox\z@\lastbox}%
    \everypar{}%
    \@endpefalse
    \noindentafterfalse% ADDED
  }%
}
\makeatother

\usepackage{etoolbox}
\BeforeBeginEnvironment{itemize}{\noindentaftertrue}

\begin{document}

\sometext

\begin{itemize}
\item \sometext
\end{itemize}

\sometext

\begin{enumerate}
\item \sometext
\end{enumerate}

\sometext

\end{document}

enter image description here

5
  • good try, but it doesn't work with amsthm. (although that isn't exactly what was requested.) Aug 2, 2013 at 14:53
  • @barbarabeeton I know that the AMS classes are special: tex.stackexchange.com/a/36835/510
    – lockstep
    Aug 2, 2013 at 14:58
  • @lockstep Great solution! It makes a lot of sense to take away the code that inserts the indentation rather than to add extra code to remove it again. And I see you even made it selective now! --- However, there are two reasons why I'm going with cgnieders solution: (1) It applies to any environment or command I want; not just list-based environments and (2) it's so much shorter and less invasive. --- Nonetheless, I found your answer very instructive.
    – mhelvens
    Aug 2, 2013 at 16:07
  • @mhelvens I was aware of (1), but since all your example environments were based on list, I decided to write an answer anyway.
    – lockstep
    Aug 2, 2013 at 16:09
  • @lockstep You're right. But as it happens, there's one command I still wanted to patch: \] :-)
    – mhelvens
    Aug 2, 2013 at 16:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .