# Environment definition separates matching braces

Suppose I want to define an environment which is essentially a modification of an existing one. I tried something like that:

\newenvironment{newenv}{%
\formatcommand{\begin{oldenv}%
}{%
\end{oldenv}}%
}


I would expect

\begin{newenv}Foo\end{newenv}


to result in the same output as

\formatcommand{\begin{oldenv}Foo\end{oldenv}}


But whenever I use \begin{newenv}, pdflatex says

Missing } inserted


and skrews up everything afterwards, of course. Without \formatcommand everything is fine, so apparently the orphan { form \formatcommand is the culprit.

My guess is that pdflatex tries to treat stuff inside environment definition parts as something syntactically correct---which what I do clearly is not---instead of "just" to replace text and parse afterwards.

Is there a way to get around this, i.e. have a command span from a new environments beginning to end?

Use case:

\newenvironment{card}{%
\resizebox{55mm}{85mm}{\begin{tabular*}{55mm}{| p{50.5mm} |}%
\hline%
}{%
\hline\end{tabular*}}%
}


If I put the same resizebox around the usage site of card, it compiles and resizes (even though not the way I intended, but that's for another day).

-
Not sure what you are tying to do here. Why are you passing the \begin{oldenv} to \formatcommand? –  Peter Grill Sep 28 '11 at 20:56
It mostly depends on what \formatcommand is supposed to do and on what oldenv is. A "real world" example is needed. –  egreg Sep 28 '11 at 20:57
I would have thought that this issue relates to general properties of (La)TeX, but there you go. –  Raphael Sep 28 '11 at 21:07
@PeterGrill I want to have \formatcommand applied to the whole environment oldenv. As I repeat card often in the application and need the same resize, I figured an environment def would be the place to put it. –  Raphael Sep 28 '11 at 21:12

For applying some macro/command to the body of an environment, you may want to extract the entire body into a macro itself. This can be done (to whatever limited extent) using the environ package. Here is a short example:

\documentclass{article}
\usepackage{environ}% http://ctan.org/pkg/environ
\NewEnviron{itquote}{%
\itshape% Set shape to italics
\begin{quote}
\BODY% regular \BODY of itquote environment
\end{quote}
}
\begin{document}
\begin{quote}% Original quote environment
Here is a very simple quote
\end{quote}
\begin{itquote}% New itquote environment
Here is a very simple quote
\end{itquote}
\end{document}
​


In the above (admittedly elementary) example, itquote italicizes its contents (stored in the macro \BODY). For some, it provides a more intuitive way of working with environments within environments.

Additionally, it is always good to view the package documentation (and sometimes even the package source .sty). For example, although minipage is an environment and is typically used in the context of \begin{minipage}{<width>} ... \end{minipage} it can also be used in a "macro pair form" using \minipage{<width} ... \endminipage. Again, for some, this allows for a more intuitive way of splitting environment begin/end's over a new environment definition.

-
That works wonderfully, thanks! Good hint regarding macro pairs, too, even though I don't see myself digging is sty files. –  Raphael Sep 28 '11 at 21:25

You can't leave unbalanced braces in a definition. That's forbidden by TeX's syntax rules.

There is a workaround:

\newsavebox{\cardbox}
\newenvironment{card}
{\begin{lrbox}{\cardbox}
\begin{tabular*}{55mm}{| p{50.5mm} |}
\hline
}
{\hline
\end{tabular}
\end{lrbox}%
\resizebox{55mm}{85mm}{\usebox{\cardbox}}%
}


The contents of the environment is saved in the \cardbox bin which is later processed.

See Werner's answer for another method which is particularly useful in other situations.

-
I don't understand what happens here, and it seems a lot of boilerplate compared to environ. Does your solution have technical advantages? –  Raphael Sep 28 '11 at 21:26
For example, environments defined with environ can't go in the argument of commands, nor in the definition of other environments. The lrbox way uses only kernel methods (except \resizebox, of course). –  egreg Sep 28 '11 at 21:31
I see. In my case, the environment in queston is going to be top-level so I'll stick with environ, but I appreciate your answer. –  Raphael Sep 28 '11 at 21:34

Here is an example of defining a new environment:

\documentclass{article}
\usepackage{lipsum}
\newenvironment{MyQuote}{%
\begin{quote}%
% Add customization that goes after the start of the environment here
}{%
% Add customization that goes before the end of the environment here
\end{quote}%
}%

\begin{document}
\begin{MyQuote}
\lipsum[1]
\end{MyQuote}
\end{document}


I suspect that you are trying to use some macro of the form \macro{} and attempting to add the \macro{ at the beginning and } at the end environment. Don't think this is allowed with the standard \newenvironment. You could use the environ package, with which provides access to the body of the environment via \BODY. Here is an example:

\documentclass{article}
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{environ}

\NewEnviron{MyQuote}{%
\quote%
\textcolor{red}{\BODY}%
}{%
\endquote%
}
\begin{document}
\begin{MyQuote}
\lipsum[1]
\end{MyQuote}
\end{document}

-
This answer does not relate to the question. I tried to clarify that the general way of defining new environments is not the issue (or so I think) but specifically how to have a command span from before its begin to after its end. –  Raphael Sep 28 '11 at 21:03
See updated regarding the environ package. –  Peter Grill Sep 28 '11 at 21:13
That works wonderfully, thanks! –  Raphael Sep 28 '11 at 21:24

What should \formatcommand do?

Your definition has no balanced braces, I hope the following sequence shows, what happens:

\newenvironment{newenv}{%Open parameter 2 of \newenvironment
\formatcommand{\begin{oldenv}%
}%this closes formatcommand
{%you open a group
\end{oldenv}
}%The group is closed%
}%you close parameter 2 of \newenvironment
%%Now you should get the 3rd parameter of \newenvironment

-
This clearly is what happens and I stated as much in the question. Do you have a solution? –  Raphael Sep 28 '11 at 21:09