Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

\count reference breaks \MakeUppercase

24 views
Skip to first unread message

Oliver Corff

unread,
Dec 26, 2004, 12:51:56 AM12/26/04
to
Dear All,

I don't know whether I fully understand the problem but I noticed
that a simple \digit=#1 \ifcase\digit instead of an \ifcase#1
makes \MakeUppercase fail completely. Here is a minimal file showing
what I talk about. I have twice the same \ifcase construct in \Literal,
once the placeholder passes its value directly, once it is first
stored in a (duely declared) counter named \digit before being passed
on to \ifcase. So, WHY does \Makeuppercase goof in the second case?

Thank you for all comments, and Merry Christmas!

Oliver.

\documentclass{minimal}
\begin{document}
\def\Literal#1{% little command to produce textual number
\ifcase#1
\or one \or two \fi}

Box contains [one]: \fbox{\Literal{1}}

Box contains [ONE]: \fbox{\MakeUppercase{\Literal{1}}}

\newcount\digit
\def\Literal#1{% little command to produce textual number
\digit#1
\ifcase\digit % \ifcase consults value in \digit instead of #1
\or one\or two\fi}

Box contains [one]: \fbox{\Literal{1}}

Box is empty: \fbox{\MakeUppercase{\Literal{1}}}

Box contains [one]: \fbox{\MakeUppercase{\protect\Literal{1}}}
\end{document}


--
Dr. Oliver Corff e-mail: co...@zedat.fu-berlin.de

Herbert Voss

unread,
Dec 26, 2004, 3:28:58 AM12/26/04
to
Oliver Corff wrote:

> \documentclass{minimal}
> \begin{document}
> \def\Literal#1{% little command to produce textual number
> \ifcase#1
> \or one \or two \fi}
>
> Box contains [one]: \fbox{\Literal{1}}
>
> Box contains [ONE]: \fbox{\MakeUppercase{\Literal{1}}}
>
> \newcount\digit
> \def\Literal#1{% little command to produce textual number
> \digit#1

\global\digit#1
% otherwise you'll get the wrong value, MakeUppercase is run
% in a group

> \ifcase\digit % \ifcase consults value in \digit instead of #1
> \or one\or two\fi}
>
> Box contains [one]: \fbox{\Literal{1}}
>
> Box is empty: \fbox{\MakeUppercase{\Literal{1}}}
>
> Box contains [one]: \fbox{\MakeUppercase{\protect\Literal{1}}}

Box contains [one]: \fbox{\MakeUppercase{\Literal{1}}}

> \end{document}

Herbert


--
http://TeXnik.de/
http://PSTricks.de/
ftp://ftp.dante.de/tex-archive/info/math/voss/Voss-Mathmode.pdf
http://www.dante.de/faq/de-tex-faq/
http://www.tex.ac.uk/cgi-bin/texfaq2html?introduction=yes

Heiko Oberdiek

unread,
Dec 26, 2004, 3:24:55 AM12/26/04
to
Oliver Corff <co...@zedat.fu-berlin.de> wrote:

> \documentclass{minimal}
> \begin{document}
> \def\Literal#1{% little command to produce textual number
> \ifcase#1
> \or one \or two \fi}

This definition is expandable.

> Box contains [one]: \fbox{\Literal{1}}
>
> Box contains [ONE]: \fbox{\MakeUppercase{\Literal{1}}}

\MakeUppercase expands its argument, "\Literal{1}" gives "one"
that is converted to uppercase "ONE".

> \newcount\digit

Counter \digit is probably zero.

> \def\Literal#1{% little command to produce textual number
> \digit#1
> \ifcase\digit % \ifcase consults value in \digit instead of #1
> \or one\or two\fi}

The assignment "\digit#1" is not expandable.

> Box contains [one]: \fbox{\Literal{1}}

\fbox implicitely provides a group for the assignment, so
the value of counter \digit remains zero.

> Box is empty: \fbox{\MakeUppercase{\Literal{1}}}

The \assignment "\digit 1" is not expanded. "\ifcase\digit"
is expandable, however \digit has value zero. After expansion
you have "\digit 1" and nothing more. Thus you get an empty box.

> Box contains [one]: \fbox{\MakeUppercase{\protect\Literal{1}}}

\protect prevents expansion, thus "\Literal{1}" remains during
conversion to uppercase. Then \Literal{1} is processed and
yields "one".

> \end{document}

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Heiko Oberdiek

unread,
Dec 26, 2004, 8:14:27 AM12/26/04
to
Herbert Voss <Herber...@gmx.net> wrote:

> Oliver Corff wrote:
>
> > \documentclass{minimal}
> > \begin{document}
> > \def\Literal#1{% little command to produce textual number
> > \ifcase#1
> > \or one \or two \fi}
> >
> > Box contains [one]: \fbox{\Literal{1}}
> >
> > Box contains [ONE]: \fbox{\MakeUppercase{\Literal{1}}}
> >
> > \newcount\digit
> > \def\Literal#1{% little command to produce textual number
> > \digit#1
>
> \global\digit#1
> % otherwise you'll get the wrong value, MakeUppercase is run
> % in a group

It does not matter, if \Literal{...} is put into a group or not.
The assignment and \ifcase are evaluated at different times,
first \ifcase, using the previous value of \digit, then the assignment
with the correct value.

> > \ifcase\digit % \ifcase consults value in \digit instead of #1
> > \or one\or two\fi}
> >
> > Box contains [one]: \fbox{\Literal{1}}
> >
> > Box is empty: \fbox{\MakeUppercase{\Literal{1}}}

Using \digit=0 before, the box is again empty, otherwise the
previous value of \digit is used.

> > Box contains [one]: \fbox{\MakeUppercase{\protect\Literal{1}}}
>
> Box contains [one]: \fbox{\MakeUppercase{\Literal{1}}}
> > \end{document}

Yours sincerely
Heiko <ober...@uni-freiburg.de>

Herbert Voss

unread,
Dec 26, 2004, 9:26:39 AM12/26/04
to
Heiko Oberdiek wrote:

> It does not matter, if \Literal{...} is put into a group or not.
> The assignment and \ifcase are evaluated at different times,
> first \ifcase, using the previous value of \digit, then the assignment
> with the correct value.

sorry Heiko, but I do not understand what you want to
say? Do you mean that \global\digits#1 isn't a solution?

Heiko Oberdiek

unread,
Dec 26, 2004, 10:40:43 AM12/26/04
to
Herbert Voss <Herber...@gmx.net> wrote:

> Heiko Oberdiek wrote:
>
> > It does not matter, if \Literal{...} is put into a group or not.
> > The assignment and \ifcase are evaluated at different times,
> > first \ifcase, using the previous value of \digit, then the assignment
> > with the correct value.
>
> sorry Heiko, but I do not understand what you want to
> say? Do you mean that \global\digits#1 isn't a solution?

Yes. :-(

\documentclass{minimal}
\begin{document}

\newcount\digit
\def\Literal#1{% little command to produce textual number

\global\digit#1


\ifcase\digit % \ifcase consults value in \digit instead of #1

zero%


\or one\or two\fi}

Box contains [1/ZERO]: \fbox{\MakeUppercase{\Literal{1}}}

Box contains [2/ONE]: \fbox{\MakeUppercase{\Literal{2}}}

Herbert Voss

unread,
Dec 26, 2004, 1:05:55 PM12/26/04
to
Heiko Oberdiek wrote:

> Herbert Voss <Herber...@gmx.net> wrote:

>>sorry Heiko, but I do not understand what you want to
>>say? Do you mean that \global\digits#1 isn't a solution?
>
>
> Yes. :-(

understood

thanks,Herbert

Herbert Voss

unread,
Dec 26, 2004, 1:21:40 PM12/26/04
to
Herbert Voss wrote:

> understood

but now I do not understand why this works ...

HErbert

\documentclass{minimal}
\usepackage{textcase}
\begin{document}

\def\ULiteral#1{
\expandafter\uppercase\expandafter{\Literal{#1}}%


}
\newcount\digit
\def\Literal#1{% little command to produce textual number

\global\digit#1\relax
\ifcase\digit% \ifcase consults value in \digit instead of #1
zero%
\or one\or two\or three \or four\fi}

Box contains [1/ZERO]: \fbox{\ULiteral{1}}

Box contains [2/TWO]: \fbox{\ULiteral{2}}

Box contains [4/FOUR]: \fbox{\ULiteral{4}}
\end{document}

Heiko Oberdiek

unread,
Dec 26, 2004, 1:41:21 PM12/26/04
to
Herbert Voss <Herber...@gmx.net> wrote:

> Herbert Voss wrote:
>
> > understood
>
> but now I do not understand why this works ...
>
> HErbert
>
> \documentclass{minimal}
> \usepackage{textcase}
> \begin{document}
>
> \def\ULiteral#1{
> \expandafter\uppercase\expandafter{\Literal{#1}}%
> }
> \newcount\digit
> \def\Literal#1{% little command to produce textual number
> \global\digit#1\relax
> \ifcase\digit% \ifcase consults value in \digit instead of #1
> zero%
> \or one\or two\or three \or four\fi}

\uppercase doesn't expand its argument.

* \ULiteral{1}


\expandafter\uppercase\expandafter{\Literal{#1}}

* \uppercase{%
\global\digit 1\relax
\ifcase\digit zero\or one\or two\or three\or four\fi
}
* Executing of \uppercase:
\global\digit 1\relax
\ifcase\digit ZERO\or ONE\or TWO\or THREE\or FOUR\fi
* ONE

Yours sincerely
Heiko <ober...@uni-freiburg.de>

co...@zedat.fu-berlin.de

unread,
Dec 26, 2004, 10:09:09 PM12/26/04
to
Herbert Voss <Herber...@gmx.net> wrote:

: \global\digit#1


: % otherwise you'll get the wrong value, MakeUppercase is run
: % in a group

Dear Herbert and Heiko,

Thank you very much for the discussion. You helped me end a weekend of
headache. Applying \global does the job in my real macro (from which this
minimal test case was derived). I had been unaware of the grouping
introduced by \MakeUppercase.

Oliver.

co...@zedat.fu-berlin.de

unread,
Dec 26, 2004, 10:11:34 PM12/26/04
to
Heiko Oberdiek <ober...@uni-freiburg.de> wrote:

: It does not matter, if \Literal{...} is put into a group or not.


: The assignment and \ifcase are evaluated at different times,
: first \ifcase, using the previous value of \digit, then the assignment
: with the correct value.

Thank you here. Timing is critical, I understand.

Oliver.

Piet van Oostrum

unread,
Dec 27, 2004, 4:53:33 AM12/27/04
to
>>>>> Herbert Voss <Herber...@gmx.net> (HV) wrote:

HV> Herbert Voss wrote:
>> understood

HV> but now I do not understand why this works ...

HV> HErbert

HV> \documentclass{minimal}
HV> \usepackage{textcase}
HV> \begin{document}

HV> \def\ULiteral#1{
HV> \expandafter\uppercase\expandafter{\Literal{#1}}%

The first \expandafter is superfluous (\uppercase does the right thing
anyway).
--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.van....@hccnet.nl

Donald Arseneau

unread,
Dec 31, 2004, 5:53:56 AM12/31/04
to
Herbert Voss <Herber...@gmx.net> writes:

> but now I do not understand why this works ...

> \def\ULiteral#1{
> \expandafter\uppercase\expandafter{\Literal{#1}}%

The original question was about \MakeUppercase which pre-expands
its argument (so that special characters will be upper-cased).
\MakeUppercase's text is a "moving argument" and the \Literal
(or \ifcase) is a fragile command (because it mixes assignments
and expansion). A command like \Literal should be defined with
\DeclareRobustCommand, so that you don't need to insert \protect
every time.

Donald Arseneau as...@triumf.ca

0 new messages