Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) by h1439878.stratoserver.net (8.14.2/8.14.2/Debian-2build1) with ESMTP id r6BLR1qN025933 for ; Thu, 11 Jul 2013 23:27:02 +0200 Received: from relay2.uni-heidelberg.de ([129.206.210.211]) by mx-ha.gmx.net (mxgmx004) with ESMTP (Nemesis) id 0MUU43-1UnndE3la7-00REmF for ; Thu, 11 Jul 2013 23:26:56 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [129.206.100.94]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id r6BLNs31023918 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 11 Jul 2013 23:23:54 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [127.0.0.1]) by listserv.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id r6BES88Z012550; Thu, 11 Jul 2013 23:23:53 +0200 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 10327646 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Thu, 11 Jul 2013 23:23:53 +0200 Received: from relay.uni-heidelberg.de (relay.uni-heidelberg.de [129.206.100.212]) by listserv.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id r6BLDrRn022296 for ; Thu, 11 Jul 2013 23:13:53 +0200 Received: from mail-we0-f177.google.com (mail-we0-f177.google.com [74.125.82.177]) by relay.uni-heidelberg.de (8.14.1/8.14.1) with ESMTP id r6BLDhZx012351 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=FAIL) for ; Thu, 11 Jul 2013 23:13:46 +0200 Received: by mail-we0-f177.google.com with SMTP id m19so7408488wev.36 for ; Thu, 11 Jul 2013 14:13:43 -0700 (PDT) X-Received: by 10.180.189.208 with SMTP id gk16mr39021261wic.9.1373577223790; Thu, 11 Jul 2013 14:13:43 -0700 (PDT) Received: from palladium.home ([109.153.181.47]) by mx.google.com with ESMTPSA id h8sm44580876wie.1.2013.07.11.14.13.41 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 11 Jul 2013 14:13:42 -0700 (PDT) User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20130620 Thunderbird/17.0.7 MIME-Version: 1.0 References: <51C94FA0.1080803@morningstar2.co.uk> <51DD0EBD.6080308@morningstar2.co.uk> X-Enigmail-Version: 1.5.1 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Message-ID: <51DF2000.30703@morningstar2.co.uk> Date: Thu, 11 Jul 2013 22:13:36 +0100 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Joseph Wright Subject: Re: l3keys feature request To: LATEX-L@LISTSERV.UNI-HEIDELBERG.DE In-Reply-To: Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: Envelope-To: X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3; X-GMX-Antivirus: 0 (no virus found) X-UI-Filterresults: notjunk:1;V01:K0:0+MDEu/HtsY=:35sqUzd7NqP1BHWzGM+iDa za61Xiw+gUSNcJ4kOAqb3eNhW/10qT+tCqfvlMjdLEAtIlDq8wQDwFn3Xr4Z8drCw808Z12 T9UUbEJaVc7q9Y6OAOGki0PXXu6X77grCxbaFnCkI/y/huVfCmS+CZUqK/5RSa54gYSoDVM kiOn5GlfX73QOoTVXxNcfm3aErsuj9WggXKIRpjlBxHq/Y1mEd/LOoX9GR6Ct/IdXuTUNu2 ld5uptMDnjoh9hRsDfpJACSv3Amzl/GA8OH0ETiQ4HzSFa1qLE5T01f6BKGLXm77mEc2hw5 7eYSkFH3iDYci2jo5oIZ2N6TbcZ9a12o/cuXli7ap5sf2E70Wg1Hc6ehK0Z0YfZ5qqsXXp7 t+idrdoAW96N0RnKcBZmEh8UIrPhSTkMOUop2EfLbEYJAaH5g6cUmrEqiNr6LHQNWmKIwN0 I5MkE9fEuD6jCsbuqNAeznvBWkHjmHL2NWV2Ym5lTZeJzRjQLa6AQWajOGhMbM46sXySzHR YkctJFnEaVfyncQHQp+N6PXFG7wsjrGOGjvWe5zTCqDviYsGrpAAzrkEKJfhi8O1xfdRxnr p4ioRzOMzJ9ySJ4ksExheze+qeQcQJezx0XKQrwpImmvINc5MC9j/FiQ2KJgoZqquv0LESG XIebmxUDHYRqTew6xjbXC7659hz8Wv6I20MvwK7RWlcnSgRgoEAfk0IgR7LNNNg3wPpo0t5 vPMSTV94hhWfjdT4MpDMVP6dyI923WXnATiwng/Ho2bZZvRR8FxMyzNMCeUD+5uxd18B2wB CThqH5YhUaivmMDJVXpz8MASvUgA8mmWq2EGdSt5TIIoJIdNmKiB0HNN5cdVF+KR3UJ7pjf UR2HvYAjO0CwjmDg/Q9zeuVSZIqPxm2M/4kIqkzYkJTYxvvDqzr+iL1dmo2mPvfwFCS4eTD bSqzdDCatzzReWk8i2Om49MadLsczPMXT14j9WlrLXYrpPMEKvCFabeV1YhskRyVQlxHsPw lKAuVzOtgg/pzfZN9eEczZIZ2tyoWm/yseOBjeehalP+nzyREdwz238RgzW9yFpNxZHpejZ eY0vhMbWim3EwXcHVH0cXBlfmeQpSmoiBCF351XFymCao30wCIJnq4TQeTzO+Dn9w6l4vMa flQCY/mi5pyls5kpLE0q/CiGWX6Tv+3av1Dxmu1YWirsSS5KhqZbVvGsY6fm1GloATGrU+m O6GCloi6P8r/HJ2nZHJ6W5dNY3zs4tkOLCLxaTkP5s1QC6OdSd9DSgkyOaswaPsyHp/SkNl ETJxSXSlM10SSr0DiVY75xLmUcNuesPFzHap/BSf4YiKH4cLcykRwWl9ijyo5sTM+xAok5x LPhyDxYe/5kx8v9MUMfcrdJC8WOQp9O4c5bdxW3saPoH74CQyBlGxac8qDyACbj9ZzGVl3+ LLZUpEKAbcl0kJZrAwH3X2TU8BxFFkY7mXUO+SIm6rXouGmHWd8FAn+mvUKbFPgdGMhbGXY T0RonjSiN1BWyrPOkdy/64zQz3SYYFX0MvLSEaO68wCsTs1/oPKDTWjDT0LBmmCoXq4p7G/ DoeeJpS602OnI/r4cwzw6uBNsyflcF2qh3oGfwuWRCOGSHJsNqqQRNTA7iQLP2uzhytuBkJ KujJMMU0l X-UI-Loop:V01:DdJvTUGf4eI=:H2EmGXpvTR4ZdY9DP8eAQaqOZ85xzu5hmOGGFyq0Kx4= Status: R X-Status: X-Keywords: X-UID: 7235 On 10/07/2013 17:15, Jura Pintar wrote: >> Looking at this, both Bruno and I noticed that if you are allowing a >> clist then in principal you could simply extend \keys_set:nn to have a >> list for the first argument. However, I'm not sure that's quite right. >> >> If you look at the pgfkeys demo above, what you see is that all of the >> keys are in the same path: >> >> /mymodule/key-A-i >> /mymodule/key-B-i >> >> with the family as a 'secondary path' (or something like that). This >> means three things: >> >> 1) With filtering turned 'off', the keys can all be set in one >> operation (no need to try different places) >> >> 2) The key names are unique >> >> 3) If the key is not found, there is one place to look for an >> unknown handler: /mymodule/unknown >> >> On the other hand, the proposed extension to l3keys uses key path for >> filtering, so we find in contrast >> >> 1) The keys can only all be set by actively choosing each subgroup >> >> 2) Key names may not be unique, so the order of subgroups becomes >> important >> >> 3) Handling for unknown keys is far from clear (do we look in >> /mymodule/, /mymodule/subgroup-A/, ...?) >> >> I'm going to take a look at how pgfkeys actually handles this. >> -- >> Joseph Wright > > > Yes, you're right, of course! The pgfkeys family structure is > independent of the tree structure, and I can't remember now why I > tried doing it based on the paths... The problems you bring up really > should have been obvious to me. :S > > Anyhow, here is a version (appended below) that does follow the > pgfkeys approach more closely. I've not tested it very thoroughly, but > it seems to work... Again, I'm sure there's much room for improvement! > > There are two new properties: > > 1) .filter: - defines a key as a filter > 2) .filters:n - takes a clist argument that specifies which filters > are to be applied to a key (this is unlike the pgfkeys '.belongs to > family' handler, which only accepts a single family key) > > And there are several new public commands: > > 1) \keys_filters_activate:nn {} {} > 2) \keys_filters_deactivate:nn {} {} > 3) \keys_filters_deactivate_all: > 4) \keys_set_filtered:nn {} {} > 5) \keys_set_known_filtered:nnN {} {} > > and a couple of public variables > > \l_keys_filtered_seq - which contains the keys that were filtered out > on the last call of \keys_set_filtered:nn > \l_active_filters_seq - which contains the filter keys currently activated > > A key will be filtered out if any of the filters that apply to it are > active, and keys with no filters applied will be set normally. The pgfkeys approach seems perhaps more complex than needed to deal with the concept of groups of keys. I suspect that's because pgfkeys aims to allow basically full programming using keys: the target of l3keys is more limited. (I still need to read over the code in pgfkeys to pick up why they do these more complex things.) Looks at what seems to be needed, an ('opt-in') interface such as \keys_define:nn { module } { key-one .code:n = { \tl_show:n { key-one } }, key-one .group:n = { a }, key-two .code:n = { \tl_show:n { key-two } }, } \keys_set_grouped:nnn { module } { a } { key-one = value , key-two = value } is not unreasonable. This allows each key to be in exactly one group: doing multiple groups is possible but more tricky. (Code follows a bit later.) My thinking with this is that you can simply do a 'filtered' or 'grouped' setting without having to track when filtering is on/off. The above interface leaves open a few questions: - How is nesting handled? Does \keys_set:nn within \keys_set_grouped:nnn respect groups? Does \keys_set_grouped:nnn within \keys_set_grouped:nnn work in a union or intersection way? - Do unknown keys raise an error, or are they ignored as they are not in any group? Quick implementation: won't be the final one if we go for this! (Some of it depends on those questions.) \documentclass{article} \usepackage{expl3} \ExplSyntaxOn \cs_set_protected:Npn \__keys_cmd_set:n #1 { \tl_clear_new:c { \c__keys_vars_root_tl #1 .default } \tl_set:cn { \c__keys_vars_root_tl #1 .default } { \q_no_value } \tl_clear_new:c { \c__keys_vars_root_tl #1 .group } \clist_set:cn { \c__keys_vars_root_tl #1 .group } { } \tl_clear_new:c { \c__keys_vars_root_tl #1 .req } } \cs_new_protected:Npn \__keys_groups_set:n #1 { \tl_set:cn { \c__keys_vars_root_tl \l_keys_path_tl .group } {#1} } \cs_new_protected:cpn { \c__keys_props_root_tl .group:n } #1 { \__keys_groups_set:n {#1} } \tl_new:N \l__keys_groups_clist \cs_new_protected:Npn \keys_set_grouped:nnn { \__keys_set_grouped:oonnn { \l__keys_module_tl } { \l__keys_groups_clist } } \cs_new_protected:Npn \__keys_set_grouped:nnnnn #1#2#3#4#5 { \tl_set:Nx \l__keys_module_tl { \tl_to_str:n {#3} } \tl_set:Nx \l__keys_groups_clist { #4 } \keyval_parse:NNn \__keys_set_elt:n \__keys_set_elt:nn {#5} \tl_set:Nn \l__keys_module_tl {#1} \tl_set:Nn \l__keys_groups_clist {#2} } \cs_generate_variant:Nn \__keys_set_grouped:nnnnn { oo } \cs_set_protected:Npn \__keys_set_elt_aux:nn #1#2 { \tl_set:Nx \l_keys_key_tl { \tl_to_str:n {#1} } \tl_set:Nx \l_keys_path_tl { \l__keys_module_tl / \l_keys_key_tl } \__keys_value_or_default:n {#2} \clist_if_empty:NTF \l__keys_groups_clist { \__keys_set_elt_aux: } { \__keys_set_elt_grouped: } } \cs_new_protected_nopar:Npn \__keys_set_elt_aux: { \bool_if:nTF { \__keys_if_value_p:n { required } && \l__keys_no_value_bool } { \__msg_kernel_error:nnx { kernel } { value-required } { \l_keys_path_tl } } { \bool_if:nTF { \__keys_if_value_p:n { forbidden } && ! \l__keys_no_value_bool } { \__msg_kernel_error:nnxx { kernel } { value-forbidden } { \l_keys_path_tl } { \l_keys_value_tl } } { \__keys_execute: } } } \cs_new_protected_nopar:Npn \__keys_set_elt_grouped: { \cs_if_exist:cT { \c__keys_vars_root_tl \l_keys_path_tl .group } { \clist_if_in:NvT \l__keys_groups_clist { \c__keys_vars_root_tl \l_keys_path_tl .group } { \__keys_set_elt_aux: } } } \cs_generate_variant:Nn \clist_if_in:NnT { Nv } -- Joseph Wright