# How to define environment in LaTeX which replaces its content?

I'd like to define an environment that would display a graphviz image. The code should look like this:

  \begin{graph}{name}[optionalArgs]
a -> b; /* graphviz code*/
\end{graph}


I've started with simple definition:

\newenvironment{graph}[2]%
{#1 %name
#2 %code itself
}%
{% end code
}


However #2 contains only first part in this case just a and the rest of input is displayed afer. How do I get whole content of environment in a variable?

-
For the specific part of getting the contents of an environment in a macro, look at the environ package (probably ctan.org/pkg/environ). – Loop Space Feb 24 '12 at 10:57
thanks for tip. I tried this \Collect@Body\writeDotFile but any other command after this one gets appended as a string. how do I force TeX to execute just this command? I'm sorry I'm pretty new to TeX – Tombart Feb 24 '12 at 22:17
You may also be interested in the listings package, useful to format nicely source code in many languages. – Bruno Le Floch Feb 26 '12 at 22:40

For standard environments, the body of the environment is placed before the end code is executed and is not accessed via the #<n> syntax. You could also use the environ package as suggested by @AndrewStacey. In this case you can use \BODY where you want the contents of the environment.

Below is an example with an optional parameter provided in the first case, and the none provided in the second case (defaults to foo). The graph environment is the standard LaTeX environment, and Graph is defined via \NewEnviron.

## Notes:

• The #<n> syntax is used to access parameters, and can not be used to access the body of an environment.

• Standard practice is to have any optional parameters before the mandatory ones. If this does not work for your case, you should consider using the xparse package.

• If you are using the \Collect@Body macro, you should enusre that this is within a \makeatletter ... \makeatother. See What do \makeatletter and \makeatother do? for more details on this.

## Code:

\documentclass{article}
\usepackage{environ}% defines NewEnviron

\NewEnviron{Graph}[2][foo]{%
\noindent%
Using \textbf{NewEnviron:} Optional Args = #1\par\noindent%
Name=#2%
\BODY%
\medskip\hrule\medskip%    end code
}

\newenvironment{graph}[2][foo]{%
\noindent%
Using \textbf{newenvironment:} Optional Args = #1\par\noindent%
Name=#2%
}{%
\medskip\hrule\medskip%    end code
}

\begin{document}
\begin{graph}[optionalArgs]{name1}
$a \to b$; /* code*/
\end{graph}

\begin{graph}{name2}
$a \to b$; /* code*/
\end{graph}

\begin{Graph}[optionalArgs]{name1}
$a \to b$; /* code*/
\end{Graph}

\begin{Graph}{name2}
$a \to b$; /* code*/
\end{Graph}
\end{document}

-
thanks for a detailed answer. I'm using it inside a package, so that's why the \Collect@Body macro – Tombart Feb 27 '12 at 22:25