Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question

4 Answers 4

up vote 4 down vote accepted

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).

share|improve this answer
    
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

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.

share|improve this answer
    
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

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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