10

Under certain conditions (triggered by selection of a package option) I would like to change specific environments into margin notes. However marginnote is not itself an environment, but a command that takes its contents as an argument. So what I want to do is replace

\begin{someenvironment}
...
\end{someenvironment}

with

\marginnote{
...
}

but I clearly cannot do this with something like

\renewenvironment{someenvironment}
    {\marginnote{ }
    { }}

What is the correct way to replace an environment with a command that takes the environment's contents as an argument?

0

2 Answers 2

11

The environ package may be of help here. You define an environment using

\NewEnviron{<env>}{%
  % environment contents
}

and the contents of the environment is available in the macro \BODY. Here's a minimal example:

enter image description here

\documentclass{article}
\usepackage{marginnote}% http://ctan.org/pkg/marginnote
\usepackage{environ}% http://ctan.org/pkg/environ
\NewEnviron{someenvironment}{%
  \marginnote{\BODY}% Place contents of <someenvironment> in a \marginnote
}
\begin{document}
Here is some text with a margin note.
\begin{someenvironment}
This is a margin note.
\end{someenvironment}
\end{document}
​

\NewEnviron has a macro-like look to it, so the usage should be fairly intuitive.

3
  • Thanks, that worked, thigh it ended up begin a bit more complicated in my case. I'm redefining an already defined environment, and end up with a lot of floats, so I had to \usepackage[maxfloats=36]{morefloats} and \let\existingenv ... \NewEnviron{existingenv}....
    – orome
    Commented Feb 21, 2012 at 22:25
  • Does this really answer the question? You are still using \begin{someenvironment}..., not writing \someenvironment{... Commented May 24, 2023 at 7:52
  • 1
    @ToivoSäwén: The OP thought there is a need to switch from an environment to a macro/command, because they wanted to capture the contents of the environment (similar to how a macro would capture its argument), with the latter being impossible. This was a false premise, so this and other answers point to ways of using the original setup (an environment).
    – Werner
    Commented May 24, 2023 at 16:08
2

Note also that you can use xparse (now included directly inside LaTeX), recent enough versions provide b or +b arguments (to allow multiple paragraphs):

\documentclass{article}
\usepackage{xparse}
\usepackage{marginnote}% http://ctan.org/pkg/marginnote
\usepackage{environ}% http://ctan.org/pkg/environ
\NewDocumentEnvironment{someenvironment}{+b}{%
  \marginnote{#1}% Place contents of <someenvironment> in a \marginnote
}{}
\begin{document}
Here is some text with a margin note.
\begin{someenvironment}
This is a margin note.
\end{someenvironment}
\end{document}

I also got lucky sometimes by replacing {...} with \bgroup...\egroup, but it seems that it's not working for all functions.

4
  • 1
    In detail, the b argument specifier has been introduced in xparse in March 2019, and xparse is part of the format since October 2020.
    – campa
    Commented Nov 19, 2021 at 13:32
  • Thanks for the precision. Btw, any idea why \bgroup...\egroup sometimes work, sometimes don't?
    – tobiasBora
    Commented Nov 19, 2021 at 13:36
  • 2
    they only work when the macros are designed not to take arguments normally but use something like a trailing \setbox0=\vbox so as to avoid freezing catcodes and improve efficiency (plain's \footnote does this)
    – plante
    Commented Nov 19, 2021 at 13:39
  • 1
    Primitives accepting arguments delimited by \bgroup and \egroup are basically the boxing primitives: \hbox, \vbox, \vtop, \vcenter, \halign. And IIRC \noalign and \insert. I might've forgotten something but anyway it's a relatively restricted list.
    – campa
    Commented Nov 19, 2021 at 13:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .