Print

Print


The recent discussions about documentation / typos and bugs in l3prop got us
thinking again about the syntax and semantics of that module.

previously the key in a property list was supposed to be a single token,
typically a csname, e.g.,

\prop_new:N  \l_foo_prop

\prop_put:NNn \l_foo_prop \bar {baz}

making \bar the key and "baz" its value. Now while fixing the bugs introduced
recently in this module, we started to wonder if it wouldn't be much better if
the key would be allowed to be an arbitrary token list (well, sort of
arbitrary) which would then allow to use natural language strings as keys with
is a pain if not outright impossible if you have to press them into a csname
first.

so bottom line is that Morten and I reimplemented the module to us "n" instead
of "N" for the key argument, so

\prop_put:Nnn \l_foo_prop {catch} {22}

etc. Quite likely I broke something along the way (and other modules need
updating as well ... not done tonight) so if anybody feels like producing a
more devilish test file than I could think of so far, please give it a wirl.

'night
frank

ps there is one function in that module (well at least one) that doesn't seem
to make any sense \prop_if_eq:NNF at least not the way it is currently
implemented (since it actually compares on the toks level, but in a property
list order should be irrelevant as it is changed whenever keys are updated.

below is an approach to do the comparison without taking order into account
(not finished) ... perhaps somebody has a better idea?

\prop_new:N \l_prop_eq_test_prop

% check if key/val #1/#2 is in \l_prop_eq_test_prop
% set \l_prop_tmpb_tlp to #1 if not or with different val and call
% \prop_map_break:w to jump out of \prop_map_function:NN call

\def:Npn \prop_in_B:nn #1#2 {
  \prop_get:NnN \l_prop_eq_test_prop {#1} \l_prop_tmpa_tlp
  \quark_if_no_value:NTF \l_prop_tmpa_tlp
    { \typeout{key~ \exp_not:n{#1}~ not ~found} 
      \tlp_set:Nn \l_prop_tmpb_tlp {#1}
      \prop_map_break:w }
    { 
      \typeout{key:~ \exp_not:n{#1}~ found}
      \exp_args:No \tlist_if_eq:nnTF \l_prop_tmpa_tlp {#2}
        { \typeout{... value~ ok} }
        { \typeout{not~ equal} 
          \tlp_set:Nn \l_prop_tmpb_tlp {#1}
          \prop_map_break:w }
    }
} 

% test if all key/val from one prop is in the other and if yes try the other
% way around
% \l_prop_tmpb_tlp used to signal failure (= non-empty)

\def:Npn \prop_if_eq:NN #1#2 {
  \prop_set_eq:NN \l_prop_eq_test_prop #2
  \tlp_clear:N    \l_prop_tmpb_tlp 
  \prop_map_function:NN #1 \prop_in_B:nn
  \tlp_if_empty:NTF \l_prop_tmpb_tlp 
      {
       \typeout{...~ checking~ opposite~ direction~ ...}
       \prop_set_eq:NN \l_prop_eq_test_prop #1
       \prop_map_function:NN #2 \prop_in_B:nn
      }
      {}
}