summaryrefslogtreecommitdiff
path: root/tex/context/base/xtag-ini.tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/xtag-ini.tex')
-rw-r--r--tex/context/base/xtag-ini.tex392
1 files changed, 298 insertions, 94 deletions
diff --git a/tex/context/base/xtag-ini.tex b/tex/context/base/xtag-ini.tex
index b6d3c6bf6..e09c63924 100644
--- a/tex/context/base/xtag-ini.tex
+++ b/tex/context/base/xtag-ini.tex
@@ -13,6 +13,9 @@
\writestatus{loading}{Context XML Macros (initialization)}
+%D Beware: don't rely on \longempty things, since this may
+%D change!
+
%D To be sure:
\newif\ifprocessingXML
@@ -189,6 +192,10 @@
%D a way around this, but for convenience \TEXEXEC\ will take
%D care of processing raw \XML\ files in a transparant way.
+\newif\ifalwaysreduceXMLtokens
+
+\let\alwaysreduceXMLtokens\alwaysreduceXMLtokenstrue
+
\bgroup
\catcode`\*=\@@comment
\catcode`\.=\@@escape
@@ -225,6 +232,32 @@
* there; this is needed because reading from file goes wrong
* (eating up argument)
+* .unexpanded.gdef.enableXML*
+* B.catcode`.!=.@@other*
+* .catcode`.?=.@@other*
+* .catcode`.:=.@@other* active in french
+* .catcode`.;=.@@other* active in french
+* .catcode`.&=.@@active .let&=.doXMLentity*
+* .catcode`.<=.@@active .unexpanded.def<B.doXMLelementE*
+* .catcode`.>=.@@other
+* .catcode`."=.@@other*
+* .catcode`./=.@@other
+* .catcode`.'=.@@other*
+* *catcode`.#=.@@active .def#PP1B&tex-hash;E* gobbles its own dup
+* .catcode`.#=.@@active .def#B&tex-hash;E*
+* .catcode`.$=.@@active .def$B&tex-dollar;E*
+* .catcode`.%=.@@active .def%B&tex-percent;E*
+* .catcode`.\=.@@active .def\B&tex-backslash;E*
+* .catcode`.^=.@@active .def^B&tex-hat;E*
+* .catcode`._=.@@active .def_B&tex-underscore;E*
+* .catcode`.{=.@@active .def{B&tex-leftbrace;E*
+* .catcode`.}=.@@active .def}B&tex-rightbrace;E*
+* .catcode`.|=.@@active .def|B&tex-bar;E*
+* .catcode`.~=.@@other *def~B&tex-tilde;E*
+* .processingXMLtrue
+* .the.everyenableXML
+* E
+
.unexpanded.gdef.enableXML*
B.catcode`.!=.@@other*
.catcode`.?=.@@other*
@@ -233,24 +266,41 @@
.catcode`.&=.@@active .let&=.doXMLentity*
.catcode`.<=.@@active .unexpanded.def<B.doXMLelementE*
.catcode`.>=.@@other
- .catcode`."=.@@other*
+ .catcode`."=.@@other
.catcode`./=.@@other
- .catcode`.'=.@@other*
- *catcode`.#=.@@active .def#PP1B&tex-hash;E* gobbles its own dup
- .catcode`.#=.@@active .def#B&tex-hash;E*
- .catcode`.$=.@@active .def$B&tex-dollar;E*
- .catcode`.%=.@@active .def%B&tex-percent;E*
- .catcode`.\=.@@active .def\B&tex-backslash;E*
- .catcode`.^=.@@active .def^B&tex-hat;E*
- .catcode`._=.@@active .def_B&tex-underscore;E*
- .catcode`.{=.@@active .def{B&tex-leftbrace;E*
- .catcode`.}=.@@active .def}B&tex-rightbrace;E*
- .catcode`.|=.@@active .def|B&tex-bar;E*
- .catcode`.~=.@@other *def~B&tex-tilde;E*
+ .catcode`.'=.@@other
+ .catcode`.#=.@@active
+ .catcode`.$=.@@active
+ .catcode`.%=.@@active
+ .catcode`.\=.@@active
+ .catcode`.^=.@@active
+ .catcode`._=.@@active
+ .catcode`.{=.@@active
+ .catcode`.}=.@@active
+ .catcode`.|=.@@active
+ .catcode`.~=.@@other
+ .ifalwaysreduceXMLtokens
+ .reduceXMLescapetokens
+ .else
+ .entitleXMLescapetokens
+ .fi
.processingXMLtrue
.the.everyenableXML
E
+.gdef.entitleXMLescapetokens*
+ B.def#B&tex-hash;E*
+ .def$B&tex-dollar;E*
+ .def%B&tex-percent;E*
+ .def\B&tex-backslash;E*
+ .def^B&tex-hat;E*
+ .def_B&tex-underscore;E*
+ .def{B&tex-leftbrace;E*
+ .def}B&tex-rightbrace;E*
+ .def|B&tex-bar;E*
+ *def~B&tex-tilde;E*
+ E
+
.gdef.reduceXMLescapetokens*
B.def#B.string#E*
.def$B.string$E*
@@ -542,7 +592,7 @@
{\def\currentXMLelement{#1}% watch out: \empty == begin or empty tag
\chardef\kindofXMLelement\ifx#2\empty\beginXMLtag\else\emptyXMLtag\fi}
-\def\@@traceXMLelement%
+\def\@@traceXMLelement
{\originalXMLfullidentifier
\ifx\originalXMLfullidentifier\currentXMLfullidentifier\else
\space=>\space\currentXMLfullidentifier
@@ -551,7 +601,7 @@
\space\string|\space\currentXMLarguments
\fi}
-\long\def\traceXMLelement%
+\long\def\traceXMLelement
{\edef\originalXMLfullidentifier{\someXMLelement\currentXMLelement}%
\cleanupXMLarguments\writestatus{xml-element}{\@@traceXMLelement}}
@@ -631,12 +681,12 @@
\long\def\docleanupXMLarguments#1/ #2\relax % space added earlier
{\edef\currentXMLarguments{#1}}
-\def\executeXMLelementA% no fallback
+\def\executeXMLelementA % no fallback
{\ifcsname\@@XMLelement:\currentXMLfullidentifier\endcsname
\csname\@@XMLelement:\currentXMLfullidentifier\endcsname
\fi}
-\def\executeXMLelementB% default fallback
+\def\executeXMLelementB % default fallback
{\csname \@@XMLelement:%
\ifcsname\@@XMLelement:\currentXMLfullidentifier\endcsname
\currentXMLfullidentifier
@@ -645,7 +695,7 @@
\fi
\endcsname}
-\def\executeXMLelementC% no namespace of default fallback
+\def\executeXMLelementC % no namespace of default fallback
{\csname \@@XMLelement:%
\ifcsname\@@XMLelement:\currentXMLfullidentifier\endcsname
\currentXMLfullidentifier
@@ -656,19 +706,85 @@
\fi\fi
\endcsname}
+\def\executeXMLelementD
+ {\csname
+ \ifcsname\@@XMLelement:\currentXMLfullidentifier\endcsname
+ \@@XMLelement:\currentXMLfullidentifier
+ \else\ifcsname\@@XMLelement:\currentXMLidentifier\endcsname
+ \@@XMLelement:\currentXMLidentifier
+ \else
+ \executeXMLelementDD % less skipping and thereby faster
+ \fi\fi
+ \endcsname}
+
+\def\executeXMLelementDD % now forget about tex mapping
+ {\ifcsname\normal@@XMLelement:\currentXMLfullidentifier\endcsname
+ \normal@@XMLelement:\currentXMLfullidentifier
+ \else\ifcsname\normal@@XMLelement:\currentXMLidentifier\endcsname
+ \normal@@XMLelement:\currentXMLidentifier
+ \else
+ \@@XMLelement:\defaultXMLelement
+ \fi\fi}
+
\def\setXMLfallbackmode#1%
{\ifcase#1\relax
- \let\executeXMLelement\executeXMLelementA
- \or
- \let\executeXMLelement\executeXMLelementB
- \or
- \let\executeXMLelement\executeXMLelementC
+ \let\executeXMLelement \executeXMLelementA
+ \let\automateXMLnamespace\automateXMLnamespaceA
+ \or % 1
+ \let\executeXMLelement \executeXMLelementB
+ \let\automateXMLnamespace\automateXMLnamespaceB
+ \or % 2
+ \let\executeXMLelement \executeXMLelementC
+ \let\automateXMLnamespace\automateXMLnamespaceC
+ \or % 3
+ \let\executeXMLelement \executeXMLelementD
+ \let\automateXMLnamespace\automateXMLnamespaceD
\fi}
-\setXMLfallbackmode2
+\setXMLfallbackmode2 % will be 3
%D An example of fall back modes is given below.
+%D The automated namespace stuff is new and yet undocumented
+%D (see resource libraries for usage).
+
+\def\xautoXMLnamespace#1% fast internal one
+ {\ifcsname\@@XMLnamespace-#1\endcsname\else
+ \@EA\appendtoks\csname\@@XMLnamespace-#1\endcsname\to\autoXMLnamespaces
+ \fi
+ \@EA\edef\csname\@@XMLnamespace-#1\endcsname
+ {\noexpand\edef\noexpand\@axmlns@{#1}% quicker #1 -> \#1
+ \noexpand\doautoXMLnamespace\noexpand\@axmlns@}}
+
+\def\doautoXMLnamespace#1% \done is set before list
+ {\ifdone\else\automateXMLnamespace#1\fi}
+
+\def\automateXMLnamespaceA#1%
+ {\ifcsname\@@XMLelement:#1:\checkedXMLnamespace\endcsname
+ \let\currentXMLnamespace#1%
+ \else\ifcsname\@@XMLelement:#1:\checkedXMLnamespace/\endcsname
+ \let\currentXMLnamespace#1%
+ \fi\fi}
+
+\let\automateXMLnamespaceB\automateXMLnamespaceA
+\let\automateXMLnamespaceC\automateXMLnamespaceA
+
+\def\automateXMLnamespaceD#1%
+ {\ifcsname\@@XMLelement:#1:\checkedXMLnamespace\endcsname
+ \let\currentXMLnamespace#1%
+ \else\ifcsname\normal@@XMLelement:#1:\checkedXMLnamespace\endcsname
+ \let\currentXMLnamespace#1%
+ \else
+ \automateXMLnamespaceDD#1%
+ \fi\fi}
+
+\def\automateXMLnamespaceDD#1%
+ {\ifcsname\@@XMLelement:#1:\checkedXMLnamespace/\endcsname
+ \let\currentXMLnamespace#1%
+ \else\ifcsname\normal@@XMLelement:#1:\checkedXMLnamespace/\endcsname
+ \let\currentXMLnamespace#1%
+ \fi\fi}
+
%D Later we will implement the error handler, here we handle
%D the default case.
@@ -677,7 +793,7 @@
#1%
\ifnum\kindofXMLelement=\emptyXMLtag/\fi}
-\def\defaultXMLelement%
+\def\defaultXMLelement
{\someXMLelement\s!default}
%D It is possible to keep track of nesting automatically,
@@ -687,21 +803,57 @@
%D mode of operation combined with space grabbing.
\def\beginXMLelement
- {\global\advance\XMLdepth \plusone % 1
+ {\global\advance\XMLdepth\plusone
\global\@EA\let\csname\@@XMLdepth:\the\XMLdepth\endcsname\currentXMLelement}
\def\endXMLelement
- {\global\advance\XMLdepth \minusone } % -1 }
+ {\global\advance\XMLdepth\minusone}
+
+% 0 = nothing
+% 1 = unknown
+% 2 = current element
+
+\chardef\XMLancestormode=2 % never change this one globally
\def\XMLancestor#1%
{\ifnum\numexpr(\XMLdepth-#1)>0
\csname\@@XMLdepth:\the\numexpr(\XMLdepth-#1)\endcsname
\else
- \currentXMLelement
+ \ifcase\XMLancestormode\or\s!unknown\or\currentXMLelement\fi
+ \fi}
+
+\def\XMLparent
+ {\XMLancestor\plusone}
+
+\def\XMLpureancestor#1%
+ {\ifnum\numexpr(\XMLdepth-#1)>0
+ \csname\@@XMLdepth:\the\numexpr(\XMLdepth-#1)\endcsname
\fi}
-\def\XMLparent%
- {\XMLancestor1}
+\def\XMLpureparent
+ {\XMLpureancestor\plusone}
+
+% \defineXMLenvironment[one]
+% {\beginXMLelement}
+% {\endXMLelement}
+%
+% \defineXMLenvironment[two]
+% {\beginXMLelement
+% \starttabulate
+% \NC ancestor 1 \NC \XMLancestor{1} \NC \NR
+% \NC ancestor 2 \NC \XMLancestor{2} \NC \NR
+% \NC ancestor 3 \NC \XMLancestor{3} \NC \NR
+% \NC ancestor 4 \NC \XMLancestor{4} \NC \NR
+% \stoptabulate}
+% {\endXMLelement}
+%
+% \startbuffer
+% <x:one> <x:two> <one> <two> </two> </one> </x:two> </x:one>
+% \stopbuffer
+%
+% {fallback A: \setXMLfallbackmode 0 \processXMLbuffer}\par
+% {fallback B: \setXMLfallbackmode 1 \processXMLbuffer}\par
+% {fallback C: \setXMLfallbackmode 2 \processXMLbuffer}\par
% todo: split #1 into raws en reconstruct, set current etc, push and pop
%
@@ -982,11 +1134,13 @@
\@EAEAEA\unknownXMLcharacter
\fi\fi{\number#1}}
+\ifx\unicodechar\undefined\let\unicodechar\rawcharacter\fi
+
\unexpanded\def\getXMLcharacter#1%
{\ifcsname\@@XMLentity:#1\endcsname
\@EA\getXMLentity
\else
- \@EA\rawcharacter
+ \@EA\unicodechar % was: \rawcharacter
\fi{#1}}
\def\unknownXMLcharacter#1{[#1]}
@@ -1042,8 +1196,21 @@
\unexpanded\def\getXMLentity{\expandedXMLentity}
-\def\doifXMLentityelse#1#2#3%
- {\ifcsname\@@XMLentity:#1\endcsname#2\else#3\fi}
+%\def\doifXMLentityelse#1#2#3%
+% {\ifcsname\@@XMLentity:#1\endcsname#2\else#3\fi}
+
+\def\doifXMLentityelse#1%
+ {\ifcsname\@@XMLentity:#1\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+% \letvalue{1@2}\firstoftwoarguments
+% \letvalue{2@2}\secondoftwoarguments
+%
+% \def\doifXMLentityelse#1%
+% {\csname\ifcsname\@@XMLentity:#1\endcsname1\else2\fi @2\endcsname}
% see \defineXML... commands:
%
@@ -1119,27 +1286,78 @@
\let\dodoparseXMLarguments\doparseXMLarguments
\doparseXMLarguments}
+% \long\def\doparseXMLarguments#1% space goes ok
+% {\if#1>%
+% \let\dodoparseXMLarguments\empty
+% \else\if#1=%
+% \edef\@@XMLname{\the\XMLtoks}%
+% \XMLtoks\emptytoks
+% \else\if#1"%
+% \let\dodoparseXMLarguments\dodoparseXMLargumentsD
+% \else\if#1'%
+% \let\dodoparseXMLarguments\dodoparseXMLargumentsS
+% \else\if#1:%
+% \XMLnamespacetrue
+% \edef\@@XMLspac{\the\XMLtoks}%
+% \XMLtoks\emptytoks
+% \else\if#1/%
+% \chardef\kindofXMLelement\emptyXMLtag
+% \else
+% \XMLtoks\@EA{\the\XMLtoks#1}%
+% \fi\fi\fi\fi\fi\fi
+% \dodoparseXMLarguments}
+%
+% The next speed optimization is suggested by Taco. Since we
+% are dealing with validated code, we can grab larger chunks.
+
\long\def\doparseXMLarguments#1% space goes ok
{\if#1>%
\let\dodoparseXMLarguments\empty
- \else\if#1=%
- \edef\@@XMLname{\the\XMLtoks}%
- \XMLtoks\emptytoks
- \else\if#1"%
- \let\dodoparseXMLarguments\dodoparseXMLargumentsD
- \else\if#1'%
- \let\dodoparseXMLarguments\dodoparseXMLargumentsS
- \else\if#1:%
- \XMLnamespacetrue
- \edef\@@XMLspac{\the\XMLtoks}%
- \XMLtoks\emptytoks
\else\if#1/%
\chardef\kindofXMLelement\emptyXMLtag
\else
- \XMLtoks\@EA{\the\XMLtoks#1}%
- \fi\fi\fi\fi\fi\fi
+ \XMLtoks{#1}%
+ \let\dodoparseXMLarguments\dodoparseXMLargumentsX
+ \fi\fi
+ \dodoparseXMLarguments}
+
+\def\dodoparseXMLargumentsX#1=#2%
+ {\edef\@@XMLname{\the\XMLtoks#1}%
+ \@EA\getXMLNSSSS\@@XMLname:\relax
+ \XMLtoks\emptytoks
+ \if#2"%
+ \let\dodoparseXMLarguments\dodoparseXMLargumentsD
+ \else
+ \let\dodoparseXMLarguments\dodoparseXMLargumentsS
+ \fi
\dodoparseXMLarguments}
+\def\gobbleuntilcolon#1:{#1}
+
+\def\getXMLNSSSS#1:#2\relax
+ {\def\!!stringa{#2}%
+ \ifx\!!stringa\empty \else
+ \XMLnamespacetrue
+ \edef\@@XMLname{\gobbleuntilcolon#2}%
+ \edef\@@XMLspac{#1}%
+ \fi}
+
+% ok ?
+%
+% \def\dodoparseXMLargumentsX#1=#2%
+% {\edef\@@XMLname{\the\XMLtoks#1}%
+% \@EA\getXMLNSSSS\@@XMLname:\relax
+% \XMLtoks\emptytoks
+% \if#2"%
+% \@EA\dodoparseXMLargumentsD
+% \else
+% \@EA\dodoparseXMLargumentsS
+% \fi}
+
+% Storing \type {#1} in a macro in order to minimize the
+% amount of data passed as argument does not improve
+% performance, so we keep the readable form.
+
\def\dodoparseXMLargumentsD#1"{\dosetXMLargument{#1}}
\def\dodoparseXMLargumentsS#1'{\dosetXMLargument{#1}}
@@ -1342,7 +1560,7 @@
\next}
\long\gdef\dododefineXMLgsave#1%
- {\letvalue{\@@XMLdata:#1}\longempty
+ {\letgvalue{\@@XMLdata:#1}\longempty
\long\setvalue{\@@XMLelement:#1/}{\long\setgvalue{\@@XMLdata:#1}{}}%
\long\setvalue{\@@XMLelement:#1}{\redoXMLgsave{#1}}}
@@ -1366,6 +1584,16 @@
{#2\long\@EA\def\csname\@@XMLdata:#1\endcsname{##1}#3}%
\next}
+\long\gdef\dododefineXMLenvironmentgsave#1#2#3%
+ {\letgvalue{\@@XMLdata:#1}\longempty
+ \long\setvalue{\@@XMLelement:#1/}{#2\long\setgvalue{\@@XMLdata:#1}{}#3}%
+ \long\setvalue{\@@XMLelement:#1}{\redoXMLenvironmentgsave{#1}{#2}{#3}}}
+
+\gdef\redoXMLenvironmentgsave#1#2#3%
+ {\long\@EA\def\@EA\next\@EA##\@EA1\@EA<\@EA/\currentXMLelement>%
+ {#2\long\@EA\gdef\csname\@@XMLdata:#1\endcsname{##1}#3}%
+ \next}
+
\long\gdef\dododefineXMLprocess#1%
{\long\setvalue{\@@XMLelement:#1/}{}%
\long\setvalue{\@@XMLelement:#1}{}%
@@ -1381,16 +1609,18 @@
%D The high level definition macros.
-\def\defineXMLsingular {\dotripleempty\dodefineXMLsingular}
-\def\defineXMLcommand {\dotripleempty\dodefineXMLcommand}
-\def\defineXMLgrouped {\dotripleempty\dodefineXMLgrouped}
-\def\defineXMLargument {\dotripleempty\dodefineXMLargument}
-\def\defineXMLignore {\dotripleempty\dodefineXMLignore}
-\def\defineXMLpickup {\dotripleempty\dodefineXMLpickup}
-\def\defineXMLenvironment {\dotripleempty\dodefineXMLenvironment}
-\def\defineXMLsave {\dotripleempty\dodefineXMLsave}
-\def\defineXMLenvironmentsave{\dotripleempty\dodefineXMLenvironmentsave}
-\def\defineXMLprocess {\dotripleempty\dodefineXMLprocess}
+\def\defineXMLsingular {\dotripleempty\dodefineXMLsingular}
+\def\defineXMLcommand {\dotripleempty\dodefineXMLcommand}
+\def\defineXMLgrouped {\dotripleempty\dodefineXMLgrouped}
+\def\defineXMLargument {\dotripleempty\dodefineXMLargument}
+\def\defineXMLignore {\dotripleempty\dodefineXMLignore}
+\def\defineXMLpickup {\dotripleempty\dodefineXMLpickup}
+\def\defineXMLenvironment {\dotripleempty\dodefineXMLenvironment}
+\def\defineXMLsave {\dotripleempty\dodefineXMLsave}
+\def\defineXMLgsave {\dotripleempty\dodefineXMLgsave}
+\def\defineXMLenvironmentsave {\dotripleempty\dodefineXMLenvironmentsave}
+\def\defineXMLenvironmentgsave{\dotripleempty\dodefineXMLenvironmentgsave}
+\def\defineXMLprocess {\dotripleempty\dodefineXMLprocess}
% push is (not yet) a real push, so:
@@ -1427,9 +1657,15 @@
\long\def\dodefineXMLsave[#1][#2][#3]%
{\defineXMLmethod\dododefineXMLsave{#1}{#2}{#3}{}{}}
+\long\def\dodefineXMLgsave[#1][#2][#3]%
+ {\defineXMLmethod\dododefineXMLgsave{#1}{#2}{#3}{}{}}
+
\long\def\dodefineXMLenvironmentsave[#1][#2][#3]#4#5%
{\defineXMLmethod\dododefineXMLenvironmentsave{#1}{#2}{#3}{#4}{#5}}
+\long\def\dodefineXMLenvironmentgsave[#1][#2][#3]#4#5%
+ {\defineXMLmethod\dododefineXMLenvironmentgsave{#1}{#2}{#3}{#4}{#5}}
+
\long\def\dodefineXMLprocess[#1][#2][#3]%
{\defineXMLmethod\dododefineXMLprocess{#1}{#2}{#3}{}{}}
@@ -1824,9 +2060,9 @@
\doXMLdata}
\def\doXMLdata#1%
- {\enableXML
- \scantokens{#1<gobblespacetokens/>}%
- \endgroup}
+ {\enableXML
+ \scantokens{#1<gobblespacetokens/>}%
+ \endgroup}
%D
@@ -1949,7 +2185,7 @@
\long\unexpanded\gdef\getXMLgrouped#1% #1 kan weg % klopt dit nu?
{\groupedtoks\emptytoks
- \scratchcounter=0
+ \scratchcounter\zerocount
\edef\theXMLnamespace
{\ifx\originalXMLnamespace\empty\else\originalXMLnamespace:\fi
\currentXMLidentifier}%
@@ -1960,7 +2196,7 @@
\ifcase\scratchcounter
\let\dogetgrouped\dodogetgrouped
\else
- \advance\scratchcounter \minusone
+ \advance\scratchcounter \minusone
\ifcollectXMLgrouped\@EA\appendtoks\@EA<\@EA/\currentXMLelement>\to\groupedtoks\fi
\fi
\dogetgrouped}%
@@ -2001,37 +2237,5 @@
%D \stoptypen
\def\XMLyes#1{\XMLownifequalelse{#1}{yes}{#1}{}}
-
-\def\expifequalelse#1#2%
- {\@@ifequal#1\relax\relax\@@and#2\relax\relax\@@then}
-
-\def\@@ifequal#1#2\@@and#3%
- {\ifx#1\relax
- \ifx#3\relax
- \@EAEAEA\@@if@@equal@@true
- \else
- \@EAEAEA\@@if@@equal@@false
- \fi
- \else
- \ifx#3\relax
- \@EAEAEAEAEAEA\@@if@@equal@@false
- \else\ifx#1#3%
- % go on
- \else
- \@EAEAEAEAEAEA\@@if@@equal@@false
- \fi\fi
- \fi
- \@@ifequal#2\@@and}
-
-\long\def\@@if@@equal@@true #1\@@then#2#3{#2}
-\long\def\@@if@@equal@@false#1\@@then#2#3{#3}
-
-%D new stuff :
-
-\def\partialexpanded#1%
- {\let\notexpanded\noexpand
- \edef\@@expanded{\noexpand#1}%
- \let\notexpanded\empty
- \@@expanded}
\protect \endinput