From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.comp.tex.context/4113 Path: main.gmane.org!not-for-mail From: Taco Hoekwater Newsgroups: gmane.comp.tex.context Subject: Re: ROT13 and alike Date: Sat, 17 Feb 2001 19:30:23 +0100 Sender: owner-ntg-context@let.uu.nl Message-ID: <3A8EC33F.3DB883D3@quicknet.nl> References: <001101c09844$ebd9ee20$a3ccfea9@nuovo> NNTP-Posting-Host: coloc-standby.netfonds.no Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: main.gmane.org 1035394799 22961 80.91.224.250 (23 Oct 2002 17:39:59 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Wed, 23 Oct 2002 17:39:59 +0000 (UTC) Original-To: ntg-context@ntg.nl Xref: main.gmane.org gmane.comp.tex.context:4113 X-Report-Spam: http://spam.gmane.org/gmane.comp.tex.context:4113 Giuseppe Bilotta wrote: > > > Any suggestions? Here is a solution that is just a little bit more robust than your one: it obeys spaces and is properly nested. It also allows primitives in the input string (\par, for example); and \unexpanded macros that dont have an argument. Note that this is a hacker's version: you can't use this to process arbitrary text: macro's that expand into something and e.g. accents won't work! In general, it is very hard to do this kind of stuff safely in TeX. A verbatim module would probably be the best solution. OTOH, my approach allows: \section{\ROT{A section}} % begin of code % % this is the converter itself. If it has to do much more than % this, it might be better to use an \ifcase instead, but that % complicates the code rather a lot \def\dorot#1{% \ifx a#1n\else \ifx b#1o\else \ifx c#1p\else \ifx d#1q\else \ifx e#1r\else \ifx f#1s\else \ifx g#1t\else \ifx h#1u\else \ifx i#1v\else \ifx j#1w\else \ifx k#1x\else \ifx l#1y\else \ifx m#1z\else \ifx n#1a\else \ifx o#1b\else \ifx p#1c\else \ifx q#1d\else \ifx r#1e\else \ifx s#1f\else \ifx t#1g\else \ifx u#1h\else \ifx v#1i\else \ifx w#1j\else \ifx x#1k\else \ifx y#1l\else \ifx z#1m\else #1% \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi } % The startcommand. \afterassigment executes the next assignment % first, (in this case a \let assignment), then afterward % it expands the command between itself and the assignment. % at that time, the assigment has already been done, so inside % \dostartROT, \nexttok is the next token from the input. % % The trick with the space at the end is the way to make sure % that spaces are seen as well: only *one* optional space % is allowed after an equals sign. If there appears another % space (that is: a space in the input), it will be assigned % instead. \def\startROT{% % here is the place to do other stuff, like % \bf or whatever. The next line has to stay % at the end of the definition. \afterassignment \dostartROT \let\nexttok= } \def\stopROT{} % \afterfi is a trick to prevent stack buildup if the text string % is very long (as it might be) \def\afterfi#1\fi{\fi#1} % if the next token is \stopROT, execute it. % otherwise, start over: \def\dostartROT{% \ifx \nexttok \stopROT \stopROT \else \dorot{\nexttok}\afterfi\startROT \fi } % parameter version: \def\ROT#1{\startROT#1\stopROT} % end of code Greetings, Taco