7

After compilation of some legacy code including the noindentafter package, I just noticed that they produce a warning which never came up before:

Package noindentafter Warning: Patching `\end' failed!
(noindentafter)                `\NoIndentAfter...' commands won't work.

I think this message is the result of an update of the etoolbox package (which is used in noindentafter) since its revision history notes say:

2.5g 2019-09-09 Update patching of \begin and \end in advance of LaTeX kernel changes

Perhaps that patch has given rise to some incompatibility with noindentafter. Here's an MWE:

\documentclass[11pt]{article}
\usepackage{noindentafter}
\NoIndentAfterEnv{enumerate}
\setlength{\parindent}{3em}% % To make the indentation clearly visible 

\begin{document}

\begin{enumerate}
\item[(1)]  Some text.
\item[(2)]  Some other text.
\end{enumerate}

Text that should not be indented.
\end{document}

And here's the result:

enter image description here

Any hint is welcome!

chandra
  • 230

2 Answers2

7

The noindentafter wants to patch \end (which is a bad thing to do), in order to inject some code. With the last release of LaTeX, \end has become robust, but in a rather peculiar way that makes xpatch useless in this case.

The package should do

\expandafter\patchcmd\csname end \endcsname{%
  \if@ignore\@ignorefalse\ignorespaces\fi%
}{%
  \if@ignore\@ignorefalse\ignorespaces\fi%
  \csuse{@noindent@#1@hook}%
}{}{%
  \PackageWarningNoLine{noindentafter}{%
    Patching `\string\end' failed!\MessageBreak%
    `\string\NoIndentAfter...' commands won't work%
  }%
}

You can do it yourself, but you have to live with the innocuous warning until the package is updated.

\documentclass[11pt]{article}
\usepackage{noindentafter}
\NoIndentAfterEnv{enumerate}
\setlength{\parindent}{3em}% % To make the indentation clearly visible 

\makeatletter
\expandafter\patchcmd\csname end \endcsname{%
  \if@ignore\@ignorefalse\ignorespaces\fi%
}{%
  \if@ignore\@ignorefalse\ignorespaces\fi%
  \csuse{@noindent@#1@hook}%
}{}{%
  \PackageWarningNoLine{noindentafter}{%
    Patching `\string\end' failed!\MessageBreak%
    `\string\NoIndentAfter...' commands won't work%
  }%
}
\makeatother

\begin{document}

\begin{enumerate}
\item[(1)]  Some text.
\item[(2)]  Some other text.
\end{enumerate}

Text that should not be indented.
\end{document}

enter image description here

I'm not sure about the usefulness of the package, as it's much easier not to leave a blank line after \end{enumerate} and obtain exactly the same output.

\documentclass[11pt]{article}
\setlength{\parindent}{3em}% % To make the indentation clearly visible

\begin{document}

\begin{enumerate}
\item[(1)]  Some text.
\item[(2)]  Some other text.
\end{enumerate}
Text that should not be indented.

\end{document}
egreg
  • 1,121,712
  • Thank you very much for the solution and the explanation. I actually find the package quite useful because it provides a generic way to suppress indentations after certain (types of) environments -- which protects against local input errors. I have brought the problem to the attention of the author of noindentafter, so hopefully there will be an update of the package. – chandra Oct 30 '19 at 19:06
  • @egreg: Thanks for this! I haven't used LaTeX for quite a while, so I haven't been keeping up to date. - As for the wisdom of patching \end, I agree, and your point is demonstrated by this very bug. :-) But I don't know a clean way to achieve the same result, and I do think the package is useful. At least for us folks who like to separate formatting from content. – mhelvens Nov 01 '19 at 12:34
  • @mhelvens You could do the fix and declare the package “no longer maintained” – egreg Nov 01 '19 at 12:43
  • Agreeing with egreg. @mhelvens: the package is broken since two years and is still on CTAN. There's also pull requests at your repo (un-accepted, un-commented) since some time, allegedly (I haven't tested myself) fixing the issues. Please at least take some actions to have it removed from CTAN, if nothing else. – Carl May 11 '21 at 18:35
4

I found out that its not necessary anymore to patch \end directly. The etoolbox-macro \AfterEndEnvironment can do the very same now. The following code works for me, copied from the noindentafter-package.

\newcommand*\@NoIndentAfter{%
    \@ifnextchar\par{%
        \def\par{%
            \everypar{\setbox\z@\lastbox\everypar{}}%
            \@restorepar%
        }%
    }{}%
}
\newrobustcmd*{\NoIndentAfterThis}{\@NoIndentAfter\par\par}

\AfterEndEnvironment{enumerate}{\NoIndentAfterThis}

I assume this works only for the updated version of \end (see @egregs answer about the update), because the noindentafter package author explicitely writes:

The package etoolbox provides the command \AfterEndEnvironment which creates a hook executed at a very late point inside the \end command. However, this hook is still located before \ignorespaces, which is too early to properly suppress the indention after an environment. Therefore another hook is now added to \end using \patchcmd. This new hook puts new code at the very end.

However, this doesn't seem to be true anymore.

Qw3ry
  • 195
  • I did write an email to the package author about this. Maybe we see a fix in the package soon. – Qw3ry Nov 08 '19 at 09:08