0

I'm new to expl3 syntax and can't get it to work properly. I'd like to get the values of known keys into variables but leave unknown pairs untouched for later use e.g. to be used in a document command where I consolidate several different package functions into one, how do I do that?

Minimum (not) working example

\documentclass{article}
\usepackage{expl3,xparse}

\ExplSyntaxOn
    
    % Declare
    \tl_new:N \l__mymod_keyi_tl
    \seq_new:N \l_mymod_keyvalue_seq
    
    % Define
    \keys_define:nn { mymod } {
        keyi        .tl_set:N   = \l__mymod_keyi_tl,
        otherKeys   .code:n     = \mymod_store:Vn \l_keys_key_tl {#1},
    }
    \cs_new_protected:Nn \mymod_store:nn {
        \seq_put_right:Nn \l_mymod_keyvalue_seq {#1~=~{#2},}
    }
    \cs_generate_variant:Nn \mymod_store:nn { V }
    
    % Setter
    \NewDocumentCommand{\setkeys}{m} {
        \keys_set:nn { mymod } { #1 }
    }
    
    % Getter i
    \NewExpandableDocumentCommand\printkeyi{} {
        \text_expand:n{
            \l__mymod_keyi_tl
        }
    }

    % Usage here
%   \NewDocumentCommand{\fun}{m} {
%       \fun1{ keyName = \text_expand:n {\l__mymod_keyi_tl} }
%       \fun2{ \otherKeys or \printkeys or whatever} % keyi should NOT be among them
%   }
    
    % Getter rest
    \NewExpandableDocumentCommand\printkeys{} {
        \seq_use:Nn \l_mymod_keyvalue_seq {,~}
    }

\ExplSyntaxOff

\begin{document}
    A few words
    
    \setkeys{keyi = 3, keyii = 4, keyiii = 5}   
    
    another few
    
    \printkeys
\end{document}

here

Output

1
1

unknown is a keyword. 😑

\documentclass{article}
\usepackage{expl3,xparse}

\ExplSyntaxOn
    
    % Declare
    \tl_new:N \l__mymod_keyi_tl
    \seq_new:N \l_mymod_keyvalue_seq
    
    % Define
    \keys_define:nn { mymod } {
        keyi        .tl_set:N   = \l__mymod_keyi_tl,
        unknown   .code:n     = \mymod_store:Vn \l_keys_key_tl {#1},
    }
    \cs_new_protected:Nn \mymod_store:nn {
        \seq_put_right:Nn \l_mymod_keyvalue_seq {#1~=~{#2},}
    }
    \cs_generate_variant:Nn \mymod_store:nn { V }
    
    % Setter
    \NewDocumentCommand{\setkeys}{m} {
        \keys_set:nn { mymod } { #1 }
    }
    
    % Getter i
    \NewExpandableDocumentCommand\printkeyi{} {
        \use:x {
            \l__mymod_keyi_tl
        }
    }

    % Usage here
%   \NewDocumentCommand{\fun}{m} {
%       \fun1{ keyName = \text_expand:n {\l__mymod_keyi_tl} }
%       \fun2{ \otherKeys or \printkeys or whatever} % keyi should NOT be among them
%   }
    
    % Getter rest
    \NewExpandableDocumentCommand\printkeys{} {
        \seq_use:Nn \l_mymod_keyvalue_seq {~}
    }

\ExplSyntaxOff

\begin{document}
    A few words
    
    \setkeys{keyi = 3, keyii = 4, keyiii = 5}   
    
    another few
    
    keyi = \printkeyi
    
    some more
    
    \printkeys
\end{document}

enter image description here

3
  • Welcome to TeX.SX! \keys_set_known:nnN {<module>} {<keyval list>} <tl> stores unknown keys in the token list <tl>: it does more or less the same as you achieved with unknown. Side notes: \printkeyi cannot be expandable because \use:x is not expandable (and \use:x is not necessary there). Since you are putting unknown keys in a seq variable, you don't need the trailing comma. – Phelype Oleinik Jun 20 '20 at 10:47
  • @PhelypeOleinik does <tl> then only contain unknown key-value pairs, the manual is a bit ambiguous there. The reason is, I'd like to grab specific ones from the input, process them and then mix them together with the "unknown" ones, so I don't have to define each and every one for - in this case - \DeclareAcronym from acro. the comma is there, so that when I then use \seq_use:Nn \l_cwurzel_glossac_keyvalue_seq {~} (where the comma could also be), I can directly hand them off to the macro. - in essence I try to define a glossentry and an acronym simultaneously. but it all works now. – learex Jun 20 '20 at 14:39
  • Yes, \keys_set_known:nnN will act on known keys, and forward the remaining ones to <tl>. Try this in your example document: \ExplSyntaxOn \tl_new:N \l__mymod_keyi_tl \tl_new:N \l__mymod_unknown_tl \keys_define:nn { mymod } { keyi .tl_set:N = \l__mymod_keyi_tl } \NewDocumentCommand{\setkeys}{m} { \keys_set_known:nnN { mymod } { #1 } \l__mymod_unknown_tl} \NewExpandableDocumentCommand\printkeyi{}{\tl_use:N \l__mymod_keyi_tl} \NewExpandableDocumentCommand\printkeys{}{\tl_use:N \l__mymod_unknown_tl} \ExplSyntaxOff – Phelype Oleinik Jun 20 '20 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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