Received: from mx0.gmx.net (mx0.gmx.net [213.165.64.100]) by h1439878.stratoserver.net (8.14.2/8.14.2/Debian-2build1) with SMTP id p1GDUs6s013930 for ; Wed, 16 Feb 2011 14:30:55 +0100 Received: (qmail 11271 invoked by alias); 16 Feb 2011 13:30:49 -0000 Delivered-To: GMX delivery to rainer.schoepf@gmx.net Received: (qmail invoked by alias); 16 Feb 2011 13:30:46 -0000 Received: from relay2.uni-heidelberg.de (EHLO relay2.uni-heidelberg.de) [129.206.210.211] by mx0.gmx.net (mx111) with SMTP; 16 Feb 2011 14:30:46 +0100 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 p1GDSnq3026125 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 16 Feb 2011 14:28:49 +0100 Received: from listserv.uni-heidelberg.de (localhost.localdomain [127.0.0.1]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id p1GD1PDN018477; Wed, 16 Feb 2011 14:28:42 +0100 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 1435592 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Wed, 16 Feb 2011 14:28:42 +0100 Received: from relay2.uni-heidelberg.de (relay2.uni-heidelberg.de [129.206.210.211]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id p1GDSg4j016140 for ; Wed, 16 Feb 2011 14:28:42 +0100 Received: from mail-gw0-f49.google.com (mail-gw0-f49.google.com [74.125.83.49]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id p1GDSbv1025951 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=FAIL) for ; Wed, 16 Feb 2011 14:28:41 +0100 Received: by gwj20 with SMTP id 20so726935gwj.22 for ; Wed, 16 Feb 2011 05:28:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.151.83.7 with SMTP id k7mr754017ybl.68.1297862916670; Wed, 16 Feb 2011 05:28:36 -0800 (PST) Received: by 10.146.86.8 with HTTP; Wed, 16 Feb 2011 05:28:33 -0800 (PST) References: <4028010D-1144-415D-A984-E3684A7E3EDE@gmail.com> <4D5B770A.2000401@morningstar2.co.uk> <20110216105124.GA5579@oberdiek.my-fqdn.de> <4D5BAE81.4020904@morningstar2.co.uk> Content-Type: text/plain; charset=ISO-8859-1 X-Spam-Whitelist: Message-ID: Date: Wed, 16 Feb 2011 08:28:33 -0500 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Bruno Le Floch Subject: Re: Expandable versions of \uppercase, \MakeUppercase, \lowercase, \MakeLowercase To: LATEX-L@listserv.uni-heidelberg.de In-Reply-To: <4D5BAE81.4020904@morningstar2.co.uk> Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=5D7Q89H36p4U4jfdfC5HDevlx1X2sAZgAaLl3DbFfW0PXxL7WgvovMFXXSEPrACW/b9IW Qp+GhEViZlUW4mdBntgP1X8KwB5tjHCA/yxSZMu7BXBiPs3ujyaoi2xLHDqpg8dk65Dhpb3Lg0c1 iTjGg==V1; X-Resent-By: Forwarder X-Resent-For: rainer.schoepf@gmx.net X-Resent-To: rainer@rainer-schoepf.de Status: R X-Status: X-Keywords: X-UID: 6604 The code for reversing tl follows. I will send the code for full expansion in a nice form soon. As I now understand, the key point in all of this is that we can detect spaces and braces expandably using delimited arguments, and we can then be sure to act on one token at a time. The current implementation ( http://users.aims.ac.za/~bruno/LaTeX/ULcase/ ) - brace group: applies \UL_table__braces to the brace group - token: if \UL_table__ exists, use it, else \UL_table__default{} For e.g., \Lowercase and \Uppercase, we use many macros (one per letter that has a different capitalization than itself), but for other applications I mentionned, there are only a few special tokens. If we want to limit the number of tokens, nothing prevents us from making the \UL_..._default test its argument against a given list to know what to do, closer to what Joseph was doing. It will be ~15 times slower (back to the previous speed) for \Uppercase and \Lowercase, but for the rest, nothing will change. By adding an argument to (almost) every macro, we can manipulate tables of case change with an argument. With some work, this can allow us some pretty crazy things, e.g. \expandwithdefs{\def\foo{FOO}\def\bar#1{Arg=(#1)}}{% \foo\bar{\baz}% } -> FOOArg=(\baz) Tell me if it is useful. % ======== Code for \UL_reverse:n ========= % To reverse, we just need to set the correct output. \input ULcase.sty\relax \long\gdef\UL_reverse:n{\UL_to_case:nn{ULreverse}} % To output one token, place it after the end of what we are reading (this is from % Joseph's implementation). Namely, at the /start/ of the argument of % |\UL_to_case_end:n|. \long\gdef\UL_reverse_output:n#1#2\UL_to_case_end:n#3{% #2\UL_to_case_end:n{#1#3}} \long\gdef\UL_table_ULreverse_default{\UL_reverse_output:n} % The default action is to output the given token. % Spaces don't need a special treatment. % % Braces are treated in the same way as for the ULnil table, except that the % output is done using |\UL_reverse_output:n|. \long\gdef\UL_table_ULreverse_braces#1#2{% \expandafter\expandafter\expandafter\UL_reverse_output:n% \expandafter\expandafter\expandafter{% \expandafter\expandafter\expandafter{\UL_to_case:nn{#1}{#2}}% }% } % ========= Tests \long\def\a{\UL_reverse:n{\a{ b \} cd\{e}f}} \long\def\b{f{e\{dc \} b }\a} \expandonce\a\expandonce\a\expandonce\a \ifx\a\b\show\CORRECT\else\show\WRONG %-- %Regards, %Bruno