I have a parser for the environment keys and command of a package and it works very well. For MWE purposes I have two environments myenv
and myenv*
, both represent list environments, but only the first can be nested up to 4 levels, I have the command \setmymodule
with which I can configure the keys in the style of package enumitem
.
That is, I can use \setmymodule[level,1]{keys}
, \setmymodule[level,2]{keys}
, \setmymodule[myenv*]{keys}
and I've added a \printhis
command that encapsulates both environments, \printhis* to myenv*
and \printhis
to myenv
, so I've extended the \setmymodule
command to accept: \setmymodule[print,1]{keys}
, \setmymodule[print,2]{keys}
... \setmymodule[print*]{keys}
.
But I have a problem and I can't adapt it to accept \setmymodule[print,*]{keys}
.
The MWE I have is the following:
\documentclass{article}
\ExplSyntaxOn
% Some vars
\int_new:N \l_mymodule_int
\int_new:N \l_mymodule_s_int
% set level
\cs_new:Nn \__mymodule_level: { \int_to_roman:n { \l_mymodule_int } }
% keys for environments
\cs_set_protected:Npn \mymodule_tmp:nn #1 #2
{
\keys_define:nn { mymodule / #1 }
{
keya .tl_set:c = { l_mymodule_keya_#2_tl },
keyb .tl_set:c = { l_mymodule_keyb_#2_tl },
}
}
\clist_map_inline:nn { {level-1}{i}, {level-2}{ii}, {level-3}{iii}, {level-4}{iv}, {myenv*}{v} } { \mymodule_tmp:nn #1 }
% envs
\NewDocumentEnvironment{myenv}{ O{} }
{
\int_incr:N \l_mymodule_int
\tl_if_novalue:nF {#1}
{
\exp_args:Ne \keys_set:nn
{ mymodule / level-\int_use:N \l_mymodule_int } {#1}
}
\texttt{myenv ~ level: \int_use:N \l_mymodule_int}; ~
\texttt{keya ~ = ~ \tl_use:c { l_mymodule_keya_ \__mymodule_level: _tl } } ; ~
\texttt{keyb ~ = ~ \tl_use:c { l_mymodule_keyb_ \__mymodule_level: _tl } } \par
}{}
\NewDocumentEnvironment{myenv*}{ O{} }
{
\int_incr:N \l_mymodule_s_int
\tl_if_novalue:nF {#1}
{ \keys_set:nn { mymodule / myenv* } {#1} }
\texttt{myenv* ~ level: \int_use:N \l_mymodule_s_int }; ~
\texttt{keya ~ = ~ \tl_use:N \l_mymodule_keya_v_tl }; ~
\texttt{keyb ~ = ~ \tl_use:N \l_mymodule_keyb_v_tl} ; \par
}{}
% keys for \printhis
\tl_new:N \l_mymodule_print_v_tl
\tl_new:N \l_mymodule_print_starred_tl
\cs_set_protected:Npn \mymodule_tmp:nnn #1 #2 #3
{
\keys_define:nn { mymodule / #1 }
{
print* .code:n = \tl_put_right:Nn \l_mymodule_print_starred_tl
{ \setmymodule[myenv*] {##1} },
print-* .code:n = \tl_put_right:Nn \l_mymodule_print_v_tl
{ \setmymodule[myenv*] {##1} },
}
\tl_new:c { l_mymodule_print_#3_tl }
\keys_define:nn { mymodule / #1 }
{
print-#2 .code:n = \tl_put_right:cn { l_mymodule_print_#3_tl }
{ \setmymodule[level,#2] {##1} },
}
}
\clist_map_inline:nn { {print}{1}{i}, {print}{2}{ii}, {print}{3}{iii}, {print}{4}{iv}, } { \mymodule_tmp:nnn #1 }
%% cmd
\NewDocumentCommand \printhis { s O{} m }
{
\group_begin:
\tl_use:N \l_mymodule_print_i_tl
\tl_use:N \l_mymodule_print_ii_tl
\tl_use:N \l_mymodule_print_iii_tl
\tl_use:N \l_mymodule_print_iv_tl
\tl_use:N \l_mymodule_print_v_tl
\__mymodule_print_this:nnn { #1 } { #2 } { #3 }
\group_end:
}
\cs_new_protected:Npn \__mymodule_print_this:nnn #1 #2 #3
{
\bool_if:nTF {#1}
{
\tl_use:N \l_mymodule_print_starred_tl
\begin{myenv*}[#2]
% use \seq_map_inline:cn here #3
\end{myenv*}
}
{
\begin{myenv}[#2]
% use \seq_map_inline:cn here #3
\end{myenv}
}
}
%% Add keys
\keys_define:nn { mymodule / meta-families }
{
level-1 .code:n = { \keys_set:nn { mymodule / level-1 } {#1} } ,
level-2 .code:n = { \keys_set:nn { mymodule / level-2 } {#1} } ,
level-3 .code:n = { \keys_set:nn { mymodule / level-3 } {#1} } ,
level-4 .code:n = { \keys_set:nn { mymodule / level-4 } {#1} } ,
myenv* .code:n = { \keys_set:nn { mymodule / myenv* } {#1} } ,
print-1 .code:n = { \keys_set:nn { mymodule / print } { print-1 = {#1} } } ,
print-2 .code:n = { \keys_set:nn { mymodule / print } { print-2 = {#1} } } ,
print-3 .code:n = { \keys_set:nn { mymodule / print } { print-3 = {#1} } } ,
print-4 .code:n = { \keys_set:nn { mymodule / print } { print-4 = {#1} } } ,
print-* .code:n = { \keys_set:nn { mymodule / print } { print-* = {#1} } } ,
print* .code:n = { \keys_set:nn { mymodule / print } { print* = {#1} } } ,
unknown .code:n = { \msg_error:nn { mymodule } { unknown-key-family } } ,
}
\seq_const_from_clist:Nn \c_mymodule_all_families_seq
{
level-1 , level-2 , level-3 , level-4 , myenv*,
print-1 , print-2 , print-3 , print-4 , print-*, print*,
}
% Define |\setmymodule|
\tl_new:N \l_mymodule_setkey_tmpa_tl
\tl_new:N \l_mymodule_setkey_tmpb_tl
\int_new:N \l_mymodule_setkey_tmpa_int
\seq_new:N \l_mymodule_setkey_tmpa_seq
\seq_new:N \l_mymodule_setkey_tmpb_seq
\NewDocumentCommand \setmymodule { o +m }
{
\tl_if_novalue:nTF {#1}
{
\seq_map_inline:Nn \c_mymodule_all_families_seq
}
{
\seq_clear:N \l_mymodule_setkey_tmpa_seq
\seq_set_from_clist:Nn \l_mymodule_setkey_tmpb_seq {#1}
\int_set:Nn \l_mymodule_setkey_tmpa_int
{
\seq_count:N \l_mymodule_setkey_tmpb_seq
}
\int_compare:nNnTF { \l_mymodule_setkey_tmpa_int } > { 1 }
{
\seq_pop_left:NN \l_mymodule_setkey_tmpb_seq \l_mymodule_setkey_tmpa_tl
\seq_map_function:NN \l_mymodule_setkey_tmpb_seq \__mymodule_set_parse:n
\seq_set_map_e:NNn \l_mymodule_setkey_tmpa_seq \l_mymodule_setkey_tmpa_seq
{
\tl_use:N \l_mymodule_setkey_tmpa_tl - ##1
}
}
{
\seq_put_right:Ne \l_mymodule_setkey_tmpa_seq { \tl_trim_spaces:n {#1} }
}
\seq_if_empty:NTF \l_mymodule_setkey_tmpa_seq
{ \seq_map_inline:Nn \c_mymodule_all_families_seq }
{ \seq_map_inline:Nn \l_mymodule_setkey_tmpa_seq }
}
{
\keys_set:nn { mymodule / meta-families } { ##1 = {#2} }
}
}
\cs_new_protected:Npn \__mymodule_set_parse:n #1
{
\tl_set:Ne \l_mymodule_setkey_tmpb_tl { \tl_trim_spaces:n {#1} }
\int_step_inline:nnn { 0 } { 4 } % <- max level
{ \tl_remove_all:Nn \l_mymodule_setkey_tmpb_tl {##1} }
\tl_if_empty:NTF \l_mymodule_setkey_tmpb_tl
{
\seq_put_right:Ne \l_mymodule_setkey_tmpa_seq
{ \tl_trim_spaces:n {#1} }
}
{ \__mymodule_set_error:nn {#1} { } }
}
\cs_new_protected:Npn \__mymodule_set_error:nn #1 #2
{ \msg_error:nnn { mymodule } { invalid-key } {#1} {#2} }
\msg_new:nnn { mymodule } { unknown-key-family }
{
Unknown ~ key ~ family ~ `\l_keys_key_str' ~ for ~ mymodule.
}
\msg_new:nnn { mymodule } { invalid-key }
{
The ~ key ~ '#1' ~ is ~ not ~ know ~ the ~ level ~ #2.
}
\ExplSyntaxOff
\begin{document}
\begin{myenv}[keya=Foo,keyb=Baz]
\begin{myenv}[keya=BAZ]
\end{myenv}
\end{myenv}
% myenv*
\begin{myenv*}[keya=STAR]
\end{myenv*}
\setmymodule[print*]{keyb=WWWWW }
\begin{myenv}
\end{myenv}
Befor
\setmymodule[print,1]{ keyb=HHH }
\printhis{KK}
Now
\setmymodule[print*]{ keya=HHH }
\printhis*{ZZZ}
\setmymodule[print,*]{ keya=HHH }
\end{document}
How can I add an exception to the \setmymodule
code so that it accepts \setmymodule[print,*]{keys}
?
Clarification
If it's a bit complicated...I'll try to explain, the issue goes through the following:
In the real implementation, when you execute
\begin{myenv}[save=foo]
...
\begin{myenv}
...
\begin{myenv*}
...
\end{myenv*}
...
\end{myenv}
...
\end{myenv}
it stores in a \seq_var = foo
the entire structure except the first level,
including myenv*
(which can be nested in it),
When you execute \begin{myenv*}[save=foo]
it also saves the entire
structure which can contain myenv
in a \seq_var = foo
(without myenv*
nested).
When running \printhis
(without *
) it opens with:
\begin{myenv}[opt first level]
\seq_map_inline:cn \seq_var = foo
\end{myenv}
So if there is myenv*
in \seq_var = foo
and I can't configure it
with \setmymodule[myenv*]{keys}
because it modifies all myenv*
environments outside of \printhis
, so I need to be able to access
these keys somehow and in this case it would be
\setmymodule[print,*]{keys}
which is different from
\setmymodule[print*]{keys}
which sets the default keys (in
\l_mymodule_print_starred_tl
) for \printhis*
which executes:
\tl_use:N \l_mymodule_print_starred_tl
\begin{myenv*}[opt first level]
\seq_map_inline:cn \seq_var = foo
\end{myenv*}
and will not necessarily have the same default settings as myenv*
in the document.
Of course the MWE is a bit ugly but I couldn't find another way to put some code where the use of \setmymodule
could be checked :(
enumitem
you don't use\setlist[level,1]{...}
but just\setlist[1]{...}
or is your list calledlevel
?print,*
supposed to do?