11

I have document with custom environment myenv which left margin is 4em.

\documentclass{book}
\usepackage{lipsum}

\newenvironment{myenv}{
\setlength{\leftskip}{4em}
}


\begin{document}

\lipsum[1-2]

\begin{myenv}

Vertical space should be here.

\lipsum[3-5]

Vertical space should be here.

\end{myenv}

\lipsum[6]

\end{document}

I want to add vertical space around this environment - that is before/above and after/below. Most straightforward, but at the same time labor-intensive, way to accomplish this that I know of is:

\begin{document}

\lipsum[1-2]

\begin{myenv}

\vspace{2em}

\lipsum[3-5]

\vspace{2em}

\end{myenv}

\lipsum[6]

\end{document}

Since I want to be able to change this vertical space without changing vertical spaces in rest of the document, I use macro:

\documentclass{book}
\usepackage{lipsum}

\newenvironment{myenv}{
\setlength{\leftskip}{4em}
}

\def \myvspacemacro{
\vspace{2em}
}


\begin{document}

\lipsum[1-2]

\begin{myenv}

\myvspacemacro{}

\lipsum[3-5]

\myvspacemacro{}

\end{myenv}

\lipsum[6]

\end{document}

Is there any easier and faster way of doing this? Ideally, I would like to set length of top vertical space and bottom vertical space for environment same way as I set leftskip value. Is it possible? There are 2 similar questions: Proper way of vertical spacing before/after environments, Vertical space before and after custom environment, but none of them seems to solve situation like mine.

Simply put, I want to achieve same effect as I would achieve in HTML/CSS by using margin-top and margin-bottom properties.

I also tried to add \vspace to my environment definition, but it only adds margin on top of environment and leaves no margin below environment.

\documentclass{book}
\usepackage{lipsum}

\newenvironment{myenv}{
\vspace{2em}
\setlength{\leftskip}{4em}
}

\begin{document}

\lipsum[1-2]

\begin{myenv}

\lipsum[3-5]

\end{myenv}

\lipsum[6]

\end{document}
1
  • 2
    You should never set \leftskip directly in latex, it will cause any nested list or display environment to be misplaced. Always use a list for this. Also you normally ant to use \addvspace rather than \vspace so the space combines with other display environments. (and you have loads of missing % at ends of lines:-) Commented Feb 1, 2014 at 18:47

3 Answers 3

4

How about this? Note that an \newenvironment has three mandatory arguments: the name, the pre-code, and the post-code. Also the line-ending % signs are often required to prevent stray spaces from being introduced (they are not needed for this example, but I place them there as a best practice).

EDITED in response to Barbara's comment and using cgnieder's suggestion. I verified that extra space is no longer added by having the environment start at the top of a page. Thanks to them both.

Further EDIT. David correctly points out that playing with \leftskip is dangerous. I tried to allay his concerns by defining it as a change, not in absolute terms, but that, apparently is not sufficient. Thinking I will leave it to the experts, I will delete my answer... which I can only do once the OP unaccepts it.

\documentclass{book}
\usepackage[nopar]{lipsum}
\newenvironment{myenv}{%
 \par%
 \addtolength{\leftskip}{4em}%
 \vspace{2em}%
}{%
 \par%
 \addtolength{\leftskip}{-4em}%
 \vspace{2em}%
}
\begin{document}
\lipsum[1-2]
\begin{myenv}
\lipsum[3-5]
\end{myenv}
\lipsum[6]
\end{document}
16
  • 2
    the starred version of \vspace will not disappear at the beginning of a page. if a new environment beginning with (unstarred) \vspace happens to start somewhere in the middle of a page, it doesn't matter whether what comes next in the environment is a paragraph or something else; the space will not disappear. (similarly, a starred \hspace is needed only if it's important to preserve the extra space at the beginning of a line.) in general, the extra vertical space is not wanted when the environment breaks from one page to the next, and the space would fall at the top of the page. Commented Feb 1, 2014 at 15:56
  • 3
    @Rafal they are mandatory! If you remove the blank line between your environment definition and the next \def you'll get an error because then \def is taken as post-code. Right now the \par is taken that is inserted implicitly by two consecutive end-of-lines
    – cgnieder
    Commented Feb 1, 2014 at 17:54
  • 2
    @Rafal your definition has \newenvironment{myenv}{...} followed by and end-of line + an empty line = two end-of-lines. TeX inserts a \par if there are two consectutive end-of lines so this is equivalent to \newenvironment{myenv}{...}\par. This \par is taken as end-code as if you had written \newenvironment{myenv}{...}{\par} => you were lucky
    – cgnieder
    Commented Feb 1, 2014 at 18:02
  • 1
    see my comment on the question:-) Commented Feb 1, 2014 at 18:52
  • 2
    It's for the best. If the accepted answer was changed it would presumably mean @egreg got the points and that would be a disaster:-) Commented Feb 1, 2014 at 19:45
8

Use the standard LaTeX list:

\documentclass{book}
\usepackage{lipsum}

\newenvironment{myenv}
  {\list{}{%
    \leftmargin=4em
    \topsep=2ex
    \parsep=\parskip
    \listparindent=\parindent
    \itemindent=\parindent
  }\item\relax}
  {\endlist}


\begin{document}

\lipsum[2]

\begin{myenv}
\lipsum[3-4]
\end{myenv}

\lipsum[6]

\end{document}

Adjust the parameters to suit your taste.

enter image description here

12
  • 1
    This works, but using list in this context is a bit bizarre and semantically wrong (in my opinion). Is there any way to control bottom margin with this solution? From code I can't tell how it is determined other than taking default value from list.
    – Rafal
    Commented Feb 1, 2014 at 17:18
  • 1
    @Rafal Why should it be wrong? It's the standard tool LaTeX uses for such purposes. With \leftskip you couldn't have a list inside your environment, for instance. The vertical spaces above and below are the same, what's specified by \topsep; if you want different spaces above and below (and I can't think for a good reason to), add \par\vspace{...} at the start of your environment.
    – egreg
    Commented Feb 1, 2014 at 17:23
  • I wrote that it was 'wrong', because my example didn't suggested that it was list - I used only paragraphs, not \item. In my mind 'list' is something that have items, so using list when there are no items seemed inappropiate. Though it is good to know that \leftskip wouldn't work with list inside this environment.
    – Rafal
    Commented Feb 1, 2014 at 17:32
  • 4
    @Rafal just as an example: the environments quote, center, flushleft and flushright are defined as lists internally. This may sound wrong but I guess the reasoning is that this way the spacing is consistent
    – cgnieder
    Commented Feb 1, 2014 at 18:06
  • 4
    @Rafal no. the list environment is not mainly for lists it is the standard display environment construct in latex see tex.stackexchange.com/questions/47057/… Commented Feb 1, 2014 at 18:50
7

I would suggest you to use the mdframed package to define your environment; the package offers you an easy way to control the vertical skip below and after and also gives you an easy way to add the padding to the left:

\documentclass{book}
\usepackage{mdframed}
\usepackage{lipsum}

\newmdenv[
  hidealllines=true,
  innerleftmargin=4em,
  innerrightmargin=0pt,
  leftmargin=4em,
  skipabove=2em,
  skipbelow=2em
]{myenv}


\begin{document}

\lipsum[2]
\begin{myenv}
\lipsum[3]
\end{myenv}
\lipsum[6]

\end{document}

enter image description here

4
  • it's generally recommended to represent vertical space in vertical units, such as ex. (the em is considered a horizontal unit in the tex context, even though one might still refer to an "em square".) Commented Feb 1, 2014 at 15:50
  • @barbarabeeton I have used em in my example since my background is in HTML/CSS, so it is more intuitive to use for me than ex or pt. Great comment, though.
    – Rafal
    Commented Feb 1, 2014 at 17:08
  • @Gonzalo It works, but seems to be an overkill when compare with Steven's environment solution. It seems that this package by default removes indents and even adding \indent in front of the text inside environment does not override this behaviour. Is it possible to introduce indents here?
    – Rafal
    Commented Feb 1, 2014 at 17:35
  • @GonzaloMedina This method seems to break down when embedded within a list environment itself. The skipabove and skipbelow do not work. Commented Sep 23, 2015 at 12:09

You must log in to answer this question.

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