1

I would like to define a convenient way to pass arguments to an environment using the notation key=value. I don't know how to find this on the documentation.

For exemple:

\newenvironment{foobar}[3]{
...
}

\begin{foobar}[foo=1,bar=2,baz=3]
    text1
\end{foobar}

\begin{foobar}[bar=10]
    text2
\end{foobar}

And the result could be:

begin_foobar
you said that foo equals 1, bar equals 2 and baz equals 3
text1
end_foobar

begin_foobar
you said that bar equals 10
text2
end_foobar

(if you have any advise for a good documentation about LaTeX plumbery, I take it)

4
  • 2
    Use one of the many packages providing this: tex.stackexchange.com/questions/26771/… (I use normally l3keys, which is now already included in the latex format, but I'm biased). Aug 8, 2020 at 9:33
  • @UlrikeFischer The manual is very small. Do you have any idea how I should use it? Where can I find a good documentation with some examples?
    – nowox
    Aug 8, 2020 at 9:44
  • that is the manual of l3keys2e, l3keys is described in the expl3 manual "interface3". If you search a bit on the site here you can find many examples. (And as I wrote: I'm biased. Perhaps for a start you should at first try keyval, to get used to key-val definitions.) Aug 8, 2020 at 9:52
  • why should I get the credit if you did the work? Aug 8, 2020 at 16:24

3 Answers 3

2

Here an example of what you can do:

\documentclass{article}
\usepackage{environ}
\usepackage{keyval}

\makeatletter
\define@key{myenv@keys}{foo}{\def\myenv@foo{#1}}%
\define@key{myenv@keys}{bar}{\def\myenv@bar{#1}}%

\newenvironment{myenv}[1][]{%
    \setkeys{myenv@keys}{foo=4,bar=4,#1}
    Foo=\myenv@foo\par
    Bar=\myenv@bar\par
    Before\par
}{
    After
}
\makeatother

\begin{document}

\begin{myenv}[foo=42]
    Inside
\end{myenv}

\begin{myenv}[bar=42]
    Inside
\end{myenv}

\end{document}
1

With expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentEnvironment{foobar}{O{}}
 {
  \par
  \nowox_foobar_init:n { #1 }
 }
 {
  \par
 }

\keys_define:nn { nowox/foobar }
 {
  foo .tl_set:N = \l_nowox_foobar_foo_tl,
  bar .tl_set:N = \l_nowox_foobar_bar_tl,
  baz .tl_set:N = \l_nowox_foobar_baz_tl,
 }

\seq_new:N \l__nowox_foobar_args_seq

\cs_new_protected:Nn \__nowox_foobar_arg_add:nn
 {
  \tl_if_empty:nF { #2 }
   {
    \seq_put_right:Nn \l__nowox_foobar_args_seq
     {
      #1~equals~#2
     }
   }
 }
\cs_generate_variant:Nn \__nowox_foobar_arg_add:nn { nV }

\cs_new_protected:Nn \nowox_foobar_init:n
 {
  \keys_set:nn { nowox/foobar } { #1 }
  \__nowox_foobar_arg_add:nV {foo} \l_nowox_foobar_foo_tl
  \__nowox_foobar_arg_add:nV {bar} \l_nowox_foobar_bar_tl
  \__nowox_foobar_arg_add:nV {baz} \l_nowox_foobar_baz_tl
  \seq_if_empty:NF \l__nowox_foobar_args_seq
   {
    you~said~that~\seq_use:Nnnn \l__nowox_foobar_args_seq { ~and~ } { ,~ } { ~and~ } \par
   }
 }

\ExplSyntaxOff

\begin{document}

\begin{foobar}[foo=1,bar=2,baz=3]
    text1
\end{foobar}

\begin{foobar}[bar=10]
    text2
\end{foobar}

\begin{foobar}
    text3
\end{foobar}

\end{document}

enter image description here

The keys are set locally, so they don't change their empty status at the beginning. The nonempty values are added to a sequence that can be “used” with different text between entries (a comma between two, “and” between only two and ”and” between the last two, if more than two.

0

Building off of @nowox's answer, I've added macro definitions that allow the key values to be used within the environment.

\documentclass{article}
\usepackage{keyval}

\makeatletter
\define@key{myenv@keys}{foo}{\def\myenv@foo{#1}}%
\define@key{myenv@keys}{bar}{\def\myenv@bar{#1}}%
\newenvironment{myenv}[1][]{%
    % \makeatletter
    \setkeys{myenv@keys}{foo=default foo,% Set default value for foo
                         bar=default bar,% Set default value for bar
                         #1}% Set values given in environment argument.
    \def\foo{\myenv@foo}% Define \foo as the value given.
    \def\bar{\myenv@bar}% Probably a bad idea to redefine \bar, but done for sake of demo.

    In environment preamble: foo=``\foo'', bar=``\bar.''\par
}{
    \par\bigskip
}
\makeatother

\begin{document}

\makeatother
\begin{myenv}[foo=hello]
    % Within the environment, \foo and \bar can used.
    In environment (1): \verb|\foo|=``\foo'', \verb|\bar|=``\bar.''
\end{myenv}


\begin{myenv}[bar=goodbye]
    In environment (2): \verb|\foo|=``\foo'', \verb|\bar|=``\bar.''
\end{myenv}

Outside the \verb|myenv| environment, \verb|\foo| is undefined 
and \verb|\bar| retains its original definition meaning, 
e.g., \verb|\bar{A}=|$\bar{A}$.

\end{document}

Output: enter image description here

You must log in to answer this question.

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