-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathunique-csname.tex
44 lines (37 loc) · 1.44 KB
/
unique-csname.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
\makeatletter
% combination of Henri Menke and Skillmon's answers to
% https://tex.stackexchange.com/q/633706
\long\def\@uniquecsname@try#1{%
\ifcsname #1\endcsname
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
% expand \@uniquecsname@generate twice
{\expandafter\expandafter\expandafter\@uniquecsname@try
\expandafter\expandafter\expandafter{\@uniquecsname@generate{#1}}}
{#1}%
}
% if no random int primitive is provided, use the null char trick
\begingroup
\catcode`\^^@=12 % default catcode is 15 (invalid character)
\unexpanded{\endgroup % tokenize ^^@ with catcode 12
\ifdefined\pdfuniformdeviate
\def\@uniquecsname@generate#1{\number\pdfuniformdeviate\maxdimen}
\else\ifdefined\uniformdeviate
\def\@uniquecsname@generate#1{\number\uniformdeviate\maxdimen}
\else
\edef\@uniquecsname@generate#1{#1^^@}% the 0x00 null char
\fi\fi
}
% start with empty csname (\csname\endcsname IS a valid cs)
\def\uniquecsname{\@uniquecsname@try{}}
% Q: Why no \uniquecmd that expands to an always-undefined control sequence?
% A: It's impossible since both \begingroup and \endgroup are unexpandable.
% \undefine and \undefinecs will cover all the unexpandable use cases.
\long\def\undefine#1{% short form \undef is taken by etoolbox.sty
\begingroup\expandafter\endgroup
\expandafter\let\expandafter#1\csname\uniquecsname\endcsname}
\long\def\undefinecs#1{%
\expandafter\undefine\csname #1\endcsname}
\makeatother