14

Sometimes when creating environments, you want to ensure that they always

  • start new paragraph when two environments appear immediately after one another
  • eat up spaces
  • generally idiot-proof (which, dare I say, might also be called "fully LaTeX compatible")

I have seen a few techniques. Are there any recommended ways of doing this to avoid trouble?

\documentclass{article}
\usepackage{fontspec}
\usepackage{lipsum}

\newenvironment{test}
  {\par\noindent}% <-- before env hook
  {}% <-- after env hook

\begin{document}
\begin{test}
\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}
\begin{test}
\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}

\begin{test}
\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}
\end{document}

Ideal Environment

This one can handle \begin{test}\end{test}\begin{test}\end{test} back to back. I used \par\noindent in the before environment hook. Is this the right way to do this? Based on this answer https://tex.stackexchange.com/a/22853/13552, it seems that I would also need \leavevmode. Could somebody clarify this and any other tips that are "good practice". enter image description here

Without Auto-new paragraphs (\par in before hook), without \noindent

enter image description here

Without Auto-new paragraphs (\par in before hook), with \noindent

enter image description here

Related

2 Answers2

15

If you want that the environment starts a new paragraph with no indentation and also ignores spaces after it,

\newenvironment{test}
 {\par\noindent\ignorespaces}
 {\ignorespacesafterend}

The missing \ignorespaces is the cause for the small spaces in the third example. This happens because \noindent starts a new paragraph (note that \par only ends a paragraph) and so the space after \begin{test} (generated by the end-of-line) is not ignored.

egreg
  • 1,121,712
  • Would you care to comment on \leavevmode as explained in the linked answer https://tex.stackexchange.com/questions/22852/function-and-usage-of-leavevmode/22853#22853? – Jonathan Komar Jun 20 '17 at 14:20
  • @JonathanKomar There's no need for \leavevmode; that answer deals with a completely different situation. – egreg Jun 20 '17 at 14:23
11

It is almost always best to avoid starting horizontal mode in the begin code of the environment, so do not use \noindent or \leavevmode etc.

The usual way is as a trivlist, the exact parameters of which can be customised, and this is how center quote verbatim etc work.

Note your test file makes overfull lines as the fbox adds space around a parbox that is already full width.

enter image description here

\documentclass{article}
%\usepackage{fontspec}
\usepackage{lipsum}

\newenvironment{test}
  {\trivlist{}\item\relax}% <-- before env hook
  {\endtrivlist}% <-- after env hook

\begin{document}

\noindent X\dotfill X

\begin{test}
\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}
\begin{test}
\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}

\begin{test}
\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}
\end{document}

To see one (of many) disadvantages to starting hmode in the environment definition try a test such as

\begin{test}

\fbox{\parbox{\linewidth}{\lipsum[1]}}
\end{test}

with the definition here and compare with other definitions. Environments that start a paragraph ought to silently accept the environment content starting with a paragraph break.

ShreevatsaR
  • 45,428
  • 10
  • 117
  • 149
David Carlisle
  • 757,742
  • 1
    (I will probably delete as this is a bit off-topic): can you check https://gist.github.com/jfbu/2f3d04414359f716f98ea64dac91eb0e –  Jun 20 '17 at 14:54
  • 1
    sorry I meant to add "please" but I hit return key too early and also I wanted to say I have other examples with minipage embedded in an environment when the minipage is fullwidth and the environement doesn't do ignorespacesafterend –  Jun 20 '17 at 14:55
  • 1
    @jfbu shouldn't need ignorespacesafterend here (I would if I had used \begin{trivlist} \end{trivlist} – David Carlisle Jun 20 '17 at 16:41
  • I have added a comment at the gist place (I don't know if the @davidcarlisle pings you there). About this ignorespacesafterend, not sure we are talking about same thing so I put it into new gist. Here is what I mean: https://gist.github.com/jfbu/87e5bcfcc64c4199a942be1d5d51c608 –  Jun 20 '17 at 19:20
  • @ShreevatsaR thanks, tricky language, English, it seems:-) – David Carlisle Jun 20 '17 at 20:38
  • @DavidCarlisle :-) – ShreevatsaR Jun 20 '17 at 21:50
  • (I have added comments at the two gists above, but as pinging from gist does not work, I have been pulling you there into not very convenient way to chat -- just mentioning here my last updates, then I will not harass you anymore ;-) ) –  Jun 21 '17 at 09:39
  • Relevant here about \trivlist: https://tex.stackexchange.com/a/47069/13552 – Jonathan Komar Jun 28 '17 at 09:56