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)

nowox
  • 1,375
  • 2
    Use one of the many packages providing this: https://tex.stackexchange.com/questions/26771/a-big-list-of-every-keyval-package (I use normally l3keys, which is now already included in the latex format, but I'm biased). – Ulrike Fischer Aug 08 '20 at 09: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 08 '20 at 09: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.) – Ulrike Fischer Aug 08 '20 at 09:52
  • why should I get the credit if you did the work? – Ulrike Fischer Aug 08 '20 at 16:24

3 Answers3

2

Here an example of what you can do, using the keyval package:

\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}

Paul Wintz
  • 402
  • 2
  • 14
nowox
  • 1,375
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.

egreg
  • 1,121,712
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

Paul Wintz
  • 402
  • 2
  • 14