-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathxparse-arglist.sty
72 lines (68 loc) · 2.93 KB
/
xparse-arglist.sty
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
\ProvidesPackage{xparse-arglist}
\RequirePackage{xparse}
% This package provides a way to define an xparse-based command which is
% "aware" of how it was called. In other words, while executing the command,
% we construct the argument list that was used to call it (or at least
% something very close to, and functionally equivalent to this argument list).
%
% To construct the argument list, we need to provide \ArgumentSpecification,
% either manually or by calling \GetDocumentCommandArgSpec (see xparse manual
% 3.4) and then expand \ArgumentList in the following way:
%
% \ArgumentList must be first fully expanded both when defining the command,
% and the result must be then fully expanded while executing the command.
%
% For example, to have \foo itself with the same arguments again :D define it
% like this:
%
% \edef\outermarshal{%
% \noexpand\NewDocumentCommand
% \noexpand\foo
% {\expandonce{\ArgumentSpecification}}%
% {%
% \unexpanded{...}%
% \edef\noexpand\innermarshal{%
% \noexpand\noexpand\noexpand\foo\ArgumentList
% }\innermarshal
% \noexpand\foo\ArgumentList
% \unexpanded{...}%
% }%
% }\outermarshal
%
% This package was implemented during the development of "memoize", which
% needs to compute the md5sum of a command plus its arguments, and then
% (sometimes) execute the command.
%
% Now maybe this exists somewhere in xparse, but I haven't been able to find
% it. And I know I should've used expl3 for this ... but plain TeX way
% compiles faster. ;-)
\def\ArgumentList{%
\expandafter\xp@arglist\expandafter0\ArgumentSpecification.%
}
\def\xp@arglist#1#2{%
\ifcsname xp@arglist@#2\endcsname
\csname xp@arglist@#2\expandafter\expandafter\expandafter\endcsname
\else
\expandafter\xp@arglist@error
\fi
\expandafter{\the\numexpr#1+1\relax}%
}
% \xp@arglist@...: #1 = the argument number
\def\xp@arglist@m#1{\noexpand\unexpanded{{#####1}}\xp@arglist{#1}}
\def\xp@arglist@r#1#2#3{\noexpand\unexpanded{#2#####1#3}\xp@arglist{#1}}
\def\xp@arglist@R#1#2#3#4{\noexpand\unexpanded{#2#####1#3}\xp@arglist{#1}}
\def\xp@arglist@v#1{{Handled commands with verbatim arguments are not
supported}\xp@arglist{#1}} % error
\def\xp@arglist@b#1{{This is not the way to handle
environment}\xp@arglist{#1}} % error
\def\xp@arglist@o#1{\noexpand\unexpanded{[#####1]}\xp@arglist{#1}}
\def\xp@arglist@d#1#2#3{\noexpand\unexpanded{#2#####1#3}\xp@arglist{#1}}
\def\xp@arglist@O#1#2{\noexpand\unexpanded{[#####1]}\xp@arglist{#1}}
\def\xp@arglist@D#1#2#3#4{\noexpand\unexpanded{#2#####1#3}\xp@arglist{#1}}
\def\xp@arglist@s#1{\noexpand\IfBooleanT{#####1}{*}\xp@arglist{#1}}
\def\xp@arglist@t#1#2{\noexpand\IfBooleanT{#####1}{#2}\xp@arglist{#1}}
\csdef{xp@arglist@+}#1{\expandafter\xp@arglist\expandafter{\the\numexpr#1-1\relax}}%
\csdef{xp@arglist@.}#1{}
% e,E: Embellishments are not supported.
% > Argument processors are not supported. And how could they be?
\def\xp@arglist@error#1.{{Unknown argument type}}