% \iffalse meta-comment % % Copyright 1997, 1998, 2008 2015 LaTeX Project and Peter Breitenlohner. % % This file (etex.sty) may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 of % this license or (at your option) any later version. The latest % version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2003/12/01 or later. % % This work has the LPPL maintenance status "maintained". % % The Current Maintainer of this work is Peter Breitenlohner. % \fi \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{etex} % [1997/08/12 v0.1 eTeX basic definition package (DPC)] % [1998/03/26 v2.0 eTeX basic definition package (PEB)] % [2015/03/02 v2.1 eTeX basic definition package (PEB,DPC)] % [2015/07/06 v2.2 eTeX basic definition package (PEB,DPC)] [2015/07/08 v2.3 eTeX basic definition package (PEB,DPC)] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% A basic interface to some etex primitives, closely modeled on %% etex.src and etexdefs.lib provided by the core etex team. %% The etex.src `module' system is not copied here, the standard %% LaTeX package option mechanism is used instead, %% however the package options match the module names. %% (Currently grouptypes, interactionmodes, nodetypes, iftypes.) %% The individual type names are different too: We use, e.g., %% %% `\bottomleveltype' and `\simplegrouptype' instead of %% `\grouptypes{bottomlevel}' and `\grouptypes{simple}'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Other Comments... %% The names of the `interactionmodes' are not too good. %% In particular \scroll and \batch are likely to clash with existing %% uses. These names have been changed into \batchinteractionmode, %% \scrollinteractionmode etc. %% Similarly, the names of the `groupetypes' have been changed, in %% particular \mathgroup would conflict with the LaTeX kernel. %% \etex logo could have the same trick as \LaTeXe to pick up a bold %% epsilon when needed. (Not done here, I hate wasting tokens on logos.) %% This version does have a \m@th not in the original. %% The \globcountvector, \loccountvector, etc. allocation macros are %% not (yet) implemented. %% Currently if run on a standard TeX, the package generates an error. %% Perhaps it should instead load some code to try to fake %% the new etex primitives in that case??? %% Likewise, the package generates an error when used with e-TeX V 1 %% The etex.src language mechanism is not copied here. That facility %% does not use any of the etex features. LaTeX should be customised %% using the same hyphen.cfg mechanism as for a format built with a %% standard TeX. %% David Carlisle %% Upgraded for e-TeX V 2.0 %% Peter Breitenlohner %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifx\eTeXversion\@undefined \PackageError{etex} {This package may only be run using an\MessageBreak etex in extended mode} {Perhaps you forgot the `*' when making the format with (e)initex.% } \fi \ifnum\eTeXversion<2 \PackageError{etex} {This package requires e-TeX V 2} {You are probably using the obsolete e-TeX V 1.% } \fi % 2.2 % Check if the new latex 2015/01/01 allocation is already using % extended reisters. If so it is too late to change allocation scheme. % Older versions of LaTeX would have given an error when the classic % TeX registers were all allocated, but newer formats allocate from % the extended range, so usually this package is not needed. \@tempswafalse \ifnum\count10>\@cclv\@tempswatrue\else \ifnum\count11>\@cclv\@tempswatrue\else \ifnum\count12>\@cclv\@tempswatrue\else \ifnum\count13>\@cclv\@tempswatrue\else \ifnum\count14>\@cclv\@tempswatrue\else \ifnum\count15>\@cclv\@tempswatrue \fi\fi\fi\fi\fi\fi \if@tempswa \PackageWarningNoLine{etex}{% Extended allocation already in use.\MessageBreak etex.sty code will not be used.\MessageBreak To force etex package to load, add\MessageBreak \string\RequirePackage{etex}\MessageBreak at the start of the document} \expandafter\endinput\fi % End of 2.2 addition. % 2.3 move option handling after the above error checks. \DeclareOption{grouptypes}{\catcode`\G=9} \DeclareOption{interactionmodes}{\catcode`\I=9} \DeclareOption{nodetypes}{\catcode`\N=9} \DeclareOption{iftypes}{\catcode`\C=9} \DeclareOption{localalloclog}{\let\et@xwlog\wlog} % the default \DeclareOption{localallocnolog}{\let\et@xwlog\@gobble} % be quiet \DeclareOption{localallocshow}{\let\et@xwlog\typeout} % debugging % End of 2.3 addition. \def\eTeX{% $\m@th\varepsilon$-\TeX} \def\tracingall{% \tracingcommands\thr@@ % etex \tracingstats\tw@ \tracingpages\@ne \tracinglostchars\tw@ % etex \tracingmacros\tw@ \tracingparagraphs\@ne \tracingrestores\@ne \tracinggroups\@ne % etex \tracingifs\@ne % etex \tracingscantokens\@ne % etex \tracingnesting\@ne % etex \tracingassigns\@ne % etex \errorcontextlines\maxdimen \showoutput} \def\loggingall{% \tracingall \tracingonline\z@} \def\tracingnone{% \tracingonline\z@ \showboxdepth\m@ne \showboxbreadth\m@ne \tracingoutput\z@ \errorcontextlines\m@ne \tracingassigns\z@ \tracingnesting\z@ \tracingscantokens\z@ \tracingifs\z@ \tracinggroups\z@ \tracingrestores\z@ \tracingparagraphs\z@ \tracingmacros\z@ \tracinglostchars\@ne \tracingpages\z@ \tracingstats\z@ \tracingcommands\z@} %% Register allocation %% We have to adjust the Plain TeX / LaTeX register allocation counts %% for our slightly modified book-keeping, but first we allocate our %% insertion counter \et@xins, because \insc@ount of Plain TeX / LaTeX %% will be used differently. \newcount\et@xins \advance\count10 by 1 % \count10=23 % allocates \count registers 23, 24, ... \advance\count11 by 1 % \count11=10 % allocates \dimen registers 10, 11, ... \advance\count12 by 1 % \count12=10 % allocates \skip registers 10, 11, ... \advance\count13 by 1 % \count13=10 % allocates \muskip registers 10, 11, ... \advance\count14 by 1 % \count14=10 % allocates \box registers 10, 11, ... \advance\count15 by 1 % \count15=10 % allocates \toks registers 10, 11, ... \advance\count16 by 1 % \count16=0 % allocates input streams 0, 1, ... \advance\count17 by 1 % \count17=0 % allocates output streams 0, 1, ... \advance\count18 by 1 % \count18=4 % allocates math families 4, 5, ... \advance\count19 by 1 % \count19=0 % allocates \language codes 0, 1, ... \et@xins=\insc@unt % \et@xins=255 % allocates insertions 254, 253, ... %% To ensure working in LaTeX 2015 release do define \newcount etc %% with their pre 2015 LaTeX definitions \def\newcount{\alloc@0\count\countdef\insc@unt} \def\newdimen{\alloc@1\dimen\dimendef\insc@unt} \def\newskip{\alloc@2\skip\skipdef\insc@unt} \def\newmuskip{\alloc@3\muskip\muskipdef\@cclvi} \def\newbox{\alloc@4\box\chardef\insc@unt} \def\newtoks{\alloc@5\toks\toksdef\@cclvi} \def\newread{\alloc@6\read\chardef\sixt@@n} \def\newwrite{\alloc@7\write\chardef\sixt@@n} \def\new@mathgroup{\alloc@8\mathgroup\chardef\sixt@@n} \let\newfam\new@mathgroup \def\newlanguage{\alloc@9\language\chardef\@cclvi} %% When the normal register pool for \count, \dimen, \skip, \muskip, %% \box, or \toks registers is exhausted, we switch to the extended pool. \def\alloc@#1#2#3#4#5% {\ifnum\count1#1<#4% make sure there's still room \allocationnumber\count1#1 \global\advance\count1#1\@ne \global#3#5\allocationnumber \wlog{\string#5=\string#2\the\allocationnumber}% \else\ifnum#1<6 \begingroup \escapechar\m@ne \expandafter\alloc@@\expandafter{\string#2}#5% \else\errmessage{No room for a new #2}\fi\fi } %% The \expandafter construction used here allows the generation of %% \newcount and \globcount from #1=count. \def\alloc@@#1#2% {\endgroup % restore \escapechar \wlog{Normal \csname#1\endcsname register pool exhausted, switching to extended pool.}% \global\expandafter\let \csname new#1\expandafter\endcsname \csname glob#1\endcsname \csname new#1\endcsname#2% } %% We do change the LaTeX definition of \newinsert \def\newinsert#1{% make sure there's still room for ... \ch@ck0\et@xins\count{% ... a \count, ... \ch@ck1\et@xins\dimen{% ... \dimen, ... \ch@ck2\et@xins\skip{% ... \skip, ... \ch@ck4\et@xins\box{% ... and \box register \global\advance\et@xins\m@ne \unless\ifnum\insc@unt<\et@xins \global\insc@unt\et@xins \fi \allocationnumber\et@xins \global\chardef#1\allocationnumber \wlog{\string#1=\string\insert\the\allocationnumber}}}}}} \def\ch@ck#1#2#3#4% {\ifnum\count1#1<#2#4\else\errmessage{No room for a new #3}\fi} %% And we define \reserveinserts, so that you can say \reserveinserts{17} %% in order to reserve room for up to 17 additional insertion classes, that %% will not be taken away by \newcount, \newdimen, \newskip, or \newbox. \outer\def \reserveinserts#1% {\global\insc@unt\numexpr \et@xins \ifnum#1>\z@ -#1\fi \relax} % Now, we define \globcount, \globbox, etc., so that you can say % \globcount\foo and \foo will be defined (with \countdef) to be the % next count register from the vastly larger but somewhat less efficient % extended register pool. We also define \loccount, etc., but these % register definitions are local to the current group. \count260=277 % globally allocates \count registers 277, 278, ... \count261=256 % globally allocates \dimen registers 256, 257, ... \count262=256 % globally allocates \skip registers 256, 257, ... \count263=256 % globally allocates \muskip registers 256, 257, ... \count264=256 % globally allocates \box registers 256, 257, ... \count265=256 % globally allocates \toks registers 256, 257, ... \count266=1 % globally allocates \marks classes 1, 2, ... \count270=32768 % locally allocates \count registers 32767, 32766, ... \count271=32768 % ditto for \dimen registers \count272=32768 % ditto for \skip registers \count273=32768 % ditto for \muskip registers \count274=32768 % ditto for \box registers \count275=32768 % ditto for \toks registers \count276=32768 % ditto for \marks classes % \count registers 256-259 and 267-269 are not (yet) used % \def \et@xglob #1#2#3#4% , , , % \def \et@xloc #1#2#3#4% , , , \def \globcount {\et@xglob 0\count \countdef} \def \loccount {\et@xloc 0\count \countdef} \def \globdimen {\et@xglob 1\dimen \dimendef} \def \locdimen {\et@xloc 1\dimen \dimendef} \def \globskip {\et@xglob 2\skip \skipdef} \def \locskip {\et@xloc 2\skip \skipdef} \def \globmuskip {\et@xglob 3\muskip \muskipdef} \def \locmuskip {\et@xloc 3\muskip \muskipdef} \def \globbox {\et@xglob 4\box \mathchardef} \def \locbox {\et@xloc 4\box \mathchardef} \def \globtoks {\et@xglob 5\toks \toksdef} \def \loctoks {\et@xloc 5\toks \toksdef} \def \globmarks {\et@xglob 6\marks \mathchardef} \def \locmarks {\et@xloc 6\marks \mathchardef} \let\newmarks=\globmarks %% this used to be \newmark for e-TeX V 1.1 \def\et@xglob#1#2#3#4% {\et@xchk#1#2{% make sure there's still room \allocationnumber=\count26#1% \global\advance\count26#1\@ne \global#3#4\allocationnumber \wlog{\string#4=\string#2\the\allocationnumber}}% } \def\et@xloc#1#2#3#4% {\et@xchk#1#2{% make sure there's still room \advance\count27#1by\m@ne \allocationnumber=\count27#1% #3#4=\allocationnumber \et@xwlog{\string#4=\string#2\the\allocationnumber\space(local)}}% } %% The allocation messages for local allocations use \et@xwlog, such that %% these messages can easily be switched on/off \let\et@xwlog=\wlog \def\et@xchk#1#2#3% {\ifnum\count26#1<\count27#1 #3\else\errmessage{No room for a new #2}\fi} % Next we define \globcountblk, \loccountblk, etc., so that you can % say \globcountblk\foo{17} and \foo will be defined (with \mathchardef) % as the first (the zeroth?) of a block of 17 consecutive registers. % Thus the user is intended to reference elements <\foo+0> to <\foo+n-1>, % where n is the length of the block allocated. % \def \et@xgblk #1#2#3#4% , , , % \def \et@xlblk #1#2#3#4% , , , \def\globcountblk {\et@xgblk 0\count } \def\loccountblk {\et@xlblk 0\count } \def\globdimenblk {\et@xgblk 1\dimen } \def\locdimenblk {\et@xlblk 1\dimen } \def\globskipblk {\et@xgblk 2\skip } \def\locskipblk {\et@xlblk 2\skip } \def\globmuskipblk {\et@xgblk 3\muskip } \def\locmuskipblk {\et@xlblk 3\muskip } \def\globboxblk {\et@xgblk 4\box } \def\locboxblk {\et@xlblk 4\box } \def\globtoksblk {\et@xgblk 5\toks } \def\loctoksblk {\et@xlblk 5\toks } \def\globmarksblk {\et@xgblk 6\marks } \def\locmarksblk {\et@xlblk 6\marks } % \def\et@xchkblk#1#1#3#4% , , , \def\et@xgblk#1#2#3#4% {\et@xchkblk#1#2{#4}% make sure there's still room {\allocationnumber\count26#1% \global\advance\count26#1by#4% \global\mathchardef#3\allocationnumber \wlog{\string#3=\string#2blk{\number#4} at \the\allocationnumber}% }% } \def\et@xlblk#1#2#3#4% {\et@xchkblk#1#2{#4}% make sure there's still room {\advance\count27#1-#4% \allocationnumber\count27#1% \mathchardef#3\allocationnumber \et@xwlog{\string#3=\string#2blk{\number#4} at \the\allocationnumber\space(local)}% }% } \def\et@xchkblk#1#2#3#4% {\ifnum#3<\z@ \errmessage{Negative register block size \number#3}% \else\ifnum\numexpr\count26#1+#3>\count27#1% \errmessage{No room for new #2block of size \number#3}% \else #4\fi \fi } \catcode`\G=14 \catcode`\I=14 \catcode`\N=14 \catcode`\C=14 \ProcessOptions %% Declare names for `grouptypes' G \chardef \bottomleveltype = 0 % for the outside world G \chardef \simplegrouptype = 1 % for local structure only G \chardef \hboxgrouptype = 2 % for `\hbox{}' G \chardef \adjustedhboxgrouptype = 3 % for `\hbox{}' in vertical mode G \chardef \vboxgrouptype = 4 % for `\vbox{}' G \chardef \vtopgrouptype = 5 % for `\vtop{}' G \chardef \aligngrouptype = 6 % for `\halign{}', `\valign{}' G \chardef \noaligngrouptype = 7 % for `\noalign{}' G \chardef \outputgrouptype = 8 % for output routine G \chardef \mathgrouptype = 9 % for, e.g, `^{}' G \chardef \discgrouptype = 10 % for `\discretionary{}{}{}' G \chardef \insertgrouptype = 11 % for `\insert{}', `\vadjust{}' G \chardef \vcentergrouptype = 12 % for `\vcenter{}' G \chardef \mathchoicegrouptype = 13 % for `\mathchoice{}{}{}{}' G \chardef \semisimplegrouptype = 14 % for `\begingroup...\endgroup' G \chardef \mathshiftgrouptype = 15 % for `$...$' G \chardef \mathleftgrouptype = 16 % for `\left...\right' %% Declare names for `interactionmodes' I \chardef \batchinteractionmode = 0 % omits all stops and omits terminal output I \chardef \nonstopinteractionmode = 1 % omits all stops I \chardef \scrollinteractionmode = 2 % omits error stops I \chardef \errorstopinteractionmode = 3 % stops at every opportunity to interact %% Declare names for `nodetypes' N \chardef \charnode = 0 % character nodes N \chardef \hlistnode = 1 % hlist nodes N \chardef \vlistnode = 2 % vlist nodes N \chardef \rulenode = 3 % rule nodes N \chardef \insnode = 4 % insertion nodes N \chardef \marknode = 5 % a mark node N \chardef \adjustnode = 6 % an adjust node N \chardef \ligaturenode = 7 % a ligature node N \chardef \discnode = 8 % a discretionary node N \chardef \whatsitnode = 9 % special extension nodes N \chardef \mathnode = 10 % a math node N \chardef \gluenode = 11 % node that points to a glue specification N \chardef \kernnode = 12 % a kern node N \chardef \penaltynode = 13 % a penalty node N \chardef \unsetnode = 14 % an unset node N \chardef \mathsnodes = 15 % nodes that occur only in maths mode %% Declare names for `iftypes' C \chardef \charif = 1 % \if C \chardef \catif = 2 % \ifcat C \chardef \numif = 3 % \ifnum C \chardef \dimif = 4 % \ifdim C \chardef \oddif = 5 % \ifodd C \chardef \vmodeif = 6 % \ifvmode C \chardef \hmodeif = 7 % \ifhmode C \chardef \mmodeif = 8 % \ifmmode C \chardef \innerif = 9 % \ifinner C \chardef \voidif = 10 % \ifvoid C \chardef \hboxif = 11 % \ifhbox C \chardef \vboxif = 12 % \ifvbox C \chardef \xif = 13 % \ifx C \chardef \eofif = 14 % \ifeof C \chardef \trueif = 15 % \iftrue C \chardef \falseif = 16 % \iffalse C \chardef \caseif = 17 % \ifcase C \chardef \definedif = 18 % \ifdefined C \chardef \csnameif = 19 % \ifcsname C \chardef \fontcharif = 20 % \iffontchar \catcode`\G=11 \catcode`\I=11 \catcode`\N=11 \catcode`\C=11