LATEX-L Archives

Mailing list for the LaTeX3 project

LATEX-L@LISTSERV.UNI-HEIDELBERG.DE

Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Jura Pintar <[log in to unmask]>
Reply To:
Mailing list for the LaTeX3 project <[log in to unmask]>
Date:
Fri, 14 Jun 2013 06:05:01 -0400
Content-Type:
text/plain
Parts/Attachments:
text/plain (130 lines)
Dear all,

I’ve recently been re-implementing some of my projects in L3, and
finding myself having to jump through some hoops to get things I had
working smoothly in pgfkeys work equivalently well with l3keys. In
particular, filtering and redirecting keys has been a bit of a chore. In
light of this, I have a couple of suggestions for features that could be
added to the module in due course (to better illustrate what I have in
mind, I’ve written a quick-and-dirty implementation - appended at the
bottom of this email; the code seems to work, but I fully expect more
experienced people could greatly improve it).

1) It would be good to add a .meta:nn property that takes a path as its
first argument, so that we could do things like

  \keys_define:nn { module / subgroup-i }
    { key-i .code:n = { < code > } }
  \keys_define:nn { module / subgroup-ii }
    { key-ii .meta:nn = { module / subgroup-i } { key-i = #1 } }

instead of having to write

  \keys_define:nn { module / subgroup-ii }
    { key-i .code:n = { \keys_set:nn { module / subgroup-i } { key-i = #1 } } }

as is the case right now.

2) It would also be useful to provide a \keys_set_in_subgroups:nnn
command which would take a list of subgroups in the second
argument-place, and would cycle through all the subgroups looking for
keys given in the third argument-place. Then we could write things like

  \keys_set_in_subgroups:nnn { module } { subgroup-i , subgroup-ii }
    { key-i = foo , key-ii = bar }

instead of

  \keys_set:nn { module / subgroup-i } { key-i = foo }
  \keys_set:nn { module / subgroup-ii } { key-ii = bar }

More importantly, we could then easily define user commands that set
different subsets of keys. A further command  \keys_set_known_in_subgroups:nnnN
could then be used to catch keys that don’t exist in any of the
specified subgroups. If this suggestion is accepted, it would also be
useful to then extend l3keys2e with something like

  \ProcessKeysOptionsInSoubgroups { < module > } { < subgroup list > }

so we can use filtering in this context as well.

Anyhow, below is some code that does these things, but does need some
improvement. Please let me know what you think.



Best regards,

Jura Pintar


  \cs_new_protected:Npn \__keys_meta_make:nn #1#2
    {
      \__keys_cmd_set:Vo \l_keys_path_tl
        { \exp_after:wN \keys_set:nn {#1} {#2} }
    }
  \cs_new_protected:Npn \__keys_meta_make:nx #1#2
    {
      \__keys_cmd_set:nx { \l_keys_path_tl }
        { \exp_not:N \keys_set:nn \exp_not:n { {#1} } {#2} }
    }
  \cs_new_protected:Npn \__keys_meta_make:xx #1#2
    {
      \__keys_cmd_set:nx { \l_keys_path_tl }
        { \exp_not:N \keys_set:nn {#1} {#2} }
    }
  \cs_new_protected:cpn { \c__keys_props_root_tl .meta:nn } #1
    { \__keys_meta_make:nn #1 }
  \cs_new_protected:cpn { \c__keys_props_root_tl .meta:nx } #1
    { \__keys_meta_make:nx #1 }
  \cs_new_protected:cpn { \c__keys_props_root_tl .meta:xx } #1
    { \__keys_meta_make:xx #1 }

  \clist_new:N \l__keys_leftover_clist
  \prop_new:N  \l__keys_leftover_prop
  \cs_generate_variant:Nn \keyval_parse:NNn { NNo }

  \__msg_kernel_new:nnnn { kernel } { key-unknown-in-subgroups }
    { The~key~’#1’~is~unknown~and~is~being~ignored. }
    {
      A~key~called~’#1’~does~not~exist~in~any~specified~subgroup~of~
      the~module~’#2’.\\
      Check~that~you~have~spelled~the~key~name~correctly.
    }

  \cs_new_protected:Npn \keys_set_in_subgroups:nnn #1#2#3
    {
      \__keys_set_in_subgroups:onnn { \l__keys_module_tl } {#1} {#2} {#3}
      \clist_map_inline:Nn \l__keys_unknown_clist
        {
          \__msg_kernel_error:nnnn { kernel }
                { key-unknown-in-subgroups } {##1} {#1}
        }
    }
  \cs_new_protected:Npn \__keys_set_in_subgroups:nnnn #1#2#3#4
    {
      \clist_set:Nn \l__keys_unknown_clist {#4}
      \cs_set_eq:NN \__keys_execute_unknown: \__keys_execute_unknown_alt:
      \clist_map_inline:nn {#3}
        {
          \tl_set:Nx \l__keys_module_tl { \tl_to_str:n { #2 / ##1 } }
          \clist_set_eq:NN \l__keys_leftover_clist \l__keys_unknown_clist
          \clist_clear:N \l__keys_unknown_clist
          \keyval_parse:NNo \__keys_set_elt:n \__keys_set_elt:nn
            { \l__keys_leftover_clist }
        }
      \cs_set_eq:NN \__keys_execute_unknown: \__keys_execute_unknown_std:
      \tl_set:Nn \l__keys_module_tl {#1}
    }
  \cs_generate_variant:Nn \__keys_set_in_subgroups:nnnn { o }
  \cs_generate_variant:Nn \keys_set_in_subgroups:nnn
    { nVn , nVV , nVv , nVo , nvn , nvV , nvv , nVo , nno }

  \cs_new_protected:Npn \keys_set_known_in_subgroups:nnnN #1#2#3#4
    {
      \__keys_set_in_subgroups:onnn { \l__keys_module_tl } {#1} {#2} {#3}
      \clist_set_eq:NN #4 \l__keys_unknown_clist
    }
  \cs_generate_variant:Nn \keys_set_known_in_subgroups:nnnN
    { nVn , nVV , nVv , nVo , nvn , nvV , nvv , nVo , nno }

ATOM RSS1 RSS2