On 03/12/2009 18:02, Julien RIVAUD (_FrnchFrgg_) wrote: > Note that those characters would be set active only in the call of the > function; outside of it the catcode is preserved (or so I think). In > fact, in my first version of the \chemin macro, I did some kind of > replace, but without expl3 that meant an ugly thing with a lot of ad-hoc > looping code. Won't search/replace be slower than setting . and : to > macros ? Anyway, the question here is more to play with expl3 than > anything else, getting rid of chemin as it is now isn't a priority at > all... :) As Will said, there will be a speed hit but not hopefully too much. \tl_replace_all_in does not loop over every token in the input, so it's not actually too bad. More importantly, I found with siunitx that it is still possible to get a "race" condition even under the circumstances you describe. If you try siunitx v1 with htlatex, things go wrong with superscripts. This is fixed in v2 by not using active characters. > I think I have tried such solutions, wouldn't TeX complain about > nonexistent \char_make_active because a colon cannot anymore be in the > name of a macro ? Was forgetting about category code of ":". Fixed examples: \group_begin: \char_set_lccode:nn { `\@ } { `\: } \tl_to_lowercase:n { \group_end: \cs_set:Nn \my_int_function:n #1 { \tl_set:Nn \l_my_tmp_tl {#1} \tl_replace_all_in:Nnn \l_my_tmp_tl { . } { \cheminsommet } \tl_replace_all_in:Nnn \l_my_tmp_tl { @ } { \cheminface } % Do more stuff with the input } \group_begin: \char_set_lccode:nn { `\@ } { `\: } \char_make_active:N \@ \char_make_active:N \. \tl_to_lowercase:n { \group_end: \cs_set:Npn \my_int_function:n #1 { \tl_set_rescan:Nnx \l_my_tmp_tl { \char_make_active:N \@ \char_make_active:N \. \cs_set_eq:NN . \cheminsommet \cs_set_eq:NN @ \cheminface } {#1} % Stuff with \l_my_tmp_tl } -- Joseph Wright