4

Suppose there is an existed environment say, existedenv, with an optional argument, that is,

\begin{existedenv}[argument]
....
\end{existedenv}

I want to define a new environment, say, myenv, which is a copy of existedenv, that is,

\begin{myenv}[argument]
....
\end{myenv}

behavior is exactly like

\begin{existedenv}[argument]
....
\end{existedenv}

How to write the code?

5

You can just define myenv like this:

\newenvironment{myenv}{%
    % maybe some code here
    \begin{existedenv}%
    % but no code here!
}{%
    \end{existedenv}%
}

The when you write \begin{myenv}[argument] the \begin{myenv} is expanded to \begin{existedenv} and it results in \begin{existedenv}[argument]. This isn't an option if you need code after the \begin{existedenv} and won't work without modification when existedenv is a verbatim or pseudo-environment (i.e. reads its body as argument like beamers frame).

  • That's definitely good to know! Do macros inherit options, too? – ℝaphink Apr 21 '11 at 9:34
  • @Raphink: It works with macros as well. However I wouldn't call it 'inherit options'. It's all about expansion. – Martin Scharrer Apr 21 '11 at 9:48
  • @Raphink: This technique is more like "partial application" or "currying/uncurrying" in functional languages. – Ulrich Schwarz Apr 21 '11 at 9:55
9

If you really, really don't need any extra functionality, you can cheat a little:

\let\myenv\existedenv
\let\endmyenv\endexistedenv

Otherwise, i.e. if you want to inspect all the arguments for some reason, things get more complicated because there are environments with multiple optargs (e.g. minipage), args in parentheses (picture), optional args in curly braces (beamer's frame) and so on.

1

If you don't want to do anything to the optional argument of myenv you can write it without the argument and let existingenv take care of it:

\newenvironment{myenv}{
  % stuff of your own...
  \existingenv
}{
  \endexistingenv
}

Then \begin{myenv}[foo] will expand to \begin{existingenv}[foo] before foo is expanded.

But if this is all you want to do you might consider using some the macros in the etoolbox package to just patch the environment. For instance,

\pretocmd{\A}{stuff of your own}{}{}

will just insert the code you want before the begin-code of A.

1

The code would be:

\newenvironment{myenv}[#args] {%
    %code coult be put here
    \begin{existedenv}{#1}..{#args}%
    %code could be put here but must be valid inside existedenv
}{%
    \end{existedenv}%
}

Where #args is the number of args used by existedenv.

  • I don't understand the ..[#args] part. You might mean: {#2}..{#args}. Also you need to place % after the two { and after \end{existedenv} to avoid unwanted spaces. – Martin Scharrer Apr 21 '11 at 9:21
  • Yes I meant {#1}..{#args} if #args>0 and if #args == 0, leave it empty. I fix(ed) it in the answer above. I added the %. – BernS Apr 21 '11 at 9:35
  • The #1 is the optional one, so you need to write [#1]{#2}..{#args} (for #args > 2 of course). – Martin Scharrer Apr 21 '11 at 9:46
  • Anyway you could also write {#1}{#2} as {#1} must not be optional, or am I wrong here? I think if you need {} or [] depends on the environment used. – BernS Apr 21 '11 at 9:52
  • Sure, that's true. The OP just requested an optional argument, so I thought your answer is specific to that. – Martin Scharrer Apr 21 '11 at 9:59

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.