# Defining a new environment whose contents go in a TikZ node

I would like to define an environment which typesets the contents in a box, and I'd like to use TikZ (I'm aware of alternatives like fancybox). So I would like something like

\newenvironment{abox}%
{\begin{tikzpicture}\node(box){\begin{minipage}{0.8\textwidth}}%
{\end{minipage}};}


However, this doesn't work, because the {...} that wraps the TikZ node can't be split across the beginning and end of the environment. Is there anyway around this? Thanks!

In such cases the environ page comes handy. Its command \NewEnviron collects the body which can be accessed as \BODY macro within your definition. Here's a complete example:

\documentclass{article}
\usepackage{tikz}
\usepackage{environ}
\NewEnviron{abox}{%
\begin{tikzpicture}
\node(box){%
\begin{minipage}{0.8\textwidth}
\BODY
\end{minipage}};
\end{tikzpicture}
}
\begin{document}
\begin{abox}
Text
\end{abox}
\end{document}


This compiles without problems and draws the test box.

• Didn't know about that one. Thanks. Nov 19, 2010 at 18:45
• +1 for pointing out the environ package; extremely useful also for other things (shameless plug). @Stefan, only one thing: \NewEnviron takes only 2 mandatory arguments (and one optional argument behind those); it won't see the pair of braces {}. Nov 19, 2010 at 20:52

First of all: I never knew about environ and am impressed. My answer is not nearly so good, but I learned it from the LaTeX sources so it should count for something.

Try writing

\newenvironment{<stuff>{\iffalse}\fi}
{\iffalse{\fi}<stuff>}


<stuff>, of course, is what you wrote. The point is that there are no unbalanced braces in this construction, because when parsing macro arguments, TeX does not actually expand anything, in particular, \iffalse. Thus, the "commented out" braces are present for the purposes of reading in the contents of the environment commands, and then absent for the purposes of executing them.

EDIT: In this and many other cases, the much simpler expedient of \bgroup...\egroup works too:

\newenvironment{<stuff>\bgroup}
{\egroup<stuff>}


Since \bgroup is \let to equal { and \egroup is \let to }, this (in theory) is synonymous with using braces, except that (since these "implicit characters" don't count as far as nesting inside arguments being parsed is concerned) it doesn't break definitions.

Occasionally you come across a situation where literal braces are required; \def itself is an example. You must write

\def\cs{<def'n>}


and not

\def\cs\bgroup<def'n>\egroup


but in many higher-level constructions (including, my quick test shows, TikZ) this is not a problem.

• +1, nice explanations. I'm not so sure about the trick with \iffalse: It looks useful, but is there any instance where you can use this trick, and \bgroup + \egroup doesn't work? (For \def it doesn't seem to help!) Nov 21, 2010 at 8:06
• @Hendrik Vogt: Unfortunately \def is totally inflexible! So that was a bad example. But I have found exactly one situation where this trick is necessary: with \halign. See, \halign allows you to protect &s and \crs appearing inside its entries (as in, within a nested \halign) by surrounding them in {...}. These are required to be literal braces. So if you have an environment where an alignment entry is broken from \begin to \end, you need to use the \iffalse trick if you want to protect its contents. Nov 21, 2010 at 8:24
• @Hendrik Vogt: By the way, you can make it work in \def if you unbalance the \iffalse trick: just write \def\cs{...\iffalse{\fi}. \def doesn't care if the inside has apparently unbalanced opening braces, but if the \iffalse{\fi} appears inside another macro argument, it will have properly balanced closing braces, which \def does care about. Of course, writing \def\cs{\iffalse}\fi...\iffalse{\fi} makes \cs = \iffalse and then gives an error as soon as \def finishes because you have a lonely \fi (unless you are in another conditional, when you get a subtler error...). Nov 21, 2010 at 8:49
• Why do you say that your answer is not as good? With the \bgroup/\egroup trick, the text inside the environment can have verbatim in it, which the environ package does not allow. Nov 21, 2010 at 20:04
• @Philippe Goutet: I added \bgroup/\egroup after I made that comment. In my opinion, the \iffalse trick is just that: a trick, and not something to be recommended. As it is, I guess what I wrote is not so bad anymore. Nov 21, 2010 at 21:11