I don't seem to be able to capitalize a letter that has been assigned to \let
.
\let\zTest=t
\uppercase{\zTest} % still small
ADDENDUM: I've tried \def\zTest{t}
just now and it didn't work either (but \uppercase{t}
works).
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It only takes a minute to sign up.
Sign up to join this community\uppercase
and \lowercase
{
of the ⟨balanced text⟩
that is to be uppercased/lowercased.⟨filler⟩
-token that is to be uppercased/lowercased. (⟨filler⟩
denotes a sequence of \relax
and/or explicit/implicit spaces.)When using \csname..\endcsname
instead of using the control-word-token directly, you can probably do somehing like this:
\let\zTest=t
\let\ZTEST=T
\let\ztest=t
\def\Ztest{t}
% \zTest and \ZTEST and \ztest are implicit character tokens.
% Let`s use uppercased/lowercased \csname..\endcsname for selecting
% which implicit character token to use:
\csname zTest\endcsname
\uppercase{\csname zTest\endcsname}%
\lowercase{\csname zTest\endcsname}%
% \Ztest is a macro, expanding to explicit character token "t".
% You can use \expandafter for triggering "toplevel-expansion"
% while \uppercase/\lowercase still searches the "{" that
% marks the begin of the balanced text:
\Ztest
\uppercase\expandafter{\Ztest}%
\lowercase\expandafter{\Ztest}%
% With more recent TeX-engines, where \expanded is available,
% you can do:
% \lowercase\expandafter{\expanded{\Ztest}}%
% "toplevel-expansion" of \expanded<general text> will deliver
% "total expansion" of the content of the <general text>'s
% <balanced text>
\bye
The following is a macro that is able to uppercase a let token if it was let to a letter (e.g., with \let\foo=t
assuming standard category codes). It does so by first checking whether the magic tokens the letter
are the start of the meaning of the passed in token, and then grabs the letter following it and uppercases that, if the meaning doesn't seem to be a letter then the input is output. The test is only applied to the first token of the input, but it is not checked whether the input is only a single token (so \uppercaselettoken{t more stuff}
would see that t
is a letter but passes more stuff
to \uppercase
, too. So this is only a proof-of-concept not a stable implementation.
\documentclass[]{article}
\let\foo=t
\makeatletter
\def\uppercaselettoken@ifletter#1%
{%
\def\uppercaselettoken@ifletter##1#1##2\end
{%
\if\relax\detokenize{##2}\relax
\expandafter\@secondoftwo
\else
\if\relax\detokenize{##1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\expandafter\@firstoftwo}
{\expandafter\@secondoftwo}%
\fi
}%
\def\uppercaselettoken@letter#1##1\end{\uppercase{##1}}%
}
\expandafter\uppercaselettoken@ifletter\expandafter{\detokenize{the letter }}
\long\edef\uppercaselettoken@#1#2%
{%
\noexpand\uppercaselettoken@ifletter#1\detokenize{the letter }\noexpand\end
{%
\noexpand\uppercaselettoken@letter#1\noexpand\end
}%
{#2}% not a letter, no uppercasing
}
\newcommand\uppercaselettoken[1]
{%
\expandafter\uppercaselettoken@\expandafter{\meaning#1}{#1}%
}
\makeatother
\usepackage{unravel}
\begin{document}
\uppercaselettoken{\foo}
\uppercaselettoken{t}% works too
\end{document}
\tl_upper_case:n
, but one could define a variant (something like \tl_upper_case_e:n
) which does this. It's your choice :)
\char
in situations where uppercasing/lowercasing of initials and shortcuts of names and the like is to be prevented.. ;->
Nov 17, 2019 at 17:45
While it is possible to implement something that interrogates the meaning of unexpandable tokens, recognises implicit characters defined by \let
and look up their upper case form, there are very few reasons to get into that situation, using \def
(or \renewcommand
) is the documented LaTeX interface and is essentially trivial to make work as you just have to expand the macros before uppercasing, and it works out of the box using LaTeX:
\documentclass{article}
\begin{document}
\let\zza=a
\let\zzb=b
\let\zzc=c
1 \MakeUppercase{\zza\zzb\zzc}
\renewcommand\zza{a}
\renewcommand\zzb{b}
\renewcommand\zzc{c}
2 \MakeUppercase{\zza\zzb\zzc}
\end{document}
\expandafter\uppercase\expandafter{\expanded{<stuff>}}
, that would work with<stuff>
being letters and macros defined using\newcommand
or\def
, but not for\let
.\uppercase
and\lowercase
only act on explicit character tokens. Implicit character tokens and macros expanding to character tokens are not touched. An character token produced with\let
doesn't have a\uccode
(or\lccode
) for\uppercase
to do its thing. Try\showthe\uccode`t
and then\showthe\uccode`\zTest
(the latter raises an error).\let
, if you are prepared to normalise the charcode of{
/}
.\uppsercase
does no expansion: when you use\def
, the macro token is not affected as it's not a char\UD@CheckWhetherNull
,\UD@CheckWhetherBrace
,\UD@CheckWhetherLeadingSpace
in my answer to the question "How do I pad a string argument to a macro to a set length string" might be of interest. ;-)