Hi all,

I encountered a bug in the \prop_map_tokens:Nn function in l3candidates.dtx.

Here's a not-working minimal example:

----------------------------------------
\ExplSyntaxOn
    \cs_set:Nn \test_mapper:nn
        { (#1,~#2)~ }
    \prop_new:N \testprop
    \prop_put:Nnn \testprop {1} {v1}
    \prop_put:Nnn \testprop {222} {v2}
    \prop_put:Nnn \testprop {3} {v3}
    \prop_put:Nnn \testprop {4} {v4}
    \prop_map_tokens:Nn \testprop { \test_mapper:nn }
\ExplSyntaxOff
----------------------------------------

The output will be:

----------------------------------------
(1, v1)2
----------------------------------------

It only processes single-token keys correctly. At the first
multi-token key, everything except for its first two tokens are
processed directly, then the rest of the list is skipped.

Here's the fix for l3candidates.dtx:

----------------------------------------
\cs_new:Npn \@@_map_tokens:nwn #1 \q__prop #2 \q__prop #3
  {
    \__quark_if_recursion_tail_break:nN {#2} \prop_map_break:
    \use:n {#1} {#2} {#3}
    \@@_map_tokens:nwn {#1}
  }
----------------------------------------

It just changes the tail-break test from :NN to :nN and adds braces around #2.

Cheers!

-- 
www.mhelvens.net