The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Implementation of Switch-Case Statement in TeX
 There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic. There was an error processing your request. Please try again. Standard view   View as tree
 12 messages

From:
To:
Cc:
Followup To:
Subject:
 Validation: For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon.

More options Apr 27 2009, 5:41 pm
Newsgroups: comp.text.tex
From: Martin Scharrer <mar...@scharrer-online.de>
Date: Mon, 27 Apr 2009 14:41:17 -0700 (PDT)
Local: Mon, Apr 27 2009 5:41 pm
Subject: Implementation of Switch-Case Statement in TeX
Hi,

I recently had the idea about a switch case statement for use in LaTeX
packages. I needed to check user input (a string) and execute
different macros on different inputs.  of a list. Because I could not
find a switch-case statement I implemented it using code like this:
\def\@tempa{foo}
\ifx\@tempa\user@input
...
\else
\def\@tempa{bar}
\ifx\@tempa\user@input
...
\fi\fi

Now I found the time to code a switch-case statement in plainTeX:

My idea about the syntax is:

\switch{<input value>}
\case{<case 1 value>}{<case 1 code}
\case{<case 2 value>}{<case 2 code}
...
\case{<case n value>}{<case n code}
\default{<default code>}
\endswitch

Instead of \endswitch there could also be \hctiws (switch reversed
like \fi for \if).
I also implemented versions of \switch and \case which expand there
argument: \eswitch, \ecase ('e' like 'edef'), or
check the definition instead the content: \switchx, \casex ('x' like
'ifx'). The different \switch and \case macros can be mixed.

The switch-statement stores the code in a macro similar to macros like
\@ifnextchar and uses a TeX group to localise its internal macros. The
code of the selected switch is then executed after the end of the
group. This makes the switch cascade-able and allows the case code to
include macros which read the tokens after the \endswitch.

Here my code. It is not yet fully tested. Comments are very welcome. I
might provide this as a package. Any suggestion about a name? Maybe
'switch' or 'swcase'. 'switchcase' might be too long.

%%%%%%%%%%% switch.tex %%%%%%%%%%%%%
\catcode\@=\catcode\A

% Normal (no expansion):

\def\switch#1{%
\begingroup
\let\switch@exec\empty
\def\switch@want{#1}%
\ignorespaces

}

\def\case#1#2{%
\def\switch@might{#1}%
\ifx\switch@might\switch@want
\def\switch@exec{#2}%
\expandafter\switch@skiprest
\fi
\ignorespaces

}

% Expansion of the argument ('e' as in 'edef'):

\def\eswitch#1{%
\begingroup
\let\switch@exec\empty
\edef\switch@want{#1}%
\ignorespaces

}

\def\ecase#1#2{%
\edef\switch@might{#1}%
\ifx\switch@might\switch@want
\def\switch@exec{#2}%
\expandafter\switch@skiprest
\fi
\ignorespaces

}

% Check definition not content ('x' as in 'ifx'):

\def\switchx#1{%
\begingroup
\let\switch@exec\empty
\let\switch@want#1\relax
\ignorespaces

}

\def\casex#1#2{%
\ifx\switch@want#1\relax
\def\switch@exec{#2}%
\expandafter\switch@skiprest
\fi
\ignorespaces

}

% Default case. Identical for all different switch statements.

\def\default#1{%
\def\switch@exec{#1}%
\switch@skiprest

}

\def\switch@skiprest#1\endswitch{%
\expandafter\switch@realend
\expandafter{\switch@exec}%

}

\def\switch@realend#1{%
\endgroup
#1%

}

\def\endswitch{%

}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Some Testcases:
\newlinechar=^^J

\def\test#1{%
\switch{#1}
\case{test1}{\message{test1^^J}}
\case{test2}{\message{test2^^J}}
\case{test3}{\message{test3^^J}}
\case{test4}{\message{sub-switch 1:^^J }
\switch{abc}
\case{a}{\message{a^^J}}
\case{ab}{\message{ab^^J}}
\case{abc}{\message{abc^^J}}
\endswitch
}
\case{test5}{\message{sub-switch 2:^^J }\test{test1}}
\default{\message{default^^J}}
\endswitch

}

\message{^^J switch: ^^J}
\test{test1}
\test{test4}
\test{other}
\test{test5}

\def\testveca{test1}
\def\testvecb{test2}
\def\testvecc{test3}
\def\testvecd{test4}
\let\testwant\testvecb

\message{^^J switchx: ^^J}
\switchx{\testwant}
\casex{\testveca}{\message{testa^^J}}
\casex{\testvecb}{\message{testb^^J}}
\casex{\testvecc}{\message{testc^^J}}
\casex{\testvecd}{\message{testd^^J}}
\default{\message{default2^^J}}
\endswitch

\def\testwant{\testvecc}

\message{^^J eswitch: ^^J}
\eswitch{\testwant}
\ecase{\testveca}{\message{testa^^J}}
\ecase{\testvecb}{\message{testb^^J}}
\ecase{\testvecc}{\message{testc^^J}}
\ecase{\testvecd}{\message{testd^^J}}
\default{\message{default2^^J}}
\endswitch

% End TeX of LaTeX run
\csname bye\endcsname
\end{document}

%%%%%%%%%%% END OF CODE %%%%%%%%%%%%

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 27 2009, 6:22 pm
Newsgroups: comp.text.tex
From: Dan Luecking <LookIn...@uark.edu>
Date: Mon, 27 Apr 2009 17:22:43 -0500
Local: Mon, Apr 27 2009 6:22 pm
Subject: Re: Implementation of Switch-Case Statement in TeX
On Mon, 27 Apr 2009 14:41:17 -0700 (PDT), Martin Scharrer

Some observations:

The different switch commands are necessary, but the
user need not have to remember different \case commands:

\def\initswitch{% shorthand
\begingroup
\let\switch@exec\empty

}

\def\switch#1{%
\initswitch
\def\switch@want{#2}% or \edef for \eswitch
\let\case\normalcase% or \expandingcase
\ignorespaces
}

\def\switchx#1{
\initswitch
\let\switch@want#2%
\let\case\meaningcase
\ignorespaces

}

Except for the first line, all the case commands are
nearly the same, so code could be shared.

\def\normalcase#1{%
\def\switch@might{#1}% \edef for \expandingcase
\fincase

}

\def\meaningcase#1{%
\let\switch@might#1%
\fincase
}

\long\def\fincase#1{% \long in case of \par
\ifx\switch@might\switch@want
\def\switch@exec{#1}%
\expandafter\switch@skiprest
\fi
\ignorespaces

}
>\def\switch@skiprest#1\endswitch{%
>  \expandafter\switch@realend
>  \expandafter{\switch@exec}%
>}

>\def\switch@realend#1{%
>  \endgroup
>  #1%
>}

Or
\def\switch@skiprest#1\endswitch{%
\expandafter\endgroup\switch@exec

}

Dan
To reply by email, change LookInSig to luecking

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 27 2009, 6:33 pm
Newsgroups: comp.text.tex
From: Martin Scharrer <mar...@scharrer-online.de>
Date: Mon, 27 Apr 2009 15:33:19 -0700 (PDT)
Local: Mon, Apr 27 2009 6:33 pm
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 27, 11:22 pm, Dan Luecking <LookIn...@uark.edu> wrote:

I had this idea too, but I decided that in some applications different
switch and case statements need to be mixed, e.g. a \ecase inside
\switch if the case value is given by a expression which must first be
expanded. Also a non-expanding \case inside a \eswitch where only the
user input muse be expanded.
This way the whole thing is much more flexible.

> Or
> \def\switch@skiprest#1\endswitch{%
>   \expandafter\endgroup\switch@exec
> }

Thanks for that suggestion. I just learned something.

Best,
Martin

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 28 2009, 5:01 am
Newsgroups: comp.text.tex
From: Donald Arseneau <a...@triumf.ca>
Date: Tue, 28 Apr 2009 02:01:23 -0700 (PDT)
Local: Tues, Apr 28 2009 5:01 am
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 27, 2:41 pm, Martin Scharrer <mar...@scharrer-online.de> wrote:

> I recently had the idea about a switch case statement for use in LaTeX
> packages. I needed to check user input (a string) and execute
> different macros on different inputs.

In general, this is done with \csname

\csname IDENT:<sanitized_user_text>\endcsname

where the IDENT string is different from regular macros and
for different switch uses.

You would define

\@namedef{IDENT:<case 1 text>}{<case 1 code>}
\@namedef{IDENT:<case 2 text>}{<case 2 code>}

Donald Arseneau                                      a...@triumf.ca

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 28 2009, 5:27 am
Newsgroups: comp.text.tex
From: Martin Scharrer <mar...@scharrer-online.de>
Date: Tue, 28 Apr 2009 02:27:37 -0700 (PDT)
Local: Tues, Apr 28 2009 5:27 am
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 28, 10:01 am, Donald Arseneau <a...@triumf.ca> wrote:

Thanks, I knew and use this in some packages, too. E.g. a lot in my
new package 'tikz-timing' where the user input causes a diagram to be
drawn.
However, in cases where the user input must be checked in different
places (with different case code) this method becomes, IMHO, a little
extensive, because a lot of macros must be defined and cascaded
switches are not easily possible. However, this solution with \@nameuse
{IDENT:<sanit. user input> should be expandable, while my switch
statement is not.

> Your macros look good though..

Thanks.

Martin

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 28 2009, 5:36 am
Newsgroups: comp.text.tex
From: Jonathan Fine <J.F...@open.ac.uk>
Date: Tue, 28 Apr 2009 10:36:05 +0100
Local: Tues, Apr 28 2009 5:36 am
Subject: Re: Implementation of Switch-Case Statement in TeX

Martin Scharrer wrote:
> Hi,

> I recently had the idea about a switch case statement for use in LaTeX
> packages. I needed to check user input (a string) and execute
> different macros on different inputs.  of a list. Because I could not
> find a switch-case statement I implemented it using code like this:
> \def\@tempa{foo}
> \ifx\@tempa\user@input
>  ...
> \else
> \def\@tempa{bar}
> \ifx\@tempa\user@input
>  ...
> \fi\fi

I wrote an article about basic control sequences (including \switch and
\CASE) in the 1990s.
http://www.tug.org/TUGboat/Articles/tb13-1/tb34fine.pdf
http://www.tug.org/TUGboat/Articles/tb14-1/tb38fine.pdf

Please take a look at them.

--
Jonathan

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 28 2009, 5:46 am
Newsgroups: comp.text.tex
From: Martin Scharrer <mar...@scharrer-online.de>
Date: Tue, 28 Apr 2009 02:46:55 -0700 (PDT)
Local: Tues, Apr 28 2009 5:46 am
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 28, 10:36 am, Jonathan Fine <J.F...@open.ac.uk> wrote:

Thank you so much for the links. I will have a deeper look at them on
the weekend.

I just saw a package 'control.sty' mentioned in one of this
publications, but I can't find it on CTAN.

Thanks,
Martin

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 28 2009, 6:29 am
Newsgroups: comp.text.tex
From: Jonathan Fine <J.F...@open.ac.uk>
Date: Tue, 28 Apr 2009 11:29:20 +0100
Local: Tues, Apr 28 2009 6:29 am
Subject: Re: Implementation of Switch-Case Statement in TeX

Martin Scharrer wrote:
>> I wrote an article about basic control sequences (including \switch and
>> \CASE) in the 1990s.
>>    http://www.tug.org/TUGboat/Articles/tb13-1/tb34fine.pdf
>>    http://www.tug.org/TUGboat/Articles/tb14-1/tb38fine.pdf

>> Please take a look at them.
> Thank you so much for the links. I will have a deeper look at them on
> the weekend.

> I just saw a package 'control.sty' mentioned in one of this
> publications, but I can't find it on CTAN.

Apologies.  I don't think it ever got to onto CTAN.  I've probably got a
copy at home, somewhere.

There's nothing in that file that's not in the articles.

--
Jonathan

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 28 2009, 4:14 pm
Newsgroups: comp.text.tex
From: Donald Arseneau <a...@triumf.ca>
Date: Tue, 28 Apr 2009 13:14:06 -0700 (PDT)
Local: Tues, Apr 28 2009 4:14 pm
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 28, 2:27 am, Martin Scharrer <mar...@scharrer-online.de> wrote:

> On Apr 28, 10:01 am, Donald Arseneau <a...@triumf.ca> wrote:
> >  \csname IDENT:<sanitized_user_text>\endcsname
> {IDENT:<sanit. user input> should be expandable, while my switch
> statement is not.

It depends on how much sanitization is needed, which can be a problem.

I forget already, is \scantokens expandable?  If so, it would be much
better for this than the old \def...\meaning.

Donald Arseneau

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 29 2009, 6:39 am
Newsgroups: comp.text.tex
From: Martin Scharrer <mar...@scharrer-online.de>
Date: Wed, 29 Apr 2009 03:39:49 -0700 (PDT)
Local: Wed, Apr 29 2009 6:39 am
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 28, 9:14 pm, Donald Arseneau <a...@triumf.ca> wrote:
> On Apr 28, 2:27 am, Martin Scharrer <mar...@scharrer-online.de> wrote:

> > On Apr 28, 10:01 am, Donald Arseneau <a...@triumf.ca> wrote:
> > >  \csname IDENT:<sanitized_user_text>\endcsname
> > {IDENT:<sanit. user input> should be expandable, while my switch
> > statement is not.

> It depends on how much sanitization is needed, which can be a problem.

> I forget already, is \scantokens expandable?  If so, it would be much
> better for this than the old \def...\meaning.

Are you thinking to use \scantokens to verbatim'ise the user input? In
this case
you need \catcode calls which are assignments (unexpandable) or aren't
they?

You don't need sanitization in all cases. \csname expands the macros
which allows the user to provide it's input as macro which is normally
what you want.
If a unexpandable macro is provided \csname will fail (at least I
think so) and the user will become the appropriate error message. Then
it is his/her problem.

Martin

To post a message you must first join this group.
You do not have the permission required to post.
More options Apr 30 2009, 8:34 pm
Newsgroups: comp.text.tex
From: Donald Arseneau <a...@triumf.ca>
Date: Thu, 30 Apr 2009 17:34:41 -0700 (PDT)
Local: Thurs, Apr 30 2009 8:34 pm
Subject: Re: Implementation of Switch-Case Statement in TeX
On Apr 29, 3:39 am, Martin Scharrer <mar...@scharrer-online.de> wrote:

Ah right, so still no better than \meaning.

> If a unexpandable macro is provided \csname will fail (at least I
> think so) and the user will become the appropriate error message. Then
> it is his/her problem.

Yes, it was sanitization of such things that I was thinking about.
Your code using \def and \ifx works fine (I expect) with such
strings whereas unsanitized \csname will fail.

Donald

To post a message you must first join this group.
You do not have the permission required to post.
More options May 1 2009, 4:10 pm
Newsgroups: comp.text.tex
From: Morten Høgholm <morten.hoegh...@gmail.com>
Date: Fri, 01 May 2009 22:10:54 +0200
Local: Fri, May 1 2009 4:10 pm
Subject: Re: Implementation of Switch-Case Statement in TeX

I the expl3 code we have case switches that look similar to this. From the
documentation (in l3prg.dtx) for the function called \prg_case_int:nnn we
have

%  This function evaluates the first \meta{integer expr} and then compares
it
%  to the values found in the list. Thus the expression
% \begin{verbatim}
% \prg_case_int:nnn{2*5}{
%   {5}{Small}  {4+6}{Medium}  {-2*10}{Negative}
% }{Other}
% \end{verbatim}
%  evaluates first the term to look for and then tries to find this
%  value in the list of values. If the value is found, the code on its
%  right is executed after removing the remainder of the list. If the
%  value is not found, the \meta{else case} is executed. The example
%  above will return `Medium''.

Others exist and the code is fairly simple. You might be able to find
inspiration in the implementation or come up with suggestions for
improvements.

--
Morten

To post a message you must first join this group.
You do not have the permission required to post.
 End of messages
 « Back to Discussions « Newer topic Older topic »