Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) by h1439878.stratoserver.net (8.14.4/8.14.4/Debian-2ubuntu2.1) with ESMTP id t8HBQWmT012578 for ; Thu, 17 Sep 2015 13:26:33 +0200 Received: from relay2.uni-heidelberg.de ([129.206.119.212]) by mx-ha.gmx.net (mxgmx103) with ESMTPS (Nemesis) id 0MRRiO-1Z9yt00C9A-00Sd5Q for ; Thu, 17 Sep 2015 13:26:27 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [129.206.100.94]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id t8HBOgXY026063 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 17 Sep 2015 13:24:43 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [127.0.0.1]) by listserv.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id t8H66P7Q022906; Thu, 17 Sep 2015 13:24:42 +0200 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 12534726 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Thu, 17 Sep 2015 13:24:42 +0200 Received: from relay.uni-heidelberg.de (relay.uni-heidelberg.de [129.206.100.212]) by listserv.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id t8HBOfZ8028484 for ; Thu, 17 Sep 2015 13:24:42 +0200 Received: from aso-006-i438.relay.mailchannels.net (aso-006-i438.relay.mailchannels.net [23.91.64.119]) by relay.uni-heidelberg.de (8.14.1/8.14.1) with ESMTP id t8HBOWeX015282 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 17 Sep 2015 13:24:37 +0200 X-Sender-Id: netnames|x-authuser|joseph.wright@morningstar2.co.uk Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 83C67600BB for ; Thu, 17 Sep 2015 11:24:31 +0000 (UTC) Received: from smtp3.easily.co.uk (ip-10-229-11-165.us-west-2.compute.internal [10.229.11.165]) by relay.mailchannels.net (Postfix) with ESMTPA id 04AE961A8B for ; Thu, 17 Sep 2015 11:24:29 +0000 (UTC) X-Sender-Id: netnames|x-authuser|joseph.wright@morningstar2.co.uk Received: from smtp3.easily.co.uk (smtp3.easily.co.uk [10.42.130.4]) (using TLSv1 with cipher DHE-RSA-AES256-SHA) by 0.0.0.0:2500 (trex/5.5.1); Thu, 17 Sep 2015 11:24:31 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: netnames|x-authuser|joseph.wright@morningstar2.co.uk X-MailChannels-Auth-Id: netnames X-MC-Loop-Signature: 1442489070571:63724279 X-MC-Ingress-Time: 1442489070570 Received: from [139.222.114.163] (port=63099 helo=[139.222.114.163]) by smtp3.easily.co.uk with esmtpa (Exim 4.43) id 1ZcXIh-0007K5-OM for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Thu, 17 Sep 2015 12:24:27 +0100 References: <55FA92C9.7020604@morningstar2.co.uk> <20150917110019.GA30131@hzdr.de> X-Enigmail-Draft-Status: N1110 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: 7bit X-AuthUser: joseph.wright@morningstar2.co.uk Message-ID: <55FAA2EB.6020708@morningstar2.co.uk> Date: Thu, 17 Sep 2015 12:24:27 +0100 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Joseph Wright Subject: Re: \tl_to_(lower|upper)case:n - Generating char tokens To: LATEX-L@LISTSERV.UNI-HEIDELBERG.DE In-Reply-To: <20150917110019.GA30131@hzdr.de> Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: Envelope-To: X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3; X-GMX-Antivirus: 0 (no virus found) X-UI-Filterresults: notjunk:1;V01:K0:u12EJZ09Zx0=:pYVhoKPBp7DG1byaqCKdJcs+rZ 52RHr9+WkV3WnddfasxrcoRBWOty5tEBteRqsl688nKsz3wxBGCjkz0/aJwWigEM38Xrh/nEg mlJsjImLXA2yA72B6Zs0r22uU8cm2FTwbVfEvROV6/F2pdMwTifMbf31MHgiVR/WePn4nLdjl /l+D0ScypL8f3wbJYdsLOqm4uC1dqK4vJjk7rg3U0De+uRAUnrCgv3wQCQkBOfATZoHxyr6ZA Ov2qmfIJKxlGaXAV93B9ReMR4TMBnSyvUwbNrPKAasm/HNm3IGKCLUEPuEV91eQqJMJvsnKpp GH9hyYSuX8oJ/oHiSi9sakEMeCcmQAawpO1oGukiNkqtZYJ7jyAADKjsRC1h6Ok0NnEMpp+V1 bJ9SxHZ/ZYtjOUCPFog4sca+fXMVPaKQIr63ukO6WYqdNwHqeAu0jGOohDKqb9r14V5h3LZtL EZQ1NDx3cqtUL8s9+gLtkQitwUlYssQxP2bLBDNerVHZImwFkHKJ/PsyVtIzBDuxhTBQYI6BN b4fJM/6bDVaNgsPadSPf/mgpEJKT68wetHyWDyX1eVP9gxm59dwWE9/PF5Z9VdTaaF61doHHe ejdZyu8mESR9PSJkIlSCBcLmnterqQIeMHdJi107bNr/vMYI3s5XKoYuLbV3jzyJ4LXeHLmts 8rI8MT6ZvJU5MfNEaHLZokhyLVHk9L4gQPpp6edTuYm9MhmhACWfv/jdWdB26ro77I/UG2bJj yXE/DXrxzRFpnHuxKPQ7ODHU8pd2UZ7dRhjzEV9bl7Z+2wGHQgRIZv08lvzsuJmwDHkmCGwpM OpjZzpJXPcKd2TqIPi1jaz0ZIra4OwHUAunu/a4KEWqRWFI5bN1T311GVZCNpPqKqkQuWRPo1 Ljd21nVnQ7137hBvvie3xk5eKTEUmM9Q5t+B7NWP+MjoE4VX1gvt9hxiV+LRxFZHbaomO/kO6 6vvmyuNAKh+8iURC7ZUFxUI+0szqY4vVzJXd1aXFJNTJ6yRC73EwYs46zhhZ9rLfZGjCouClL tu+IBMA7M9v/jAw/twRdbhLIH1a9ba8KkovXSpexwBiFY3bhTTKbathSfbcVfL9fcIDu1u8Wu WNduuKJW7zYRiuww2zLgatfoBNPip6DCtKCxkOmLU+fr0rZ6b9T6vPgrUsWwceYfEYhpobMpq CnJDK0z5XA6JoS9ZBMX1LVeFBAioh5ZYf30XWGq43LpvARD9o6bcdudYolykQU+ZJ1+kaeELJ W4aZbILwUGDXsf1JTH3Md/Qmf05EzMrFlrRs0uwAk/4ulDuCZaQghh5IJqOFqFqccWsDU3nzA m4kjvD/RlTVXOdeQ/1/0DTjm64nrnBM/94NZEx+tUpAUEDLVFn849R8cQKIDg9e4tbMApaxL5 6HV2LtfDpBwjEEbKPdef/KCUYGt7MZ1rZr7iGPMo8LehZp5ooEJcibAwMwNH97TnBxJSJByKz l+OS/TpQQk4wOcBR5R9pf6JBe0jqrvDEbDfszHiXyvNBZJHEl0l2nnvZsEUJY2hYZja+XQnw= = X-UI-Loop:V01:amfSenVOlk4=:QxJYXwmUVsZOvTTkJxDjhJeVHaGecUBlAFrxh4gOTsk= X-UI-Out-Filterresults: notjunk:1;V01:K0:SUPh5Wxs/N4=:1AjvQ9/sOaNrknPgS8szAA iqyB5X2rg5N+LL9MvEXABRv6n33Ey5tC2Vpn6qztaQ3KoB+QjiiNtZetzz49hFAJ2zpYpCcJ2 /RsVXF40j6nI/pQxS5k4r97bynTCsx/6GjBJWAFs8KeF9l8gM7ru1wtGb+HgM0rZ9weBQlxGw elIaVsSx0OY10kZzvyv1zhSfJoxHK/HR2Gszgc2L9Uz8jFY8UBjhUdPQKiFanUJkAdfCoL+lI l+x0XZfeZcRSAI8ZsDG9dSWIA5MjtBIdZjtEXx9ec1MMEKDFOJVVz7bgvGoVNanwjsWBCCdkD atcSXqdm9+yd1uTxzsXXXIaaMJiKFRmrY2lVZoW35dNW+xUSlxuK4nxduOZeyqyYTO+T//9ts mreO0fW/VLk3Ba79ShLMsY2AFfEniFPlFD2/7Mi1Y8wqFn9/4LdtHyE36F3byWUr8wxjWT83l 6CocWHAvSz/d2ZyCPqvn1pKVdxGxx8Cs+fkiliGOkEvId7XnDCkT X-Scanned-By: MIMEDefang 2.71 on 85.214.41.38 Status: R X-Status: X-Keywords: X-UID: 7882 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