4

I have a macro that requires some setup code before being called :

\documentclass{minimal}
\usepackage{color}
\begin{document}
% some setup code
\colorbox{green}{This is green.}
% some cleanup code
\end{document}

All is good, but I don't like duplicating the setup/cleanup code.

How can I get a similar result using Environments? That way I could place the setup code in the "begin" section and the cleanup in the "end" section.

I tried the following, but obviously that's not how it works :

\documentclass{minimal}
\usepackage{color}

% % % % THIS DOES NOT WORK % % % %
\newenvironment{green}{\colorbox{green}\begingroup}{\endgroup}
% % % % THIS DOES NOT WORK % % % %

\begin{document}

\begin{green}
This should be green as well.
\end{green}

\end{document}

This gives the error ! Extra }, or forgotten \endgroup. I tought that \begingroup and \endgroup were specifically for using in unbalanced situations.

What are my options?

  • In Lieu of my bad answer, let me leave my original comment: \begingroup and \endgroup only help if you want a group. To get unbalanced braces, one technique is to use \bgroup and \egroup, which are \let to { and }, but this doesn't help with macro arguments. It does help with (most) boxes, but that's special. – Ryan Reich Aug 27 '13 at 19:08
7

enter image description here

You can use the lrbox environment to collect the contents.

\documentclass{minimal}
\usepackage{color}


\newenvironment{green}
{\begin{lrbox}{0}}
{\end{lrbox}\colorbox{green}{\usebox{0}}}


\begin{document}

\begin{green}
This should be green as well.
\end{green}

\end{document}
|improve this answer|||||
  • this doesn't work for long piece of texts with linebreaks in it though. How could one go in that case (without using environ)? – glS Oct 24 '16 at 13:56
  • @glS it uses colorbox as the OP requested, if you need a multi-line box then you need to nest minipage inside the lrbox, as usual. – David Carlisle Oct 24 '16 at 14:13
  • but with minipage you get that if you started the environment in the middle of a line the whole text in the environment starts from the middle of the line – glS Oct 24 '16 at 14:15
6

You can manage environments in a similar way you would macros by means of environ:

enter image description here

\documentclass{article}
\usepackage{environ}% http://ctan.org/pkg/environ
\usepackage{xcolor}% http://ctan.org/pkg/xcolor

\NewEnviron{green}{\colorbox{green}{\BODY}}%

\begin{document}

\colorbox{green}{This should be green as well.}

\begin{green}
This should be green as well.
\end{green}

\end{document}

The environment contents is grabbed and stored in \BODY, which can then be passed to a macro. However, this does not support boxing verbatim content, something an lrbox-approach does.

|improve this answer|||||
1

While the other answers fully address the OP's question quite well, no one has mentioned the use of keys. I would take an approach very similar to @DavidCarlisle (though I also like @Werner 's approach too). But, I would create keys to manage the color (and possibly other set up material) to allow me to change the color later in the document for a particular use.

The OP's comment about set up code is what got me thinking about keys.

Here's a MWE:

\documentclass{article}
\usepackage{pgfkeys}
\usepackage{xcolor}

\pgfkeys{/jt/colored/box/.cd,
  color/.initial = green,
}

\newsavebox{\mycolorBox}
\newenvironment{mycolor}[1][green]
  {\pgfkeys{/jt/colored/box/.cd,color=#1}%%'
   \begin{lrbox}{\mycolorBox}}
  {\end{lrbox}%%'
   \colorbox
     {\pgfkeysvalueof{/jt/colored/box/color}}%%'
     {\usebox{\mycolorBox}}}
\pagestyle{empty}
\begin{document}

   \begin{mycolor}
    Green box
   \end{mycolor}

   \begin{mycolor}[blue!20]
    Blue box
   \end{mycolor}

\end{document}

enter image description here

Regarding keys, there are many nice packages out there for dealing with keys. Recently, I've been experimenting a lot with pgfkeys or working with l3keys. But there's also many other such packages: see A big list of every keyval package details about other possible key-value packages

|improve this answer|||||
  • I don't think those \expandafter's are necessary, as accessing the value requires two expansion steps. – egreg Aug 27 '13 at 20:11
  • @egreg You're right! Somehow things weren't working until I put those in. I must have inadvertently fixed the bug when I modified my code. – A.Ellett Aug 27 '13 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.