Print

Print


On 17/09/2015 12:00, Alexander Grahn wrote:
> I am puzzled. What exactly do I have to do in order to adjust existing
> code which uses the lowercase trick
> 
> \group_begin:
> \char_set_lccode:nn{...}{...}
> \tl_to_lowercase:n{
>   \group_end:
>   ...
> }
> 
> ?

It will depend on what outcome you want, hence giving some different
possibilities: for some cases there are several alternative
formulations. Taking some examples from media9 :-)

    \group_begin:
    \char_set_lccode:nn{`\+}{`\@}
    \tl_to_lowercase:n{
      \group_end:
      \cs_new:Npn\mix_parse_windowedarg:w#1+#2+#3\q_stop{
        \tl_if_blank:nF{#1}{\tl_gset:Nn\g_mix_winsize_tl{#1}}
        \tl_if_blank:nF{#2}{\tl_gset:Nn\g_mix_winpos_tl{#2}}
      }
      \cs_new:Nn\mix_parse_windowedarg:N{
        \exp_after:wN\mix_parse_windowedarg:w#1++\q_stop
      }
    }

doesn't really need anything 'tricky' at all, as

    \group_begin:
      \char_set_catcode_other:n { `\@ }
      \cs_new_protected:Npn
        \mix_parse_windowedarg:w #1 @ #2 @ #3 \q_stop
        {
          \tl_if_blank:nF {#1}
            { \tl_gset:Nn \g_mix_winsize_tl {#1} }
          \tl_if_blank:nF {#2}
            { \tl_gset:Nn \g_mix_winpos_tl {#2} }
        }
      \cs_new_protected:Nn \mix_parse_windowedarg:N
        {
          \exp_after:wN \mix_parse_windowedarg:w #1 @ @ \q_stop
        }
    \group_end:

does the same. (I've made protected as 'best practice.)

On the other hand

    \group_begin:
    \char_set_catcode_active:N\~
    \cs_new:Npn\mix_uribegin:{
      \group_begin:
      %code contributed by E. Gregorio
      \tl_map_inline:nn{.:;?!/"'*+,->=<$@][)(^_`|~}{
        \group_begin:
        \char_set_lccode:nn{`\~}{`##1}
        \tl_to_lowercase:n{\group_end:\cs_set:Npn~}{\token_to_str:N##1}
      }
      \cs_set:Npn\#{\token_to_str:N\#}
      \cs_set:Npn\&{\token_to_str:N\&}
      \cs_set:Npn\%{\token_to_str:N\%}
      \cs_set:Npn\\{\token_to_str:N\\}
      \cs_set:Npn\{{\token_to_str:N\{}
      \cs_set:Npn\}{\token_to_str:N\}}
    }
    \group_end:

does need some way to make active tokens, which is now available as
\char_set_active_eq:NN

    \group_begin:
      \char_set_catcode_other:n { `\~ }
      \cs_new_protected_nopar:Npn \mix_uribegin:
        {
          \tl_map_inline:nn { .:;?!/"'*+,->=<$@[]()^_`|~ }
            {
              \cs_set_nopar:Npx \__mix_tmp:w { \token_to_str:N ##1 }
              \char_set_active_eq:NN ##1 \__mix_tmp:w
            }
          \tl_map_inline:nn { \# \& \% \\ \{ \} }
            { \cs_set_nopar:Npx ##1 { \token_to_str:N ##1 } }
        }
    \group_end:

where I need the change of catcode for ~ so that it is N-type for the
loop/active setting. (Internally \char_set_active_eq:NN does use the
'lowercase trick': we are however providing a wrapper which better
describes the outcome.)

Some other examples from siunitx. I've altered

    \cs_new_protected:Npn
      \@@_unit_format_literal_extras_aux:nN #1#2 {
      \char_set_lccode:nn { `\@ } {#1}
      \tl_to_lowercase:n
        { \tl_replace_all:NnV \l_@@_unit_tl { @ } #2 }
    }

to

    \cs_new_protected:Npn \@@_unit_format_literal_extras_aux:nN #1#2
      {
        \tl_replace_all:Nxn \l_@@_unit_tl
          { \char_generate:nn { #1 } { 12 } }
          {#2}
      }

as here I need to generate a char token from its char code. I've got
several uses of \char_set_active_eq:NN now for situations like the above
media9 example. In places where I want say a 'standard' category code _
I've changed for example

    \char_set_lccode:nn { `\@ } { `\_ }
    \char_set_catcode_math_subscript:N \@
    \tl_to_lowercase:n {
      \group_end:
      \DeclareSIUnit \clight { \text { \ensuremath { c @ { 0 } } } }
      \DeclareSIUnit \electronmass
         { \text { \ensuremath { m @ { \text { e } } } } }
    }

into the slightly tricky

    \cs_set_eq:NN \endgroup \group_end:
    \char_set_catcode_math_subscript:N \_
    \use:n
      {
        \endgroup
        \DeclareSIUnit \clight { \text { \ensuremath { c _ { 0 } } } }
        \DeclareSIUnit \electronmass
          { \text { \ensuremath { m _ { \textup { e } } } } }
      }

which could also have been done using an x-type expansion and
\char_generate:nn (more complex in this case, hence avoiding it).

Finally, one example from ctex, where I've suggested

    \group_begin:
      \char_set_catcode_other:N \P
      \char_set_catcode_other:N \T
    \tex_lowercase:D
      {
        \cs_new:Npn \@@_default_pt:w #1 PT #2 \q_stop { #1 PT }
      }

becomes

    \use:x
       {
        \cs_new:Npn \exp_not:N \@@_default_pt:w
          ##1 \tl_to_str:n { pt } ##2 \exp_not:N \q_stop
          { ##1 \tl_to_str:n { pt } }
       }

using an x-type expansion to make string-like tokens. (Aside: we will
soon extend the l3str module to have more handy 'string constants' such
as \c_backslash_str ready 'out of the box'.)

I hope this helps: depending on the use case, the best/clearest approach
can vary a bit.

Joseph