On 18/02/2011, at 2:49 PM, Bruno Le Floch wrote:

> I ended up defining a new data structure: "conversion table" (ctab),
> which behaves somewhat like a property list, plus a bunch of special
> methods (for brace groups, etc.). For efficiency reasons, I went for
> the "one macro per token" approach. This can be changed later.
> 
> Since the code leads to an expandable version of the "x" argument
> specifier, I took the liberty of defining a *new argument type*, "e"
> (for expandable x), via \::e. See Sections 2.5.5 and 2.5.4 for
> details.

I managed to only have a quick look at this over the weekend. I like the look of the package, and well done for the good documentation.

I am especially interested in this last part with the e-type argument, especially its relationship to LuaTeX's \expanded primitive (also available in pdfTeX >= 1.5, if it's turning up in TL this year?). Do you think that we'd be able to add 'e' as an argument type using your code above where necessary and replace it with \expanded if it's available? Or will there be edge cases to cause us headaches?

Another function I'd like to see based on this work: expandable nestable function mapping. E.g., 

    \tl_nest_map_function:nN {ab{cd{e}f}g} \foo:n

resulting in (whitespace/newlines inserted for clarity)

    \foo:n{a} \foo:n{b}
    {
      \foo:n{c} \foo:n{d} 
      { \foo:n{e} } 
      \foo:n{f}
    }
    \foo:n{g}

It's easy to write \tl_nest_map_function:nN that *almost* works (see attached), but it drops braces around single tokens, which isn't always appropriate. (I haven't looked into doing it non-expandably, which would be more robust.)


Cheers,
-- Will


\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\cs_new:Npn \tl_nest_map_function:nN #1#2{
  \tl_nest_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop
}

\cs_new:Npn \tl_nest_map_function_aux:Nn #1#2{
  \quark_if_recursion_tail_stop:n{#2}
  \tl_if_single:nTF {#2}
    { #1{#2} }
    { {\tl_nest_map_function:nN {#2} #1 } }
  \tl_nest_map_function_aux:Nn  #1
}

\cs_new_nopar:Npn \tl_nest_map_function:NN #1#2{
  \exp_after:wN \tl_nest_map_function_aux:Nn
  \exp_after:wN #2 #1 \q_recursion_tail \q_recursion_stop
}

\cs_new:Npn \tl_nest_replace:Nnn #1#2#3 {
  \cs_set:Npn \tl_tmp:n ##1 {
    \tl_if_eq:NNTF ##1 #2
      { \exp_not:n  {#3} }
      { \exp_not:n {##1} }
  }
  \tl_set:Nx #1 {\tl_nest_map_function:NN #1 \tl_tmp:n}
}

\def\1{abc{def}ghi{j{k}l}}
\tl_nest_replace:Nnn \1 {e} {E}
\tl_nest_replace:Nnn \1 {k} {K}
\show\1
\end{document}