diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/syst-aux.mkiv')
-rw-r--r-- | Master/texmf-dist/tex/context/base/syst-aux.mkiv | 2607 |
1 files changed, 1239 insertions, 1368 deletions
diff --git a/Master/texmf-dist/tex/context/base/syst-aux.mkiv b/Master/texmf-dist/tex/context/base/syst-aux.mkiv index d2bc84ae8bc..0e43a6202bd 100644 --- a/Master/texmf-dist/tex/context/base/syst-aux.mkiv +++ b/Master/texmf-dist/tex/context/base/syst-aux.mkiv @@ -5,7 +5,7 @@ %D subtitle=General, %D author=Hans Hagen, %D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for @@ -14,6 +14,13 @@ %D Some of the macros will move to syst-obs as they might become %D obsolete once we've redone the bibliography module. Of course %D the handy helpers will stay. +%D +%D There are some references to \LUA\ variants here but these concern +%D (often old) experiments, moved from local test modules to here, +%D cleaned up, but not really used. After all it's not that urgent +%D and replacing helpers is a delicate process. Don't depend on it. + +\registerctxluafile{syst-aux}{1.001} %D This is a stripped down combination of: %D @@ -34,6 +41,9 @@ %D Some of the macros here are used in the bibliography module. They %D will be moved to a separate syst module some once the bib module %D is made \MKIV. +%D +%D The original files contain previous implementations and notes about +%D performance. This file will be stripped down in due time. \unprotect @@ -53,23 +63,6 @@ \let\unexpanded\normalprotected %D \macros -%D {doifolderversionelse} -%D -%D We start with a macro specially for Aditya who wants to be able -%D to use development versions of \MKIV\ for real documents. -%D -%D \starttyping -%D \doifolderversionelse\contextversion{1010.10.10} {OLDER} {OKAY} => OLDER -%D \doifolderversionelse\contextversion{2020.20.20} {OLDER} {OKAY} => OKAY -%D \doifolderversionelse\contextversion{2020} {OLDER} {OKAY} => OKAY -%D \stoptyping -%D -%D The version pattern is \type {yyyy.mm.dd} (with mm and dd being optional). - -\def\doifolderversionelse#1#2{\ctxcommand{doifolderversionelse("#1","#2")}} -\def\doifoldercontextelse #1{\ctxcommand{doifolderversionelse("#1")}} - -%D \macros %D {normalspace} %D %D There is already \type{\space} but just to be sure we also @@ -114,10 +107,10 @@ \def\!!plustwo {2} % alongside \plustwo \def\!!plusthree {3} % alongside \plusthree -\setnewconstant\uprotationangle 0 -\setnewconstant\rightrotatioangle 90 -\setnewconstant\downrotatioangle 180 -\setnewconstant\leftrotatioangle 270 +\setnewconstant \uprotationangle 0 +\setnewconstant\rightrotationangle 90 +\setnewconstant \downrotationangle 180 +\setnewconstant \leftrotationangle 270 \ifdefined\data \else \let\data \relax \fi % dep checker @@ -128,33 +121,34 @@ %D variables). Redefining these constants can have disastrous %D results. -\def\v!prefix! {v!} \def\c!prefix! {c!} -\def\s!prefix! {s!} \def\p!prefix! {p!} +\def\v!prefix! {v!} +\def\c!prefix! {c!} +\def\s!prefix! {s!} -\def\s!next {next} \def\s!default {default} -\def\s!dummy {dummy} \def\s!unknown {unknown} +\def\s!next {next} +\def\s!default {default} +\def\s!dummy {dummy} +\def\s!unknown {unknown} -\def\s!do {do} \def\s!dodo {dodo} +\def\s!do {do} +\def\s!dodo {dodo} -\def\s!complex {complex} \def\s!start {start} -\def\s!simple {simple} \def\s!stop {stop} +\def\s!complex {complex} +\def\s!start {start} +\def\s!simple {simple} +\def\s!stop {stop} \def\s!empty {empty} -%D \macros -%D {@EA,@EAEA,@EAEAEA,@EAEAEAEAEAEA,expanded,startexpanded} -%D -%D When in unprotected mode, to be entered with -%D \type{\unprotect}, one can use \type{\@EA} as equivalent -%D of \type{\expandafter}. - -\let\@NX\noexpand -\let\@EA\expandafter +%D These are not needed any more now that we have wide screens (and +%D bytes come cheap). -\def\@EAEA {\expandafter\expandafter} -\def\@EAEAEA{\expandafter\expandafter\expandafter} +\let\@EA \singleexpandafter +\let\@EAEAEA \doubleexpandafter +\let\@EAEAEAEAEAEA\tripleexpandafter -\def\@EAEAEAEAEAEA{\expandafter\@EAEAEA\expandafter} +\let\@NX \noexpand +\def\@EAEA {\expandafter\expandafter} % can often be avoided %D Sometimes we pass macros as arguments to commands that %D don't expand them before interpretation. Such commands can @@ -171,22 +165,24 @@ %D alternatives to this command. Beware, only the simple one %D has \type {\noexpand} before its argument. - \long\def\@@expanded{} % always long; global (less restores) +\let\@@expanded\empty % always long and global (less restores) -\long\def\expanded#1% - {\long\xdef\@@expanded{\noexpand#1}\@@expanded} +\unexpanded\def\expanded#1% + {\xdef\@@expanded{\noexpand#1}\@@expanded} -\long\def\startexpanded#1\stopexpanded % see x-fo for example - {\long\xdef\@@expanded{#1}\@@expanded} +\unexpanded\def\startexpanded#1\stopexpanded % see x-fo for example + {\xdef\@@expanded{#1}\@@expanded} + +\let\stopexpanded\relax %D Recent \TEX's have a primitive \expanded % not yet as we need to adapt ##'s in calls % -% \long\def\expanded#1% +% \def\expanded#1% % {\normalexpanded{\noexpand#1}} % -% \long\def\startexpanded#1\stopexpanded +% \def\startexpanded#1\stopexpanded % {\normalexpanded{#1}} %D \macros @@ -195,16 +191,16 @@ %D The next set of macros just do nothing, except that they %D get rid of a number of arguments. -\long\def\gobbleoneargument #1{} -\long\def\gobbletwoarguments #1#2{} -\long\def\gobblethreearguments#1#2#3{} -\long\def\gobblefourarguments #1#2#3#4{} -\long\def\gobblefivearguments #1#2#3#4#5{} -\long\def\gobblesixarguments #1#2#3#4#5#6{} -\long\def\gobblesevenarguments#1#2#3#4#5#6#7{} -\long\def\gobbleeightarguments#1#2#3#4#5#6#7#8{} -\long\def\gobbleninearguments #1#2#3#4#5#6#7#8#9{} -\long\def\gobbletenarguments #1{\gobbleninearguments} +\def\gobbleoneargument #1{} +\def\gobbletwoarguments #1#2{} +\def\gobblethreearguments#1#2#3{} +\def\gobblefourarguments #1#2#3#4{} +\def\gobblefivearguments #1#2#3#4#5{} +\def\gobblesixarguments #1#2#3#4#5#6{} +\def\gobblesevenarguments#1#2#3#4#5#6#7{} +\def\gobbleeightarguments#1#2#3#4#5#6#7#8{} +\def\gobbleninearguments #1#2#3#4#5#6#7#8#9{} +\def\gobbletenarguments #1{\gobbleninearguments} \def\gobbleoneoptional [#1]{} \def\gobbletwooptionals [#1][#2]{} @@ -237,24 +233,24 @@ %D {\localnext} because we don't want clashes with \type %D {\next}. -\long\def\doifnextcharelse#1#2#3% #1 should not be {} ! +\unexpanded\def\doifnextcharelse#1#2#3% #1 should not be {} ! {\let\charactertoken=#1% = needed here \def\!!stringa{#2}% \def\!!stringb{#3}% - \futurelet\nexttoken\inspectnextcharacter} + \futurelet\nexttoken\syst_helpers_inspect_next_character} -\def\inspectnextcharacter +\def\syst_helpers_inspect_next_character {\ifx\nexttoken\blankspace - \@EA\reinspectnextcharacter + \expandafter\syst_helpers_reinspect_next_character \else - \@EA\inspectnextcharacterindeed + \expandafter\syst_helpers_inspect_next_character_indeed \fi} -\def\inspectnextcharacterindeed +\def\syst_helpers_inspect_next_character_indeed {\ifx\nexttoken\charactertoken - \@EA\!!stringa + \expandafter\!!stringa \else - \@EA\!!stringb + \expandafter\!!stringb \fi} %D Because we will mostly use this macro for testing if the next @@ -263,87 +259,107 @@ %D test in a run. Of course it also is more convenient to read a %D trace then. -\newif\ifnextblankspacetoken +% We could make variants without the \if_next_blank_space_token but +% the overhead is only .1 sec on 3.5 for 10^6 tests and often that +% branch is not entered anyway. The fast variants with less checking +% do make a difference however: + +% \testfeature{1000000}{\doifnextoptionalelse \gobbleoneargument\gobbleoneargument[} % 2.902s +% \testfeature{1000000}{\doifnextoptionalcselse \gobbleoneargument\gobbleoneargument[} % 2.590s +% \testfeature{1000000}{\doiffastoptionalcheckelse \gobbleoneargument\gobbleoneargument[} % 2.387s +% \testfeature{1000000}{\doiffastoptionalcheckcselse\gobbleoneargument\gobbleoneargument[} % 2.168s + +\newif\if_next_blank_space_token -\let\nextoptionalcharactertoken=[ +\let\syst_helpers_next_optional_character_token=[ -\long\def\doifnextoptionalelse#1#2% - {\def\nextoptionalcommandyes{#1}% - \def\nextoptionalcommandnop{#2}% - \let\ifnextblankspacetoken\iffalse - \futurelet\nexttoken\inspectnextoptionalcharacter} +\unexpanded\def\doifnextoptionalelse#1#2% + {\def\syst_helpers_next_optional_command_yes{#1}% + \def\syst_helpers_next_optional_command_nop{#2}% + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\inspectnextoptionalcharacter +\unexpanded\def\doifnextoptionalcselse#1#2% \cs \cs (upto 10% faster) + {\let\syst_helpers_next_optional_command_yes#1% + \let\syst_helpers_next_optional_command_nop#2% + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} + +\def\syst_helpers_inspect_next_optional_character {\ifx\nexttoken\blankspace - \@EA\reinspectnextoptionalcharacter + \expandafter\syst_helpers_reinspect_next_optional_character \else - \@EA\inspectnextoptionalcharacterindeed + \expandafter\syst_helpers_inspect_next_optional_character_indeed \fi} -\def\inspectnextoptionalcharacterindeed - {\ifx\nexttoken\nextoptionalcharactertoken - \@EA\nextoptionalcommandyes +\def\syst_helpers_inspect_next_optional_character_indeed + {\ifx\nexttoken\syst_helpers_next_optional_character_token + \expandafter\syst_helpers_next_optional_command_yes \else - \@EA\nextoptionalcommandnop + \expandafter\syst_helpers_next_optional_command_nop \fi} -\let\nextbgroupcharactertoken\bgroup +\let\syst_helpers_next_bgroup_character_token\bgroup -\long\def\doifnextbgroupelse#1#2% - {\def\nextbgroupcommandyes{#1}% - \def\nextbgroupcommandnop{#2}% - \let\ifnextblankspacetoken\iffalse - \futurelet\nexttoken\inspectnextbgroupcharacter} +\unexpanded\def\doifnextbgroupelse#1#2% + {\def\syst_helpers_next_bgroup_command_yes{#1}% + \def\syst_helpers_next_bgroup_command_nop{#2}% + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character} -\def\inspectnextbgroupcharacter +\def\syst_helpers_inspect_next_bgroup_character {\ifx\nexttoken\blankspace - \@EA\reinspectnextbgroupcharacter + \expandafter\syst_helpers_reinspect_next_bgroup_character \else - \@EA\inspectnextbgroupcharacterindeed + \expandafter\syst_helpers_inspect_next_bgroup_character_indeed \fi} -\def\inspectnextbgroupcharacterindeed - {\ifx\nexttoken\nextbgroupcharactertoken - \@EA\nextbgroupcommandyes +\def\syst_helpers_inspect_next_bgroup_character_indeed + {\ifx\nexttoken\syst_helpers_next_bgroup_character_token + \expandafter\syst_helpers_next_bgroup_command_yes \else - \@EA\nextbgroupcommandnop + \expandafter\syst_helpers_next_bgroup_command_nop \fi} -\let\nextparenthesischaractertoken( +\let\syst_helpers_next_parenthesis_character_token( -\long\def\doifnextparenthesiselse#1#2% - {\def\nextparenthesiscommandyes{#1}% - \def\nextparenthesiscommandnop{#2}% - \let\ifnextblankspacetoken\iffalse - \futurelet\nexttoken\inspectnextparenthesischaracter} +\unexpanded\def\doifnextparenthesiselse#1#2% + {\def\syst_helpers_next_parenthesis_command_yes{#1}% + \def\syst_helpers_next_parenthesis_command_nop{#2}% + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_parenthesis_character} -\def\inspectnextparenthesischaracter +\def\syst_helpers_inspect_next_parenthesis_character {\ifx\nexttoken\blankspace - \@EA\reinspectnextparenthesischaracter + \expandafter\syst_helpers_reinspect_next_parenthesis_character \else - \@EA\inspectnextparenthesischaracterindeed + \expandafter\syst_helpers_inspect_next_parenthesis_character_indeed \fi} -\def\inspectnextparenthesischaracterindeed - {\ifx\nexttoken\nextparenthesischaractertoken - \@EA\nextparenthesiscommandyes +\def\syst_helpers_inspect_next_parenthesis_character_indeed + {\ifx\nexttoken\syst_helpers_next_parenthesis_character_token + \expandafter\syst_helpers_next_parenthesis_command_yes \else - \@EA\nextparenthesiscommandnop + \expandafter\syst_helpers_next_parenthesis_command_nop \fi} %D The next one is handy in predictable situations: -\long\def\doiffastoptionalcheckelse#1#2% - {\def\nextoptionalcommandyes{#1}% - \def\nextoptionalcommandnop{#2}% - \let\ifnextblankspacetoken\iffalse % not needed - \futurelet\nexttoken\dodoiffastoptionalcheckelse} +\unexpanded\def\doiffastoptionalcheckelse#1#2% + {\def\syst_helpers_next_optional_command_yes{#1}% + \def\syst_helpers_next_optional_command_nop{#2}% + \futurelet\nexttoken\syst_helpers_do_if_fast_optional_check_else} + +\unexpanded\def\doiffastoptionalcheckcselse#1#2% \cs \cs + {\let\syst_helpers_next_optional_command_yes#1% + \let\syst_helpers_next_optional_command_nop#2% + \futurelet\nexttoken\syst_helpers_do_if_fast_optional_check_else} -\def\dodoiffastoptionalcheckelse - {\ifx\nexttoken\nextoptionalcharactertoken - \expandafter\nextoptionalcommandyes +\def\syst_helpers_do_if_fast_optional_check_else + {\ifx\nexttoken\syst_helpers_next_optional_character_token + \expandafter\syst_helpers_next_optional_command_yes \else - \expandafter\nextoptionalcommandnop + \expandafter\syst_helpers_next_optional_command_nop \fi} %D This macro uses some auxiliary macros. Although we were able @@ -361,18 +377,23 @@ %D \type{\:} becomes a delimiter of the longer named %D \type{\reinspectnextcharacter}. +% try: \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_character} {...} + \let\next\: \def\:{\let\blankspace= } \: -\def\:{\reinspectnextcharacter} -\expandafter\def\: {\let\ifnextblankspacetoken\iftrue\futurelet\nexttoken\inspectnextcharacter} +\def\:{\syst_helpers_reinspect_next_character} +\expandafter\def\: {\let\if_next_blank_space_token\iftrue\futurelet\nexttoken\syst_helpers_inspect_next_character} + +\def\:{\syst_helpers_reinspect_next_optional_character} +\expandafter\def\: {\let\if_next_blank_space_token\iftrue\futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\:{\reinspectnextoptionalcharacter} -\expandafter\def\: {\let\ifnextblankspacetoken\iftrue\futurelet\nexttoken\inspectnextoptionalcharacter} +\def\:{\syst_helpers_reinspect_next_bgroup_character} +\expandafter\def\: {\let\if_next_blank_space_token\iftrue\futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character} -\def\:{\reinspectnextbgroupcharacter} -\expandafter\def\: {\let\ifnextblankspacetoken\iftrue\futurelet\nexttoken\inspectnextbgroupcharacter} +\def\:{\syst_helpers_reinspect_next_parenthesis_character} +\expandafter\def\: {\let\if_next_blank_space_token\iftrue\futurelet\nexttoken\syst_helpers_inspect_next_parenthesis_character} \let\:\next @@ -465,53 +486,27 @@ % % use a real if like \ifcsname#1\endcsname\else instead -\ifdefined\suppressifcsnameerror - - \suppressifcsnameerror\plusone - - \def\doifundefinedelse#1% - {\ifcsname#1\endcsname - \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments - \fi} - - \def\doifdefinedelse#1% - {\ifcsname#1\endcsname - \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments - \fi} +\suppressifcsnameerror\plusone - \def\doifundefined#1% - {\ifcsname#1\endcsname - \@EA\gobbleoneargument\else\@EA\firstofoneargument - \fi} - - \def\doifdefined#1% - {\ifcsname#1\endcsname - \@EA\firstofoneargument\else\@EA\gobbleoneargument - \fi} - -\else - - \def\doifundefinedelse#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments - \fi} - - \def\doifdefinedelse#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments - \fi} +\def\doifundefinedelse#1% + {\ifcsname#1\endcsname + \expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments + \fi} - \def\doifundefined#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\gobbleoneargument\else\@EA\firstofoneargument - \fi} +\def\doifdefinedelse#1% + {\ifcsname#1\endcsname + \expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments + \fi} - \def\doifdefined#1% - {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname - \@EA\firstofoneargument\else\@EA\gobbleoneargument - \fi} +\def\doifundefined#1% + {\ifcsname#1\endcsname + \expandafter\gobbleoneargument\else\expandafter\firstofoneargument + \fi} -\fi +\def\doifdefined#1% + {\ifcsname#1\endcsname + \expandafter\firstofoneargument\else\expandafter\gobbleoneargument + \fi} %D \macros %D {letbeundefined} @@ -540,21 +535,22 @@ %D was due to this grouping subtilities. We therefore decided %D to use \type{\begingroup} instead of \type{\bgroup}. -\def\docheckonedefined#1% - {\ifcsname#1\endcsname\else - \donefalse - \expandafter\quitcommalist % added - \fi} - -\def\doifalldefinedelse#1% +\unexpanded\def\doifalldefinedelse#1% {\begingroup - \donetrue \processcommalist[#1]\docheckonedefined + \donetrue % we could use a reserved one and avoid the group + \processcommalist[#1]\syst_helpers_do_if_all_defined_else \ifdone \endgroup\expandafter\firstoftwoarguments \else \endgroup\expandafter\secondoftwoarguments \fi} +\def\syst_helpers_do_if_all_defined_else#1% + {\ifcsname#1\endcsname\else + \donefalse + \expandafter\quitcommalist % added + \fi} + %D \macros %D {doif,doifelse,doifnot} %D @@ -574,24 +570,27 @@ %D \doifelse {string1} {string2} {then ...}{else ...} %D \stoptyping -\long\def\doif#1#2% - {\edef\!!stringa{#1}\edef\!!stringb{#2}% +\unexpanded\def\doif#1#2% + {\edef\!!stringa{#1}% + \edef\!!stringb{#2}% \ifx\!!stringa\!!stringb \expandafter\firstofoneargument \else \expandafter\gobbleoneargument \fi} -\long\def\doifnot#1#2% - {\edef\!!stringa{#1}\edef\!!stringb{#2}% +\unexpanded\def\doifnot#1#2% + {\edef\!!stringa{#1}% + \edef\!!stringb{#2}% \ifx\!!stringa\!!stringb \expandafter\gobbleoneargument \else \expandafter\firstofoneargument \fi} -\long\def\doifelse#1#2% - {\edef\!!stringa{#1}\edef\!!stringb{#2}% +\unexpanded\def\doifelse#1#2% + {\edef\!!stringa{#1}% + \edef\!!stringb{#2}% \ifx\!!stringa\!!stringb \expandafter\firstoftwoarguments \else @@ -611,7 +610,7 @@ %D %D This time, the string is not expanded. -\long\def\doifemptyelse#1% +\unexpanded\def\doifemptyelse#1% {\def\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\firstoftwoarguments @@ -619,7 +618,7 @@ \expandafter\secondoftwoarguments \fi} -\long\def\doifempty#1% +\unexpanded\def\doifempty#1% {\def\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\firstofoneargument @@ -627,7 +626,7 @@ \expandafter\gobbleoneargument \fi} -\long\def\doifnotempty#1% +\unexpanded\def\doifnotempty#1% {\def\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\gobbleoneargument @@ -675,128 +674,128 @@ % !5yes=\doifnotinset{}{}{yes} % !6yes=\doifnotinset{aaa}{}{yes} -\def\rightoptionalbracket{]} +\def\v_syst_helpers_right_optional_bracket{]} -\long\def\doquitifiteminsetelse#1],\relax{\firstoftwoarguments} -\long\def\doquitifiteminset #1],\relax{\firstofoneargument} -\long\def\doquitifitemnotinset #1],\relax{\gobbleoneargument} +\def\syst_helpers_do_quit_if_item_in_set_else#1],\relax{\firstoftwoarguments} +\def\syst_helpers_do_quit_if_item_in_set #1],\relax{\firstofoneargument} +\def\syst_helpers_do_quit_if_item_not_in_set #1],\relax{\gobbleoneargument} -\long\def\redoifinsetelse{\expandafter\docheckifiteminsetelse\!!stringb,],\relax} -\long\def\redoifinset {\expandafter\docheckifiteminset \!!stringb,],\relax} -\long\def\redoifnotinset {\expandafter\docheckifitemnotinset \!!stringb,],\relax} +\def\syst_helpers_re_do_if_in_set_else{\expandafter\syst_helpers_do_check_if_item_in_set_else\!!stringb,],\relax} +\def\syst_helpers_re_do_if_in_set {\expandafter\syst_helpers_do_check_if_item_in_set \!!stringb,],\relax} +\def\syst_helpers_re_do_if_not_in_set {\expandafter\syst_helpers_do_check_if_item_not_in_set \!!stringb,],\relax} -\long\def\doifinsetelse#1% make this two step too +\unexpanded\def\doifinsetelse#1% make this two step too {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\thirdofthreearguments \else - \expandafter\dodoifinsetelse + \expandafter\syst_helpers_do_if_in_set_else \fi} -\long\def\dodoifinsetelse#1% +\def\syst_helpers_do_if_in_set_else#1% {\edef\!!stringb{#1}% \ifx\!!stringb\empty \expandafter\secondoftwoarguments \else - \expandafter\redoifinsetelse + \expandafter\syst_helpers_re_do_if_in_set_else \fi} -\long\def\doifinset#1% +\unexpanded\def\doifinset#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\gobbletwoarguments \else - \expandafter\dodoifinset + \expandafter\syst_helpers_do_if_in_set \fi} -\long\def\dodoifinset#1% +\def\syst_helpers_do_if_in_set#1% {\edef\!!stringb{#1}% \ifx\!!stringb\empty \expandafter\gobbleoneargument \else - \expandafter\redoifinset + \expandafter\syst_helpers_re_do_if_in_set \fi} -\long\def\doifnotinset#1% +\unexpanded\def\doifnotinset#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\secondoftwoarguments \else - \expandafter\dodoifnotinset + \expandafter\syst_helpers_do_if_not_in_set \fi} -\long\def\dodoifnotinset#1% +\def\syst_helpers_do_if_not_in_set#1% {\edef\!!stringb{#1}% \ifx\!!stringb\empty \expandafter\firstofoneargument \else - \expandafter\redoifnotinset % ...]{true} + \expandafter\syst_helpers_re_do_if_not_in_set % ...]{true} \fi} -\def\docheckifiteminsetelse#1,#2% #2 eats up preceding space +\def\syst_helpers_do_check_if_item_in_set_else#1,#2% #2 eats up preceding space {\edef\!!stringb{#1}% \ifx\!!stringb\empty - \expandafter\docheckifiteminsetelse + \expandafter\syst_helpers_do_check_if_item_in_set_else \else - \expandafter\dodocheckifiteminsetelse + \expandafter\syst_helpers_do_do_check_if_item_in_set_else \fi#2} -\def\dodocheckifiteminsetelse - {\ifx\!!stringb\rightoptionalbracket +\def\syst_helpers_do_do_check_if_item_in_set_else + {\ifx\!!stringb\v_syst_helpers_right_optional_bracket \expandafter\thirdofthreearguments \else - \expandafter\dododocheckifiteminsetelse + \expandafter\syst_helpers_do_do_do_check_if_item_in_set_else \fi} -\def\dododocheckifiteminsetelse +\def\syst_helpers_do_do_do_check_if_item_in_set_else {\ifx\!!stringa\!!stringb - \expandafter\doquitifiteminsetelse + \expandafter\syst_helpers_do_quit_if_item_in_set_else \else - \expandafter\docheckifiteminsetelse + \expandafter\syst_helpers_do_check_if_item_in_set_else \fi} -\def\docheckifiteminset#1,#2% #2 eats up preceding space +\def\syst_helpers_do_check_if_item_in_set#1,#2% #2 eats up preceding space {\edef\!!stringb{#1}% \ifx\!!stringb\empty - \expandafter\docheckifiteminset + \expandafter\syst_helpers_do_check_if_item_in_set \else - \expandafter\dodocheckifiteminset + \expandafter\syst_helpers_do_do_check_if_item_in_set \fi#2} -\def\dodocheckifiteminset - {\ifx\!!stringb\rightoptionalbracket +\def\syst_helpers_do_do_check_if_item_in_set + {\ifx\!!stringb\v_syst_helpers_right_optional_bracket \expandafter\gobbletwoarguments \else - \expandafter\dododocheckifiteminset + \expandafter\syst_helpers_do_do_do_check_if_item_in_set \fi} -\def\dododocheckifiteminset +\def\syst_helpers_do_do_do_check_if_item_in_set {\ifx\!!stringa\!!stringb - \expandafter\doquitifiteminset + \expandafter\syst_helpers_do_quit_if_item_in_set \else - \expandafter\docheckifiteminset + \expandafter\syst_helpers_do_check_if_item_in_set \fi} -\def\docheckifitemnotinset#1,#2% #2 eats up preceding space +\def\syst_helpers_do_check_if_item_not_in_set#1,#2% #2 eats up preceding space {\edef\!!stringb{#1}% \ifx\!!stringb\empty - \expandafter\docheckifitemnotinset + \expandafter\syst_helpers_do_check_if_item_not_in_set \else - \expandafter\dodocheckifitemnotinset + \expandafter\syst_helpers_do_do_check_if_item_not_in_set \fi#2} -\def\dodocheckifitemnotinset - {\ifx\!!stringb\rightoptionalbracket +\def\syst_helpers_do_do_check_if_item_not_in_set + {\ifx\!!stringb\v_syst_helpers_right_optional_bracket \expandafter\secondoftwoarguments \else - \expandafter\dododocheckifitemnotinset + \expandafter\syst_helpers_do_do_do_check_if_item_not_in_set \fi} -\def\dododocheckifitemnotinset +\def\syst_helpers_do_do_do_check_if_item_not_in_set {\ifx\!!stringa\!!stringb - \expandafter\doquitifitemnotinset + \expandafter\syst_helpers_do_quit_if_item_not_in_set \else - \expandafter\docheckifitemnotinset + \expandafter\syst_helpers_do_check_if_item_not_in_set \fi} %D \macros @@ -827,61 +826,65 @@ % !9yes=\doifcommonelse{,a,}{,,,a,}{yes}{nop} % !9yes=\doifcommonelse{,,a,}{,,,a,}{yes}{nop} -\long\def\doquitifcommonelse#1],\relax#2],\relax{\firstoftwoarguments} +\let\m_syst_common_a\empty +\let\m_syst_common_b\empty +\let\m_syst_common_c\empty -\long\def\doquitifcommonelsenop{\secondoftwoarguments} +\def\syst_helpers_do_quit_if_common_else#1],\relax#2],\relax{\firstoftwoarguments} -\def\docheckifcommonelseone#1,#2% - {\edef\!!stringc{#1}% - \ifx\!!stringc\rightoptionalbracket +\def\syst_helpers_do_check_if_common_else_one#1,#2% + {\edef\m_syst_common_c{#1}% + \ifx\m_syst_common_c\v_syst_helpers_right_optional_bracket \expandafter\thirdofthreearguments \else - \expandafter\p!docommoncheck + \expandafter\syst_helpers_do_common_check \fi#2} -\def\docheckifcommonelsetwo#1,#2% we can do an empty #1 check too +\def\syst_helpers_do_check_if_common_else_two#1,#2% we can do an empty #1 check too {\edef\commalistelement{#1}% - \ifx\commalistelement\rightoptionalbracket - \expandafter\redocheckifcommonelseone + \ifx\commalistelement\v_syst_helpers_right_optional_bracket + \expandafter\syst_helpers_re_do_check_if_common_else_one \else - \expandafter\dodocheckifcommonelsetwo + \expandafter\syst_helpers_do_do_check_if_common_else_two \fi#2} -\def\dodocheckifcommonelsetwo +\def\syst_helpers_do_do_check_if_common_else_two {\ifx\commalistelement\empty - \expandafter\docheckifcommonelsetwo + \expandafter\syst_helpers_do_check_if_common_else_two \else - \expandafter\dododocheckifcommonelsetwo + \expandafter\syst_helpers_do_do_do_check_if_common_else_two \fi} -\def\dododocheckifcommonelsetwo - {\ifx\!!stringc\commalistelement - \expandafter\doquitifcommonelse +\def\syst_helpers_do_do_do_check_if_common_else_two + {\ifx\m_syst_common_c\commalistelement + \expandafter\syst_helpers_do_quit_if_common_else \else - \expandafter\docheckifcommonelsetwo + \expandafter\syst_helpers_do_check_if_common_else_two \fi} -\def\redocheckifcommonelseone#1{\docheckifcommonelseone} +\def\syst_helpers_re_do_check_if_common_else_one#1{\syst_helpers_do_check_if_common_else_one} -\def\p!doifcommonelse#1#2#3#4% - {\edef\!!stringa{#3}% - \edef\!!stringb{#4}% - \ifx\!!stringa\empty +\def\syst_helpers_do_common_check + {\expandafter\syst_helpers_do_check_if_common_else_two\m_syst_common_b,],\relax}% + +\def\syst_helpers_do_do_do_if_common_else + {\expandafter\syst_helpers_do_check_if_common_else_one\m_syst_common_a,],\relax} + +\def\syst_helpers_do_do_if_common_else#1#2#3#4% + {\edef\m_syst_common_a{#3}% + \edef\m_syst_common_b{#4}% + \ifx\m_syst_common_a\empty \expandafter\secondoftwoarguments - \else\ifx\!!stringb\empty + \else\ifx\m_syst_common_b\empty \expandafter\expandafter\expandafter\secondoftwoarguments \else - \expandafter\expandafter\expandafter\pp!doifcommonelse + \expandafter\expandafter\expandafter\syst_helpers_do_do_do_if_common_else \fi\fi #1#2} -\def\pp!doifcommonelse - {\def\p!docommoncheck{\expandafter\docheckifcommonelsetwo\!!stringb,],\relax}% - \expandafter\docheckifcommonelseone\!!stringa,],\relax} - -\def\doifcommonelse{\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments} -\def\doifcommon {\p!doifcommonelse\firstofoneargument \gobbleoneargument } -\def\doifnotcommon {\p!doifcommonelse\gobbleoneargument \firstofoneargument } +\unexpanded\def\doifcommonelse{\syst_helpers_do_do_if_common_else\firstoftwoarguments\secondoftwoarguments} +\unexpanded\def\doifcommon {\syst_helpers_do_do_if_common_else\firstofoneargument \gobbleoneargument } +\unexpanded\def\doifnotcommon {\syst_helpers_do_do_if_common_else\gobbleoneargument \firstofoneargument } %D \macros %D {processcommalist,processcommacommand,quitcommalist, @@ -917,68 +920,72 @@ \newcount\commalevel -\def\dododoprocesscommaitem +\def\syst_helpers_do_do_do_process_comma_item {\csname\s!next\the\commalevel\endcsname} -\def\dodoprocesscommaitem +\def\syst_helpers_do_do_process_comma_item {\ifx\nexttoken\blankspace - \@EA\redoprocesscommaitem + \expandafter\syst_helpers_re_do_process_comma_item \else - \@EA\dodoprocesscommaitemindeed + \expandafter\syst_helpers_do_do_process_comma_item_indeed \fi} -\def\dodoprocesscommaitemindeed +\def\syst_helpers_do_do_process_comma_item_indeed {\ifx\nexttoken]% - \@EA\gobbleoneargument + \expandafter\gobbleoneargument \else - \@EA\dododoprocesscommaitem + \expandafter\syst_helpers_do_do_do_process_comma_item \fi} -\def\doprocesscommaitem - {\futurelet\nexttoken\dodoprocesscommaitem} +\def\syst_helpers_do_process_comma_item + {\futurelet\nexttoken\syst_helpers_do_do_process_comma_item} %D Empty arguments are not processed. Empty items (\type{,,}) %D however are treated. We have to check for the special case %D \type{[{a,b,c}]}. \unexpanded\def\processcommalist[% - {\futurelet\nexttoken\docheckcommaitem} + {\futurelet\nexttoken\syst_helpers_do_check_comma_item} -\def\docheckcommaitem +\def\syst_helpers_do_check_comma_item {\ifx\nexttoken]% \expandafter\gobblethreearguments \else - \expandafter\doprocesscommalist + \expandafter\syst_helpers_do_process_comma_list \fi \relax} % this one preserved the next {} -\def\doprocesscommalist#1]#2% +\def\syst_helpers_do_process_comma_list#1]#2% {\global\advance\commalevel \plusone - \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% - {#2{##1}\doprocesscommaitem}% - \@EA\dodoprocesscommaitem\gobbleoneargument#1,]\relax + \expandafter\def\csname\s!next\the\commalevel\endcsname##1,% + {#2{##1}\syst_helpers_do_process_comma_item}% + \expandafter\syst_helpers_do_do_process_comma_item\gobbleoneargument#1,]\relax \global\advance\commalevel \minusone } %D One way of quitting a commalist halfway is: \def\quitcommalist - {\begingroup\let\doprocesscommaitem\doquitcommalist} + {\begingroup\let\syst_helpers_do_process_comma_item\syst_helpers_do_quit_comma_list} -\def\doquitcommalist#1]% +\def\syst_helpers_do_quit_comma_list#1]% {\endgroup} \def\quitprevcommalist - {\begingroup\let\doprocesscommaitem\doquitprevcommalist} + {\begingroup\let\syst_helpers_do_process_comma_item\syst_helpers_do_quit_prev_comma_list} -\def\doquitprevcommalist#1]% - {\let\doprocesscommaitem\doquitcommalist} +\def\syst_helpers_do_quit_prev_comma_list#1]% + {\let\syst_helpers_do_process_comma_item\syst_helpers_do_quit_comma_list} %D The hack we used for checking the next character %D \type {\doifnextcharelse} is also used here. -\def\:{\redoprocesscommaitem} +\let\next\: + +\def\:{\syst_helpers_re_do_process_comma_item} % \:not saved ? -\expandafter\def\: {\futurelet\nexttoken\dodoprocesscommaitem} +\expandafter\def\: {\futurelet\nexttoken\syst_helpers_do_do_process_comma_item} + +\let\:\next %D The previous examples lead to: %D @@ -1028,21 +1035,21 @@ %D \def\command[#1]{... #1 ...} %D \stoptyping -\def\processcommalistwithparameters[#1]#2% - {\def\docommand##1{#2[##1]}% - \processcommalist[#1]\docommand} +\unexpanded\def\processcommalistwithparameters[#1]#2% + {\def\syst_helpers_do_process_comma_list_with_parameters##1{#2[##1]}% + \processcommalist[#1]\syst_helpers_do_process_comma_list_with_parameters} %D \macros %D {startprocesscommalist,startprocesscommacommand} %D %D Two more: -\long\unexpanded\def\startprocesscommalist[#1]#2\stopprocesscommalist - {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% +\unexpanded\def\startprocesscommalist[#1]#2\stopprocesscommalist + {\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% \processcommalist[#1]\currentcommalistcommand} -\long\unexpanded\def\startprocesscommacommand[#1]#2\stopprocesscommacommand - {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% +\unexpanded\def\startprocesscommacommand[#1]#2\stopprocesscommacommand + {\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% \normalexpanded{\processcommalist[#1]}\currentcommalistcommand} %D \macros @@ -1087,7 +1094,9 @@ \newcount\processlevel -\def\p!compareprocessactionA[#1=>#2][#3]% +% obsolete: \def\expandactions{\let\expandedaction\edef} \expandactions (see mkii) + +\unexpanded\def\syst_helpers_do_compare_process_action_a[#1=>#2][#3]% {\edef\!!stringb{#1}% \ifx\!!stringb\s!default \let\commalistelement\empty @@ -1096,34 +1105,30 @@ % met \quitcommalist tot meer dan 25\% sneller -\def\p!compareprocessactionB[#1=>#2][#3]% - {\expandedaction\!!stringb{#1}% +\unexpanded\def\syst_helpers_do_compare_process_action_b[#1=>#2][#3]% + {\edef\!!stringb{#1}% \ifx\!!stringa\!!stringb \def\commalistelement{#3}% #2% \expandafter\quitcommalist - \else - \edef\!!stringb{#1}% - \ifx\!!stringb\s!unknown - \def\commalistelement{#3}% beware of loops - #2% - \fi - \fi} + \else\ifx\!!stringb\s!unknown + \def\commalistelement{#3}% beware of loops + #2% + \fi\fi} -\def\processaction[#1]#2[% - {\expandedaction\!!stringa{#1}% +\unexpanded\def\processaction[#1]#2[% + {\edef\!!stringa{#1}% \ifx\!!stringa\empty - \let\p!compareprocessaction\p!compareprocessactionA + \let\syst_helpers_do_compare_process_action\syst_helpers_do_compare_process_action_a \else - \let\p!compareprocessaction\p!compareprocessactionB + \let\syst_helpers_do_compare_process_action\syst_helpers_do_compare_process_action_b \fi - \def\p!doprocessaction##1% - {\p!compareprocessaction[##1][#1]}% - \processnextcommalist\relax\expandactions\p!doprocessaction[} + \edef\syst_helpers_do_process_action##1{\syst_helpers_do_compare_process_action[##1][#1]}% expands #1 + \processnextcommalist\relax\relax\syst_helpers_do_process_action[} -\def\p!compareprocessactionC[#1=>#2][#3]% - {\expandedaction\!!stringa{#1}% - \expandedaction\!!stringb{#3}% +\unexpanded\def\syst_helpers_do_compare_process_action_c[#1=>#2][#3]% + {\edef\!!stringa{#1}% + \edef\!!stringb{#3}% \ifx\!!stringa\!!stringb \def\commalistelement{#3}% #2% @@ -1137,25 +1142,23 @@ \fi} \unexpanded\def\processfirstactioninset[#1]% - {\expandedaction\!!stringa{#1}% + {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\processaction \else - \expandafter\processfirstactionsinsetindeed + \expandafter\syst_helpers_process_first_action_in_set_indeed \fi [#1]} -\unexpanded\def\processfirstactionsinsetindeed[#1]#2[#3]% - {\def\p!doprocessaction##1% - {\def\p!dodoprocessaction####1% - {\p!compareprocessactionC[####1][##1]}% - \processcommalist[#3]\p!dodoprocessaction}% - \processcommalist[#1]\p!doprocessaction - \expandactions} - -\def\p!compareprocessactionD[#1=>#2][#3]% - {\expandedaction\!!stringa{#1}% - \expandedaction\!!stringb{#3}% +\unexpanded\def\syst_helpers_process_first_action_in_set_indeed[#1]#2[#3]% + {\def\syst_helpers_do_process_action##1% + {\def\syst_helpers_do_do_process_action####1{\syst_helpers_do_compare_process_action_c[####1][##1]}% + \processcommalist[#3]\syst_helpers_do_do_process_action}% + \normalexpanded{\processcommalist[#1]}\syst_helpers_do_process_action} + +\unexpanded\def\syst_helpers_do_compare_process_action_d[#1=>#2][#3]% + {\edef\!!stringa{#1}% + \edef\!!stringb{#3}% \ifx\!!stringa\!!stringb \def\commalistelement{#3}% #2% @@ -1168,71 +1171,39 @@ \fi \fi} -\def\doprocessallactionsinset +\unexpanded\def\syst_helpers_do_process_all_actions_in_set {\csname\s!do\the\processlevel\endcsname} \unexpanded\def\processallactionsinset[#1]% - {\expandedaction\!!stringa{#1}% + {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\processaction \else - \expandafter\processallactionsinsetindeed + \expandafter\syst_helpers_process_all_actions_in_set_indeed \fi [#1]} -\unexpanded\def\processallactionsinsetindeed[#1]#2[#3]% +\unexpanded\def\syst_helpers_process_all_actions_in_set_indeed[#1]#2[#3]% {\advance\processlevel \plusone \expandafter\def\csname\s!do\the\processlevel\endcsname##1% - {\def\p!dodoprocessaction####1% - {\p!compareprocessactionD[####1][##1]}% - \processcommalist[#3]\p!dodoprocessaction}% - \processcommalist[#1]\doprocessallactionsinset - \advance\processlevel \minusone - \expandactions} + {\def\syst_helpers_do_do_process_action####1{\syst_helpers_do_compare_process_action_d[####1][##1]}% + \processcommalist[#3]\syst_helpers_do_do_process_action}% + \normalexpanded{\processcommalist[#1]}\syst_helpers_do_process_all_actions_in_set + \advance\processlevel\minusone} %D These macros use: -\def\processnextcommalist#1#2#3[#4#5]% +\unexpanded\def\processnextcommalist#1#2#3[#4#5]% {#1% \let\nexttoken#4% \global\advance\commalevel \plusone - \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% - {#3{##1}\doprocesscommaitem}% - \dodoprocesscommaitem#4#5,]\relax - \global\advance\commalevel \minusone + \expandafter\def\csname\s!next\the\commalevel\endcsname##1,% + {#3{##1}\syst_helpers_do_process_comma_item}% + \syst_helpers_do_do_process_comma_item#4#5,]\relax + \global\advance\commalevel\minusone #2} %D \macros -%D {unexpandedprocessaction, -%D unexpandedprocessfirstactioninset, -%D unexpandedprocessallactionsinset} -%D -%D Now what are those expansion commands doing there. Well, -%D sometimes we want to compare actions that may consist off -%D commands (i.e. are no constants). In such occasions we can -%D use the a bit slower alternatives: - -\def\unexpandedprocessfirstactioninset{\dontexpandactions\processfirstactioninset} -\def\unexpandedprocessaction {\dontexpandactions\processaction} -\def\unexpandedprocessallactionsinset {\dontexpandactions\processallactionsinset} - -%D By default we expand actions: - -\def\expandactions{\let\expandedaction\edef} \expandactions - -%D But when needed we convert the strings to meaningful -%D sequences of characters. - -\def\unexpandedaction#1>{} - -\def\noexpandedaction#1#2% - {\def\@@convertedargument{#2}% - \@EA\edef\@EA#1\@EA{\@EA\unexpandedaction\meaning\@@convertedargument}} - -\def\dontexpandactions - {\let\expandedaction\noexpandedaction} - -%D \macros %D {getfirstcharacter, firstcharacter, remainingcharacters, doiffirstcharacter} %D %D Sometimes the action to be undertaken depends on the @@ -1247,27 +1218,8 @@ %D complicated arguments, for instance arguments that %D consist of two or more expandable tokens. -\def\dogetfirstcharacter#1#2\relax - {\def\firstcharacter{#1}% - \def\remainingcharacters{#2}} - -\def\getfirstcharacter#1% - {\edef\!!stringa{#1}% - \expandafter\dogetfirstcharacter\!!stringa\relax} - -\def\doiffirstcharelse#1#2% char string -% kort (maar onleesbaar) -% {\expanded{\dogetfirstcharacter#2}\\\doifelse{#1}\firstcharacter} -% korter (en begrijpelijk)) - {\getfirstcharacter{#2}\doifelse{#1}\firstcharacter} -% snel (maar zelden gebruikt, dus niet zo belangrijk) -% {\getfirstcharacter{#2}% -% \edef\!!stringa{#1}% -% \ifx\!!stringa\firstcharacter -% \expandafter\firstoftwoarguments -% \else -% \expandafter\secondoftwoarguments -% \fi} +\def\getfirstcharacter #1{\ctxcommand{getfirstcharacter(\!!bs#1\!!es)}} +\def\doiffirstcharelse#1#2{\ctxcommand{doiffirstcharelse(\!!bs#1\!!es,\!!bs#2\!!es)}} % chr str %D \macros %D {doifinstringelse, doifincsnameelse} @@ -1279,56 +1231,57 @@ %D \doifinsetelse {substring} {string} {then ...} {else ...} %D \stoptyping -\long\def\doifinstringelse#1% +\unexpanded\def\doifinstringelse#1% {\edef\@@@instring{#1}% expand #1 here \ifx\@@@instring\empty - \@EA\thirdofthreearguments + \expandafter\thirdofthreearguments \else - \@EA\dodoifinstringelse + \expandafter\syst_helpers_do_if_in_string_else_indeed \fi} -\long\def\dodoifinstringelse#1% - {\p!doifinstringelse\@@@instring{#1}% - \@EA\firstoftwoarguments +\unexpanded\def\syst_helpers_do_if_in_string_else_indeed#1% + {\syst_helpers_do_if_in_string_else\@@@instring{#1}% + \expandafter\firstoftwoarguments \else - \@EA\secondoftwoarguments + \expandafter\secondoftwoarguments \fi} -\long\def\doifinstring#1%% +\unexpanded\def\doifinstring#1%% {\edef\@@@instring{#1}% expand #1 here \ifx\@@@instring\empty - \@EA\gobbletwoarguments + \expandafter\gobbletwoarguments \else - \@EA\dodoifinstring + \expandafter\syst_helpers_do_if_in_string_indeed \fi} -\long\def\dodoifinstring#1% - {\p!doifinstringelse\@@@instring{#1}% - \@EA\firstofoneargument +\unexpanded\def\syst_helpers_do_if_in_string_indeed#1% + {\syst_helpers_do_if_in_string_else\@@@instring{#1}% + \expandafter\firstofoneargument \else - \@EA\gobbleoneargument + \expandafter\gobbleoneargument \fi} -\long\def\doifnotinstring#1%% +\unexpanded\def\doifnotinstring#1%% {\edef\@@@instring{#1}% expand #1 here \ifx\@@@instring\empty - \@EA\gobbletwoarguments + \expandafter\gobbletwoarguments \else - \@EA\dodoifnotinstring + \expandafter\syst_helpers_do_if_not_in_string_indeed \fi} -\long\def\dodoifnotinstring#1% - {\p!doifinstringelse\@@@instring{#1}% - \@EA\gobbleoneargument +\unexpanded\def\syst_helpers_do_if_not_in_string_indeed#1% + {\syst_helpers_do_if_in_string_else\@@@instring{#1}% + \expandafter\gobbleoneargument \else - \@EA\firstofoneargument + \expandafter\firstofoneargument \fi} % replaces prev -\long\def\p!doifinstringelse#1#2% ##2 can be {abc} - {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here - \expandafter\pp!doifinstringelse\normalexpanded{#2#1}@@\war} % expand #2 here +\unexpanded\def\syst_helpers_do_if_in_string_else#1#2% ##2 can be {abc} + {\expandafter\def\expandafter\syst_helpers_do_do_if_in_string_else + \expandafter##\expandafter1#1##2##3\war{\unless\if##2@}% expand #1 here + \expandafter\syst_helpers_do_do_if_in_string_else\normalexpanded{#2#1}@@\war} % expand #2 here %D The next alternative proved to be upto twice as fast on %D tasks like checking reserved words in pretty verbatim @@ -1343,14 +1296,14 @@ %D possible, the latter alternative does minimal (one level) %D expansion. -\long\def\p!doifincsnameelse#1#2% - {\long\def\pp!doifincsnameelse##1#1##2##3\war +\unexpanded\def\syst_helpers_do_if_in_csname_else#1#2% + {\def\syst_helpers_do_do_if_in_csname_else##1#1##2##3\war {\unless\if##2@}% - \@EA\pp!doifincsnameelse#2#1@@\war} + \expandafter\syst_helpers_do_do_if_in_csname_else#2#1@@\war} -\long\def\doifincsnameelse#1#2% % #3#4% +\unexpanded\def\doifincsnameelse#1#2% {\edef\@@@instring{#1}% - \@EA\p!doifincsnameelse\@EA{\@@@instring}{#2}% % #3\else#4\fi} + \expandafter\syst_helpers_do_if_in_csname_else\expandafter{\@@@instring}{#2}% \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments @@ -1372,7 +1325,7 @@ %D \type{\getal} and \type{\the\count...}. This macro is a %D rather dirty one. -\long\def\doifnumberelse#1% does not accept counters +\def\doifnumberelse#1% does not accept counters (fully expandable) {\ifcase0\ifcase1#1\or\or\or\or\or\or\or\or\or\else1\fi\space \expandafter\secondoftwoarguments \else @@ -1407,26 +1360,26 @@ %D length of the argument (the longer the argument, the less %D we gain). -\def\makerawcommalist[#1]#2% use \processnext ... here - {\def\domakerawcommalist##1% we don't expand ##1 +\unexpanded\def\makerawcommalist[#1]#2% use \processnext ... here + {\def\syst_helpers_do_make_raw_comma_list##1% we don't expand ##1 {\ifx#2\empty \def#2{##1}% \else - \@EA\def\@EA#2\@EA{#2,##1}% + \expandafter\def\expandafter#2\expandafter{#2,##1}% \fi}% \let#2\empty - \processcommalist[#1]\domakerawcommalist} + \processcommalist[#1]\syst_helpers_do_make_raw_comma_list} -\def\rawprocesscommaitem#1,#2% #2 eats up preceding space +\def\syst_helpers_raw_process_comma_item#1,#2% #2 eats up preceding space {\if]#1\else \csname\s!next\the\commalevel\endcsname{#1}% - \expandafter\rawprocesscommaitem + \expandafter\syst_helpers_raw_process_comma_item \fi#2} \unexpanded\def\rawprocesscommalist[#1]#2% accepteert ook [\cs] {\global\advance\commalevel \plusone \expandafter\let\csname\s!next\the\commalevel\endcsname#2% - \expandafter\rawprocesscommaitem#1,],% \relax + \expandafter\syst_helpers_raw_process_comma_item#1,],% \relax \global\advance\commalevel \minusone } \unexpanded\def\rawprocesscommacommand[#1]% not really needed @@ -1437,55 +1390,55 @@ \def\@@rawempty{,,} -\long\def\rawdoifinsetelse#1% +\unexpanded\def\rawdoifinsetelse#1% {\edef\@@@instring{,#1,}% expand #1 here \ifx\@@@instring\@@rawempty - \@EA\thirdofthreearguments + \expandafter\thirdofthreearguments \else - \@EA\rawdodoifinsetelse + \expandafter\syst_helpers_raw_do_if_in_set_else \fi} -\long\def\rawdodoifinsetelse#1% - {\p!doifinstringelse\@@@instring{,#1,}% - \@EA\firstoftwoarguments +\unexpanded\def\syst_helpers_raw_do_if_in_set_else#1% + {\syst_helpers_do_if_in_string_else\@@@instring{,#1,}% + \expandafter\firstoftwoarguments \else - \@EA\secondoftwoarguments + \expandafter\secondoftwoarguments \fi} -\long\def\rawdoifinset#1% +\unexpanded\def\rawdoifinset#1% {\edef\@@@instring{,#1,}% expand #1 here \ifx\@@@instring\@@rawempty - \@EA\gobbletwoarguments + \expandafter\gobbletwoarguments \else - \@EA\rawdodoifinset + \expandafter\syst_helpers_raw_do_if_in_set \fi} -\long\def\rawdodoifinset#1%% - {\p!doifinstringelse\@@@instring{,#1,}% - \@EA\firstofoneargument +\unexpanded\def\syst_helpers_raw_do_if_in_set#1%% + {\syst_helpers_do_if_in_string_else\@@@instring{,#1,}% + \expandafter\firstofoneargument \else - \@EA\gobbleoneargument + \expandafter\gobbleoneargument \fi} %D Some more raw material: -\def\p!rawprocessaction[#1][#2]% - {\def\pp!rawprocessaction##1,#1=>##2,##3\war% +\def\syst_helpers_do_raw_process_action[#1][#2]% + {\def\syst_helpers_do_do_raw_process_action##1,#1=>##2,##3\war {\if##3@\else \def\!!processaction{##2}% \fi}% - \pp!rawprocessaction,#2,#1=>,@\war} + \syst_helpers_do_do_raw_process_action,#2,#1=>,@\war} -\def\rawprocessaction[#1]#2[#3]% +\unexpanded\def\rawprocessaction[#1]#2[#3]% {\edef\!!stringa{#1}% \edef\!!stringb{undefined}% better \!!undefined \let\!!processaction\!!stringb \ifx\!!stringa\empty - \@EA\p!rawprocessaction\@EA[\s!default][#3]% + \expandafter\syst_helpers_do_raw_process_action\expandafter[\s!default][#3]% \else - \expandafter\p!rawprocessaction\expandafter[\!!stringa][#3]% + \expandafter\syst_helpers_do_raw_process_action\expandafter[\!!stringa][#3]% \ifx\!!processaction\!!stringb - \@EA\p!rawprocessaction\@EA[\s!unknown][#3]% + \expandafter\syst_helpers_do_raw_process_action\expandafter[\s!unknown][#3]% \fi \fi \ifx\!!processaction\!!stringb @@ -1519,22 +1472,22 @@ %D for use outside the assignment macros. \def\dosetvalue#1#2% #3 - {\@EA\def\csname#1#2\endcsname} % {#3}} + {\expandafter\def\csname#1#2\endcsname} % {#3}} \def\dosetevalue#1#2% #3 - {\@EA\edef\csname#1#2\endcsname} % {#3}} + {\expandafter\edef\csname#1#2\endcsname} % {#3}} \def\dosetgvalue#1#2% #3 - {\@EA\gdef\csname#1#2\endcsname} % {#3}} + {\expandafter\gdef\csname#1#2\endcsname} % {#3}} \def\doresetvalue#1#2% - {\@EA\let\csname#1#2\endcsname\empty} + {\expandafter\let\csname#1#2\endcsname\empty} \def\doignorevalue#1#2#3% - {\@EA\let\csname#1#2\endcsname\empty} + {\expandafter\let\csname#1#2\endcsname\empty} \def\docopyvalue#1#2#3% - {\@EA\def\csname#1#3\endcsname{\csname#2#3\endcsname}} + {\expandafter\def\csname#1#3\endcsname{\csname#2#3\endcsname}} %D \macros %D {doassign,undoassign,doassignempty} @@ -1656,13 +1609,13 @@ \let\currentvalue\empty -\def\getparameters {\dogetparameters\dosetvalue} -\def\geteparameters {\dogetparameters\dosetevalue} -\def\getgparameters {\dogetparameters\dosetgvalue} -\def\getxparameters {\dogetparameters\dosetxvalue} -\def\forgetparameters{\dogetparameters\doignorevalue} +\unexpanded\def\getparameters {\dogetparameters\dosetvalue} +\unexpanded\def\geteparameters {\dogetparameters\dosetevalue} +\unexpanded\def\getgparameters {\dogetparameters\dosetgvalue} +\unexpanded\def\getxparameters {\dogetparameters\dosetxvalue} +\unexpanded\def\forgetparameters{\dogetparameters\doignorevalue} -\let\getexpandedparameters=\geteparameters +\let\getexpandedparameters\geteparameters \def\dogetparameters#1[#2]#3[#4% {\if\noexpand#4]% @@ -1676,14 +1629,14 @@ \def\xdogetparameters#1]% {\xprocesscommaitem#1,],\@relax@} -\long\def\xprocesscommaitem#1,#2% #2 takes space before , +\def\xprocesscommaitem#1,#2% #2 takes space before , {\if,#1,% dirty trick for testing #1=empty - \@EA\xprocesscommaitem + \expandafter\xprocesscommaitem \else\if]#1% - \@EAEAEA\gobbleoneargument + \doubleexpandafter\gobbleoneargument \else \p!dogetparameter\@relax@#1==\empty\@relax@ - \@EAEAEA\xprocesscommaitem + \doubleexpandafter\xprocesscommaitem \fi\fi#2} \def\xshowassignerror#1#2#3% @@ -1691,26 +1644,26 @@ \def\p!n!doassign#1\@relax@#2=#3=#4#5\@relax@ {\ifx\empty#2\empty - \@EA\xshowassignerror + \expandafter\xshowassignerror \else\ifx#4\empty - \@EAEAEA\xshowassignerror + \doubleexpandafter\xshowassignerror \else - \@EAEAEA\setsomevalue + \doubleexpandafter\setsomevalue \fi\fi {#1}{#2}{#3}} \def\p!e!doassign#1\@relax@#2=#3=#4#5\@relax@ {\ifx\empty#2\empty - \@EA\xshowassignerror + \expandafter\xshowassignerror \else\ifx#4\empty - \@EAEAEA\xshowassignerror + \doubleexpandafter\xshowassignerror \else \ifcsname#1#2\endcsname - \@EA\let\@EA\currentvalue\csname#1#2\endcsname + \expandafter\let\expandafter\currentvalue\csname#1#2\endcsname \else \let\currentvalue\empty \fi - \@EAEAEA\setsomevalue + \doubleexpandafter\setsomevalue \fi\fi {#1}{#2}{#3}} @@ -1741,12 +1694,12 @@ \unexpanded\def\processassignmentcommand[#1]% {\normalexpanded{\processassignmentlist[#1]}} -\long\unexpanded\def\startprocessassignmentlist[#1]#2\stopprocessassignmentlist - {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% +\unexpanded\def\startprocessassignmentlist[#1]#2\stopprocessassignmentlist + {\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% \processassignmentlist[#1]\currentassignmentlistcommand} -\long\unexpanded\def\startprocessassignmentcommand[#1]#2\stopprocessassignmentcommand - {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% +\unexpanded\def\startprocessassignmentcommand[#1]#2\stopprocessassignmentcommand + {\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% \normalexpanded{\processassignmentlist[#1]}\currentassignmentlistcommand} %D \macros{currentvalue} @@ -1846,7 +1799,7 @@ %D By using \type{\docopyvalue} we've prepared this command %D for use in a multi||lingual environment. -\def\copyparameters[#1]#2[#3]#4[#5]% +\unexpanded\def\copyparameters[#1]#2[#3]#4[#5]% {\doifnot{#1}{#3} {\def\docopyparameter{\docopyvalue{#1}{#3}}% ##1 \processcommalist[#5]\docopyparameter}} @@ -1975,7 +1928,7 @@ % check sources \def\dogetcommacommandelement#1\from#2\to% - {\@EA\dodogetcommalistelement\@EA#1\@EA\from#2,,,,,,\to} + {\expandafter\dodogetcommalistelement\expandafter#1\expandafter\from#2,,,,,,\to} %D \macros %D {dosingleargument,dodoubleargument,dotripleargument, @@ -2031,13 +1984,13 @@ %D us to do some checking, we reimplemented the non||empty %D ones. -\def\dosingleargument {\let\expectedarguments\plusone \dosingleempty } -\def\dodoubleargument {\let\expectedarguments\plustwo \dodoubleempty } -\def\dotripleargument {\let\expectedarguments\plusthree \dotripleempty } -\def\doquadrupleargument {\let\expectedarguments\plusfour \doquadrupleempty } -\def\doquintupleargument {\let\expectedarguments\plusfive \doquintupleempty } -\def\dosixtupleargument {\let\expectedarguments\plussix \dosixtupleempty } -\def\doseventupleargument{\let\expectedarguments\plusseven \doseventupleempty} +\unexpanded\def\dosingleargument {\let\expectedarguments\plusone \dosingleempty } +\unexpanded\def\dodoubleargument {\let\expectedarguments\plustwo \dodoubleempty } +\unexpanded\def\dotripleargument {\let\expectedarguments\plusthree \dotripleempty } +\unexpanded\def\doquadrupleargument {\let\expectedarguments\plusfour \doquadrupleempty } +\unexpanded\def\doquintupleargument {\let\expectedarguments\plusfive \doquintupleempty } +\unexpanded\def\dosixtupleargument {\let\expectedarguments\plussix \dosixtupleempty } +\unexpanded\def\doseventupleargument{\let\expectedarguments\plusseven \doseventupleempty} %D \macros %D {iffirstagument,ifsecondargument,ifthirdargument, @@ -2100,169 +2053,6 @@ \def\noshowargumenterror {\let\expectedarguments\noexpectedarguments} -% \long\def\dogetargument#1#2#3#4% -% {\let\charactertoken=#1% -% \def\!!stringa{\noshowargumenterror#3\dodogetargument}% -% \def\!!stringb{\doshowargumenterror#4\dodogetargument#1#2}% -% \futurelet\nexttoken\inspectnextcharacter} - -% \def\getsingleempty#1#2#3% -% {\def\dodogetargument% -% {#3}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\getdoubleempty#1#2#3% -% {\def\dodogetargument#1##1#2% -% {\def\dodogetargument% -% {#3#1{##1}#2}% -% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\gettripleempty#1#2#3% -% {\def\dodogetargument#1##1#2% -% {\def\dodogetargument#1####1#2% -% {\def\dodogetargument% -% {#3#1{##1}#2% -% #1{####1}#2}% -% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% -% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\getquadrupleempty#1#2#3% -% {\def\dodogetargument#1##1#2% -% {\def\dodogetargument#1####1#2% -% {\def\dodogetargument#1########1#2% -% {\def\dodogetargument% -% {#3#1{##1}#2% -% #1{####1}#2% -% #1{########1}#2}% -% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% -% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% -% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\getquintupleempty#1#2#3% -% {\def\dodogetargument#1##1#2% -% {\def\dodogetargument#1####1#2% -% {\def\dodogetargument#1########1#2% -% {\def\dodogetargument#1################1#2% -% {\def\dodogetargument% -% {#3#1{##1}#2% -% #1{####1}#2% -% #1{########1}#2% -% #1{################1}#2}% -% \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% -% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% -% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% -% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\getsixtupleempty#1#2#3% -% {\def\dodogetargument#1##1#2% -% {\def\dodogetargument#1####1#2% -% {\def\dodogetargument#1########1#2% -% {\def\dodogetargument#1################1#2% -% {\def\dodogetargument#1################################1#2% -% {\def\dodogetargument% -% {#3#1{##1}#2% -% #1{####1}#2% -% #1{########1}#2% -% #1{################1}#2% -% #1{################################1}#2}% -% \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% -% \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% -% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% -% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% -% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\getseventupleempty#1#2#3% -% {\def\dodogetargument#1##1#2% -% {\def\dodogetargument#1####1#2% -% {\def\dodogetargument#1########1#2% -% {\def\dodogetargument#1################1#2% -% {\def\dodogetargument#1################################1#2% -% {\def\dodogetargument#1################################% -% ################################1#2% -% {\def\dodogetargument% -% {#3#1{##1}#2% -% #1{####1}#2% -% #1{########1}#2% -% #1{################1}#2% -% #1{################################1}#2% -% #1{################################% -% ################################1}#2}% -% \dogetargument#1#2\seventhargumenttrue\seventhargumentfalse}% -% \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% -% \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% -% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% -% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% -% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% -% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -% \def\dosingleempty {\getsingleempty []} -% \def\dodoubleempty {\getdoubleempty []} -% \def\dotripleempty {\gettripleempty []} -% \def\doquadrupleempty {\getquadrupleempty []} -% \def\doquintupleempty {\getquintupleempty []} -% \def\dosixtupleempty {\getsixtupleempty []} -% \def\doseventupleempty{\getseventupleempty[]} - -%D Because some of these are called quite often, we will now -%D replace the more general version by alternatives tuned for -%D speed. - -% \def\dosingleempty#1% we can make dedicated doifnextoptional's -% {\noshowargumenterror % \relax % prevents lookahead, brr -% \doifnextoptionalelse -% {\firstargumenttrue#1}% -% {\dosinglefakeempty#1}} -% -% \def\dosinglefakeempty#1% -% {\firstargumentfalse#1[]} -% -% \def\dodoubleempty#1% -% {\noshowargumenterror % \relax % prevents lookahead, brr -% \doifnextoptionalelse -% {\dodoubletestempty#1}% -% {\dodoublefakeempty#1}} -% -% \def\dodoublefakeempty#1% -% {\firstargumentfalse\secondargumentfalse#1[][]} -% -% \long\def\dodoubletestempty#1[#2]% -% {\firstargumenttrue -% \doifnextoptionalelse -% {\secondargumenttrue #1[{#2}]}% -% {\secondargumentfalse#1[{#2}][]}} -% -% \def\dotripleempty#1% -% {\noshowargumenterror % \relax % prevents lookahead, brr -% \doifnextoptionalelse -% {\dotripletestempty#1}% -% {\dotriplefakeempty#1}} -% -% \def\dotriplefakeempty#1% -% {\firstargumentfalse\secondargumentfalse\thirdargumentfalse#1[][][]} -% -% \long\def\dotripletestempty#1[#2]% -% {\firstargumenttrue -% \doifnextoptionalelse -% {\dotripletestemptyx #1[{#2}]}% -% {\secondargumentfalse -% \thirdargumentfalse #1[{#2}][][]}} -% -% \long\def\dotripletestemptyx#1[#2][#3]% -% {\secondargumenttrue -% \doifnextoptionalelse -% {\thirdargumenttrue #1[{#2}][{#3}]}% -% {\thirdargumentfalse#1[{#2}][{#3}][]}} - -%D We can obey following spaces with a bit more code. - -% 0.172 0.187 new (per 10000) -% 0.156 0.140 old (per 10000) -% % \def\test[#1]{(#1)} % % \dosingleempty\test[] xxx\par @@ -2283,7 +2073,7 @@ %D Single: -\def\dosingleempty#1% +\unexpanded\def\dosingleempty#1% {\noshowargumenterror \doifnextoptionalelse {\firstargumenttrue#1}% @@ -2295,13 +2085,13 @@ %D Double -\def\dodoubleempty#1% +\unexpanded\def\dodoubleempty#1% {\noshowargumenterror \doifnextoptionalelse {\dodoubleemptyYESone#1}% {\dodoubleemptyNOPone#1}} -\long\def\dodoubleemptyYESone#1[#2]% +\def\dodoubleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse {\secondargumenttrue#1[{#2}]}% @@ -2314,7 +2104,7 @@ \def\dodoubleemptyNOPtwo {\secondargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dodoubleemptyonespaced \else \expandafter\dodoubleemptyonenormal @@ -2325,19 +2115,19 @@ % Three -\def\dotripleempty#1% +\unexpanded\def\dotripleempty#1% {\noshowargumenterror \doifnextoptionalelse {\dotripleemptyYESone#1}% {\dotripleemptyNOPone#1}} -\long\def\dotripleemptyYESone#1[#2]% +\def\dotripleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse {\dotripleemptyYEStwo#1{#2}}% {\dotripleemptyNOPtwo#1{#2}}} -\long\def\dotripleemptyYEStwo#1#2[#3]% +\def\dotripleemptyYEStwo#1#2[#3]% {\secondargumenttrue \doifnextoptionalelse {\thirdargumenttrue#1[{#2}][{#3}]}% @@ -2352,7 +2142,7 @@ \def\dotripleemptyNOPtwo {\secondargumentfalse \thirdargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dotripleemptytwospaced \else \expandafter\dotripleemptytwonormal @@ -2360,7 +2150,7 @@ \def\dotripleemptyNOPthree {\thirdargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dotripleemptythreespaced \else \expandafter\dotripleemptythreenormal @@ -2373,25 +2163,25 @@ %D Four: -\def\doquadrupleempty#1% +\unexpanded\def\doquadrupleempty#1% {\noshowargumenterror \doifnextoptionalelse {\doquadrupleemptyYESone#1}% {\doquadrupleemptyNOPone#1}} -\long\def\doquadrupleemptyYESone#1[#2]% +\def\doquadrupleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse {\doquadrupleemptyYEStwo#1{#2}}% {\doquadrupleemptyNOPtwo#1{#2}}} -\long\def\doquadrupleemptyYEStwo#1#2[#3]% +\def\doquadrupleemptyYEStwo#1#2[#3]% {\secondargumenttrue \doifnextoptionalelse {\doquadrupleemptyYESthree#1{#2}{#3}}% {\doquadrupleemptyNOPthree#1{#2}{#3}}} -\long\def\doquadrupleemptyYESthree#1#2#3[#4]% +\def\doquadrupleemptyYESthree#1#2#3[#4]% {\thirdargumenttrue \doifnextoptionalelse {\fourthargumenttrue#1[{#2}][{#3}][{#4}]}% @@ -2408,7 +2198,7 @@ {\secondargumentfalse \thirdargumentfalse \fourthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquadrupleemptytwospaced \else \expandafter\doquadrupleemptytwonormal @@ -2417,7 +2207,7 @@ \def\doquadrupleemptyNOPthree {\thirdargumentfalse \fourthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquadrupleemptythreespaced \else \expandafter\doquadrupleemptythreenormal @@ -2425,7 +2215,7 @@ \def\doquadrupleemptyNOPfour {\fourthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquadrupleemptyfourspaced \else \expandafter\doquadrupleemptyfournormal @@ -2440,31 +2230,31 @@ %D Five: -\def\doquintupleempty#1% +\unexpanded\def\doquintupleempty#1% {\noshowargumenterror \doifnextoptionalelse {\doquintupleemptyYESone#1}% {\doquintupleemptyNOPone#1}} -\long\def\doquintupleemptyYESone#1[#2]% +\def\doquintupleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse {\doquintupleemptyYEStwo#1{#2}}% {\doquintupleemptyNOPtwo#1{#2}}} -\long\def\doquintupleemptyYEStwo#1#2[#3]% +\def\doquintupleemptyYEStwo#1#2[#3]% {\secondargumenttrue \doifnextoptionalelse {\doquintupleemptyYESthree#1{#2}{#3}}% {\doquintupleemptyNOPthree#1{#2}{#3}}} -\long\def\doquintupleemptyYESthree#1#2#3[#4]% +\def\doquintupleemptyYESthree#1#2#3[#4]% {\thirdargumenttrue \doifnextoptionalelse {\doquintupleemptyYESfour#1{#2}{#3}{#4}}% {\doquintupleemptyNOPfour#1{#2}{#3}{#4}}} -\long\def\doquintupleemptyYESfour#1#2#3#4[#5]% +\def\doquintupleemptyYESfour#1#2#3#4[#5]% {\fourthargumenttrue \doifnextoptionalelse {\fifthargumenttrue#1[{#2}][{#3}][{#4}][{#5}]}% @@ -2483,7 +2273,7 @@ \thirdargumentfalse \fourthargumentfalse \fifthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquintupleemptytwospaced \else \expandafter\doquintupleemptytwonormal @@ -2493,7 +2283,7 @@ {\thirdargumentfalse \fourthargumentfalse \fifthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquintupleemptythreespaced \else \expandafter\doquintupleemptythreenormal @@ -2502,7 +2292,7 @@ \def\doquintupleemptyNOPfour {\fourthargumentfalse \fifthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquintupleemptyfourspaced \else \expandafter\doquintupleemptyfournormal @@ -2510,7 +2300,7 @@ \def\doquintupleemptyNOPfive {\fifthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\doquintupleemptyfivespaced \else \expandafter\doquintupleemptyfivenormal @@ -2527,37 +2317,37 @@ %D Six -\def\dosixtupleempty#1% +\unexpanded\def\dosixtupleempty#1% {\noshowargumenterror \doifnextoptionalelse {\dosixtupleemptyYESone#1} {\dosixtupleemptyNOPone#1}} -\long\def\dosixtupleemptyYESone#1[#2]% +\def\dosixtupleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse {\dosixtupleemptyYEStwo#1{#2}}% {\dosixtupleemptyNOPtwo#1{#2}}} -\long\def\dosixtupleemptyYEStwo#1#2[#3]% +\def\dosixtupleemptyYEStwo#1#2[#3]% {\secondargumenttrue \doifnextoptionalelse {\dosixtupleemptyYESthree#1{#2}{#3}}% {\dosixtupleemptyNOPthree#1{#2}{#3}}} -\long\def\dosixtupleemptyYESthree#1#2#3[#4]% +\def\dosixtupleemptyYESthree#1#2#3[#4]% {\thirdargumenttrue \doifnextoptionalelse {\dosixtupleemptyYESfour#1{#2}{#3}{#4}}% {\dosixtupleemptyNOPfour#1{#2}{#3}{#4}}} -\long\def\dosixtupleemptyYESfour#1#2#3#4[#5]% +\def\dosixtupleemptyYESfour#1#2#3#4[#5]% {\fourthargumenttrue \doifnextoptionalelse {\dosixtupleemptyYESfive#1{#2}{#3}{#4}{#5}}% {\dosixtupleemptyNOPfive#1{#2}{#3}{#4}{#5}}} -\long\def\dosixtupleemptyYESfive#1#2#3#4#5[#6]% +\def\dosixtupleemptyYESfive#1#2#3#4#5[#6]% {\fifthargumenttrue \doifnextoptionalelse {\sixthargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}]}% @@ -2578,7 +2368,7 @@ \fourthargumentfalse \fifthargumentfalse \sixthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosixemptytwospaced \else \expandafter\dosixemptytwonormal @@ -2589,7 +2379,7 @@ \fourthargumentfalse \fifthargumentfalse \sixthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosixemptythreespaced \else \expandafter\dosixemptythreenormal @@ -2599,7 +2389,7 @@ {\fourthargumentfalse \fifthargumentfalse \sixthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosixemptyfourspaced \else \expandafter\dosixemptyfournormal @@ -2608,7 +2398,7 @@ \def\dosixtupleemptyNOPfive {\fifthargumentfalse \sixthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosixemptyfivespaced \else \expandafter\dosixemptyfivenormal @@ -2616,7 +2406,7 @@ \def\dosixtupleemptyNOPsix {\sixthargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosixemptysixspaced \else \expandafter\dosixemptysixnormal @@ -2635,43 +2425,43 @@ %D Seven: -\def\doseventupleempty#1% +\unexpanded\def\doseventupleempty#1% {\noshowargumenterror \doifnextoptionalelse {\doseventupleemptyYESone#1}% {\doseventupleemptyNOPone#1}} -\long\def\doseventupleemptyYESone#1[#2]% +\def\doseventupleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse {\doseventupleemptyYEStwo#1{#2}}% {\doseventupleemptyNOPtwo#1{#2}}} -\long\def\doseventupleemptyYEStwo#1#2[#3]% +\def\doseventupleemptyYEStwo#1#2[#3]% {\secondargumenttrue \doifnextoptionalelse {\doseventupleemptyYESthree#1{#2}{#3}}% {\doseventupleemptyNOPthree#1{#2}{#3}}} -\long\def\doseventupleemptyYESthree#1#2#3[#4]% +\def\doseventupleemptyYESthree#1#2#3[#4]% {\thirdargumenttrue \doifnextoptionalelse {\doseventupleemptyYESfour#1{#2}{#3}{#4}}% {\doseventupleemptyNOPfour#1{#2}{#3}{#4}}} -\long\def\doseventupleemptyYESfour#1#2#3#4[#5]% +\def\doseventupleemptyYESfour#1#2#3#4[#5]% {\fourthargumenttrue \doifnextoptionalelse {\doseventupleemptyYESfive#1{#2}{#3}{#4}{#5}}% {\doseventupleemptyNOPfive#1{#2}{#3}{#4}{#5}}} -\long\def\doseventupleemptyYESfive#1#2#3#4#5[#6]% +\def\doseventupleemptyYESfive#1#2#3#4#5[#6]% {\fifthargumenttrue \doifnextoptionalelse {\doseventupleemptyYESsix#1{#2}{#3}{#4}{#5}{#6}}% {\doseventupleemptyNOPsix#1{#2}{#3}{#4}{#5}{#6}}} -\long\def\doseventupleemptyYESsix#1#2#3#4#5#6[#7]% +\def\doseventupleemptyYESsix#1#2#3#4#5#6[#7]% {\sixthargumenttrue \doifnextoptionalelse {\seventhargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}]}% @@ -2694,7 +2484,7 @@ \fifthargumentfalse \sixthargumentfalse \seventhargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosevenemptytwospaced \else \expandafter\dosevenemptytwonormal @@ -2706,7 +2496,7 @@ \fifthargumentfalse \sixthargumentfalse \seventhargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosevenemptythreespaced \else \expandafter\dosevenemptythreenormal @@ -2717,7 +2507,7 @@ \fifthargumentfalse \sixthargumentfalse \seventhargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosevenemptyfourspaced \else \expandafter\dosevenemptyfournormal @@ -2727,7 +2517,7 @@ {\fifthargumentfalse \sixthargumentfalse \seventhargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosevenemptyfivespaced \else \expandafter\dosevenemptyfivenormal @@ -2736,7 +2526,7 @@ \def\doseventupleemptyNOPsix {\sixthargumentfalse \seventhargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosevenemptysixspaced \else \expandafter\dosevenemptysixnormal @@ -2744,7 +2534,7 @@ \def\doseventupleemptyNOPseven {\seventhargumentfalse - \ifnextblankspacetoken + \if_next_blank_space_token \expandafter\dosevenemptysevenspaced \else \expandafter\dosevenemptysevennormal @@ -2819,13 +2609,13 @@ %D but changed into more versatile (more object oriented) ones %D using the \type{\get..argument} commands. -\def\complexorsimple#1% +\unexpanded\def\complexorsimple#1% {% \relax % prevents lookahead, brrr \doifnextoptionalelse {\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname} {\firstargumentfalse\csname\s!simple \strippedcsname#1\endcsname}} -\def\complexorsimpleempty#1% +\unexpanded\def\complexorsimpleempty#1% {% \relax % prevents lookahead, brrr \doifnextoptionalelse {\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname} @@ -2847,13 +2637,13 @@ \unexpanded\def\definecomplexorsimple#1% {\unexpanded\edef#1% {\noexpand\docomplexorsimple - \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname - \@EA\noexpand\csname\s!simple \strippedcsname#1\endcsname}} + \expandafter\noexpand\csname\s!complex\strippedcsname#1\endcsname + \expandafter\noexpand\csname\s!simple \strippedcsname#1\endcsname}} \unexpanded\def\definecomplexorsimpleempty#1% {\unexpanded\edef#1% {\noexpand\docomplexorsimpleempty - \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname}} + \expandafter\noexpand\csname\s!complex\strippedcsname#1\endcsname}} %D These commands are called as: %D @@ -3016,32 +2806,34 @@ %D used to select arguments. Their names explain their %D functionality. -\long\def\firstofoneargument #1{#1} +\def\firstofoneargument #1{#1} -\long\def\firstoftwoarguments #1#2{#1} -\long\def\secondoftwoarguments #1#2{#2} +\def\firstoftwoarguments #1#2{#1} +\def\secondoftwoarguments #1#2{#2} -\long\def\firstofthreearguments #1#2#3{#1} -\long\def\secondofthreearguments #1#2#3{#2} -\long\def\thirdofthreearguments #1#2#3{#3} +\def\firstofthreearguments #1#2#3{#1} +\def\secondofthreearguments #1#2#3{#2} +\def\thirdofthreearguments #1#2#3{#3} -\long\def\firstoffourarguments #1#2#3#4{#1} -\long\def\secondoffourarguments #1#2#3#4{#2} -\long\def\thirdoffourarguments #1#2#3#4{#3} -\long\def\fourthoffourarguments #1#2#3#4{#4} +\def\firstoffourarguments #1#2#3#4{#1} +\def\secondoffourarguments #1#2#3#4{#2} +\def\thirdoffourarguments #1#2#3#4{#3} +\def\fourthoffourarguments #1#2#3#4{#4} -\long\def\firstoffivearguments #1#2#3#4#5{#1} -\long\def\secondoffivearguments #1#2#3#4#5{#2} -\long\def\thirdoffivearguments #1#2#3#4#5{#3} -\long\def\fourthoffivearguments #1#2#3#4#5{#4} -\long\def\fifthoffivearguments #1#2#3#4#5{#5} +\def\firstoffivearguments #1#2#3#4#5{#1} +\def\secondoffivearguments #1#2#3#4#5{#2} +\def\thirdoffivearguments #1#2#3#4#5{#3} +\def\fourthoffivearguments #1#2#3#4#5{#4} +\def\fifthoffivearguments #1#2#3#4#5{#5} -\long\def\firstofsixarguments #1#2#3#4#5#6{#1} -\long\def\secondofsixarguments#1#2#3#4#5#6{#2} -\long\def\thirdofsixarguments #1#2#3#4#5#6{#3} -\long\def\fourthofsixarguments#1#2#3#4#5#6{#4} -\long\def\fifthofsixarguments #1#2#3#4#5#6{#5} -\long\def\sixthofsixarguments #1#2#3#4#5#6{#6} +\def\firstofsixarguments #1#2#3#4#5#6{#1} +\def\secondofsixarguments#1#2#3#4#5#6{#2} +\def\thirdofsixarguments #1#2#3#4#5#6{#3} +\def\fourthofsixarguments#1#2#3#4#5#6{#4} +\def\fifthofsixarguments #1#2#3#4#5#6{#5} +\def\sixthofsixarguments #1#2#3#4#5#6{#6} + +\unexpanded\def\firstofoneunexpanded#1{#1} %D \macros %D {globalletempty,letempty, @@ -3220,7 +3012,7 @@ %D Apart from the prefixes, a few more \type{\expandafters} %D are needed: -\def\newif#1% +\unexpanded\def\newif#1% {\scratchcounter\escapechar \escapechar\minusone \expandafter\expandafter\expandafter @@ -3237,16 +3029,16 @@ \unexpanded\def\define#1% {\ifdefined#1% \message{[\noexpand#1is already defined]}% - \expandafter\def\expandafter\gobbleddefinition + \unexpanded\expandafter\def\expandafter\gobbleddefinition \else - \expandafter\def + \unexpanded\expandafter\def \fi#1} \def\redefine#1% {\ifdefined#1% \message{[\noexpand#1is redefined]}% \fi - \def#1} + \unexpanded\def#1} % \define\hans{hans} % \redefine\hans{hans} @@ -3270,6 +3062,40 @@ % % [\test] +% todo: pick up keywords: +% +% \starttexdefinition unexpanded bagger .... + +% \bgroup \obeylines +% +% \gdef\starttexdefinition% +% {\bgroup% +% \obeylines% +% \dostarttexdefinition} +% +% \gdef\dostarttexdefinition #1 +% {\catcode\endoflineasciicode\ignorecatcode% +% \doifinstringelse\letterhash{\detokenize{#1}}\dodostarttexdefinition\nonostarttexdefinition#1 +% } +% +% \gdef\dodostarttexdefinition#1 #2 +% {\dododostarttexdefinition{#1}{#2}} +% +% \gdef\dododostarttexdefinition#1#2#3\stoptexdefinition% +% {\egroup% +% \expandafter\def\csname#1\endcsname#2{#3}} +% +% \gdef\nonostarttexdefinition#1 +% {\nononostarttexdefinition{#1}{}} +% +% \gdef\nononostarttexdefinition#1#2#3\stoptexdefinition% +% {\egroup% +% \expandafter\def\csname#1\endcsname{#3}} +% +% \egroup + +\def\s!unexpanded{unexpanded} + \bgroup \obeylines \gdef\starttexdefinition% @@ -3282,22 +3108,37 @@ \doifinstringelse\letterhash{\detokenize{#1}}\dodostarttexdefinition\nonostarttexdefinition#1 } -\long\gdef\dodostarttexdefinition#1 #2 - {\dododostarttexdefinition{#1}{#2}} - -\long\gdef\dododostarttexdefinition#1#2#3\stoptexdefinition% +\gdef\dodostarttexdefinition#1 #2 + {\edef\texdefinitionname{#1}% + \ifx\texdefinitionname\s!unexpanded% + \expandafter\dododostarttexdefinitionU% + \else% + \expandafter\dododostarttexdefinitionN% + \fi% + {#1}#2 + } + +\gdef\dododostarttexdefinitionU#1#2 #3 + #4\stoptexdefinition% + {\egroup% #1=unexpanded + \unexpanded\expandafter\def\csname#2\endcsname#3{#4}} + +\gdef\dododostarttexdefinitionN#1#2 + #3\stoptexdefinition% {\egroup% \expandafter\def\csname#1\endcsname#2{#3}} -\long\gdef\nonostarttexdefinition#1 +\gdef\nonostarttexdefinition#1 {\nononostarttexdefinition{#1}{}} -\long\gdef\nononostarttexdefinition#1#2#3\stoptexdefinition% +\gdef\nononostarttexdefinition#1#2#3\stoptexdefinition% {\egroup% \expandafter\def\csname#1\endcsname{#3}} \egroup +\unexpanded\def\texdefinition#1{\csname\ifcsname#1\endcsname#1\else donothing\fi\endcsname} + % This is a first variant, more might be added: \def\starttexcode{\unprotect} @@ -3367,26 +3208,20 @@ %D Nowadays we don't mind a few more tokens if we can gain a %D bit of speed. -\def\doincrement#1% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\plusone \relax}} -\def\dodecrement#1% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\minusone\relax}} +\def\syst_helpers_do_increment#1{\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\plusone \relax}} +\def\syst_helpers_do_decrement#1{\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\minusone\relax}} -\def\dododoincrement#1,#2)% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+#2\relax}} -\def\dodododecrement#1,#2)% - {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi-#2\relax}} +\def\syst_helpers_do_do_do_increment#1,#2){\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+#2\relax}} +\def\syst_helpers_do_do_do_decrement#1,#2){\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi-#2\relax}} -\def\dodoincrement(#1% - {\doifnextcharelse,{\dododoincrement#1}{\dododoincrement#1,\plusone}} -\def\dododecrement(#1% - {\doifnextcharelse,{\dodododecrement#1}{\dodododecrement#1,\plusone}} +\def\syst_helpers_do_do_increment(#1{\doifnextcharelse,{\syst_helpers_do_do_do_increment#1}{\syst_helpers_do_do_do_increment#1,\plusone}} +\def\syst_helpers_do_do_decrement(#1{\doifnextcharelse,{\syst_helpers_do_do_do_decrement#1}{\syst_helpers_do_do_do_decrement#1,\plusone}} \def\fastincrement#1{\dodoglobal\edef#1{\the\numexpr#1+\plusone \relax}} \def\fastdecrement#1{\dodoglobal\edef#1{\the\numexpr#1+\minusone\relax}} -\def\increment{\doifnextcharelse(\dodoincrement\doincrement} -\def\decrement{\doifnextcharelse(\dododecrement\dodecrement} +\def\increment{\doifnextcharelse(\syst_helpers_do_do_increment\syst_helpers_do_increment} +\def\decrement{\doifnextcharelse(\syst_helpers_do_do_decrement\syst_helpers_do_decrement} \def\incrementvalue#1{\expandafter\increment\csname#1\endcsname} \def\decrementvalue#1{\expandafter\decrement\csname#1\endcsname} @@ -3443,77 +3278,6 @@ \fi} %D \macros -%D {newconditional, -%D settrue, setfalse, -%D ifconditional,then} -%D -%D \TEX's lacks boolean variables, although the \PLAIN\ format -%D implements \type{\newif}. The main disadvantage of this -%D scheme is that it takes three hash table entries. A more -%D memory saving alternative is presented here. A conditional -%D is defined by: -%D -%D \starttyping -%D \newconditional\doublesided -%D \setfalse -%D \stoptyping -%D Setting a conditional is done by \type{\settrue} and -%D \type{\setfalse}: -%D -%D \starttyping -%D \settrue\doublesided -%D \setfalse -%D \stoptyping -%D while testing is accomplished by: -%D -%D \starttyping -%D \ifconditional\doublesided ... \else ... \fi -%D \setfalse -%D \stoptyping -%D We cannot use the simple scheme: -%D -%D \starttyping -%D \def\settrue #1{\let#1=\iftrue} -%D \def\setfalse#1{\let#1=\iffalse} -%D \stoptyping -%D -%D Such an implementation gives problems with nested -%D conditionals. The next implementation is abaou as fast -%D and just as straightforward: - -% maybe reserve special zero and plusone - -\def\settrue #1{\let#1\zerocount} -\def\setfalse#1{\let#1\plusone} - -\let\newconditional\setfalse -\let\ifconditional \ifcase - -\let\then\relax % so that we can say: \ifnum1>2\then -) - -% demands that each conditional is defined .. it would be handy to have -% a primitive \unless\ifcase .. then we could use better values -% -% \def\settrue #1{#1\zerocount} -% \def\setfalse#1{#1\plusone} -% -% \def\newconditional#1{\ifdefined#1\else\newcount#1\fi\setfalse#1} -% \let\ifconditional \ifcase - -%D \macros -%D {ifzeropt} -%D -%D The next macro is both cosmetic and byte saving. It is -%D pretty \type{\if}||safe too. It can be used in cases -%D like: -%D -%D \starttyping -%D \ifzeropt \somedimen ... \else ... \fi -%D \stoptyping - -\let\ifzeropt\ifcase - -%D \macros %D {dorecurse,recurselevel,recursedepth, %D dostepwiserecurse, %D for} @@ -3567,10 +3331,10 @@ \def\@@irecurse{@@ir@@} % ecurse} % stepper \def\@@arecurse{@@ar@@} % ecurse} % action -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname{#4}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \ifnum#3>0\relax \ifnum#2<#1\relax \let\nextrecurse\exitstepwiserecurse @@ -3589,13 +3353,13 @@ \fi \fi\normalexpanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} -\long\def\dodostepwiserecurse#1#2#3% from to step +\def\dodostepwiserecurse#1#2#3% from to step {\ifnum#1>#2\relax - \@EA\nodostepwiserecurse + \expandafter\nodostepwiserecurse \else \def\recurselevel{#1}% - \@EAEAEA\redostepwiserecurse\@EA - \fi\@EA{\the\numexpr\recurselevel+#3\relax}{#2}{#3}} + \doubleexpandafter\redostepwiserecurse\expandafter + \fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}} \unexpanded\def\expandrecursecontent {\csname\@@arecurse\recursedepth\endcsname} @@ -3603,15 +3367,15 @@ \unexpanded\def\redostepwiserecurse {\expandrecursecontent\dodostepwiserecurse} -\long\unexpanded\def\dodostepwisereverse#1#2#3% from to step +\unexpanded\def\dodostepwisereverse#1#2#3% from to step {\ifnum#1<#2\relax - \@EA\nodostepwiserecurse + \expandafter\nodostepwiserecurse \else \def\recurselevel{#1}% \innerrecurse#1\relax \advance\innerrecurse#3\relax - \@EAEAEA\redostepwisereverse\@EA - \fi\@EA{\the\innerrecurse}{#2}{#3}} + \doubleexpandafter\redostepwisereverse\expandafter + \fi\expandafter{\the\innerrecurse}{#2}{#3}} \unexpanded\def\redostepwisereverse {\expandrecursecontent\dodostepwisereverse} @@ -3620,16 +3384,21 @@ {\nodostepwiserecurse\relax} \unexpanded\def\nodostepwiserecurse#1#2#3#4% - {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + {\expandafter\let\expandafter\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} \unexpanded\def\nonostepwiserecurse#1#2#3% - {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + {\expandafter\let\expandafter\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} \unexpanded\def\dorecurse#1% {\dostepwiserecurse1{#1}1} +\def\doexpandedrecurse#1#2% + {\ifnum#1>\zerocount + #2\expandafter\doexpandedrecurse\expandafter{\the\numexpr#1-1\relax}{#2}% + \fi} + %D As we can see here, the simple command \type{\dorecurse} is %D a special case of the more general: %D @@ -3649,7 +3418,7 @@ %D Because the simple case is used often, we implement it %D more efficiently: -\long\unexpanded\def\dorecurse#1% +\unexpanded\def\dorecurse#1% {\ifcase#1\relax \expandafter\gobbletwoarguments \or @@ -3658,42 +3427,42 @@ \expandafter\xdorecurse \fi{#1}} -\long\unexpanded\def\xdorecurse#1#2% +\unexpanded\def\xdorecurse#1#2% {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#2}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \@EA\dodorecurse\@EA1\@EA{\number#1}} + \expandafter\gdef\csname\@@arecurse\recursedepth\endcsname{#2}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \expandafter\dodorecurse\expandafter1\expandafter{\number#1}} -\long\unexpanded\def\ydorecurse#1#2% +\unexpanded\def\ydorecurse#1#2% {\global\advance\outerrecurse \plusone - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\recurselevel\!!plusone #2% - \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \expandafter\let\expandafter\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} -\long\unexpanded\def\dodorecurse#1#2% from to +\unexpanded\def\dodorecurse#1#2% from to {\ifnum#1>#2\relax - \@EA\nodorecurse + \expandafter\nodorecurse \else \def\recurselevel{#1}% - \@EAEAEA\redorecurse - \fi\@EA{\the\numexpr\recurselevel+\plusone\relax}{#2}} + \doubleexpandafter\redorecurse + \fi\expandafter{\the\numexpr\recurselevel+\plusone\relax}{#2}} -\long\unexpanded\def\dodorecurse#1#2% from to +\unexpanded\def\dodorecurse#1#2% from to {\ifnum#1>#2\relax - \@EA\nodorecurse + \expandafter\nodorecurse \else \def\recurselevel{#1}% \innerrecurse#1\advance\innerrecurse\plusone - \@EAEAEA\redorecurse - \fi\@EA{\the\innerrecurse}{#2}} + \doubleexpandafter\redorecurse + \fi\expandafter{\the\innerrecurse}{#2}} \unexpanded\def\redorecurse {\expandrecursecontent\dodorecurse} \unexpanded\def\nodorecurse#1#2#3% - {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + {\expandafter\let\expandafter\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone } %D \macros @@ -3716,29 +3485,29 @@ \let\endofloop\donothing -\unexpanded\long\def\doloop#1% +\unexpanded\def\doloop#1% {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#1}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\@@arecurse\recursedepth\endcsname{#1}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\endofloop\dodoloop \dodoloop1} % no \plusone else \recurselevel wrong -\unexpanded\long\def\dodoloop#1% +\unexpanded\def\dodoloop#1% {\def\recurselevel{#1}% - \@EA\redoloop\@EA{\the\numexpr\recurselevel+\plusone\relax}} + \expandafter\redoloop\expandafter{\the\numexpr\recurselevel+\plusone\relax}} \unexpanded\def\redoloop {\expandrecursecontent\endofloop} \unexpanded\def\nodoloop#1% {\let\endofloop\dodoloop % new, permits nested \doloop's - \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \expandafter\let\expandafter\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse\minusone} \unexpanded\def\exitloop % \exitloop quits at end {\let\endofloop\nodoloop} -\long\unexpanded\def\exitloopnow#1\endofloop % \exitloopnow quits directly +\unexpanded\def\exitloopnow#1\endofloop % \exitloopnow quits directly {\nodoloop} %D The loop is executed at least once, so beware of situations @@ -3780,27 +3549,28 @@ %D \stoptyping \def\expandrecursecontent - {\csname\@@arecurse\recursedepth\@EA\@EA\@EA\endcsname\@EA\@EA\@EA{\@EA\recurselevel\@EA}\@EA{\recursedepth}} + {\csname\@@arecurse\recursedepth\expandafter\expandafter\expandafter\endcsname + \expandafter\expandafter\expandafter{\expandafter\recurselevel\expandafter}\expandafter{\recursedepth}} -\long\unexpanded\def\xdorecurse#1#2% +\unexpanded\def\xdorecurse#1#2% {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \@EA\dodorecurse\@EA1\@EA{\number#1}} + \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \expandafter\dodorecurse\expandafter1\expandafter{\number#1}} -\long\unexpanded\def\ydorecurse#1#2% +\unexpanded\def\ydorecurse#1#2% {\global\advance\outerrecurse \plusone - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\recurselevel\!!plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% + \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% \expandrecursecontent - \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \expandafter\let\expandafter\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} -\long\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \ifnum#3>0\relax \ifnum#2<#1\relax \let\nextrecurse\exitstepwiserecurse @@ -3819,46 +3589,19 @@ \fi \fi\normalexpanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} -\long\unexpanded\def\doloop#1% +\unexpanded\def\doloop#1% {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\endofloop\dodoloop \dodoloop1} % no \plusone else \recurselevel wrong -% EXPERIMENT - % faster -\long\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel - \ifnum#3>\zerocount - \ifnum#2<#1\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwiserecurse - \fi - \else - \ifnum#3<\zerocount - \ifnum#1<#2\relax - \let\nextrecurse\exitstepwiserecurse - \else - \let\nextrecurse\dodostepwisereverse - \fi - \else - \let\nextrecurse\exitstepwiserecurse - \fi - \fi - \normalexpanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} - -% slightly faster - -\long\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 - {\global\advance\outerrecurse \plusone - \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% - \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% + \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \csname @swr% \ifnum#3>\zerocount \ifnum#2<#1\else d\fi @@ -3873,10 +3616,10 @@ % quite okay too, but untested % -% \long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +% \def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 % {\global\advance\outerrecurse \plusone -% \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% -% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel +% \global\expandafter\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% +% \global\expandafter\let\csname\@@irecurse\recursedepth\endcsname\recurselevel % \normalexpanded % {\ifnum#3>\zerocount % \ifnum#2<#1 @@ -3898,56 +3641,63 @@ %D For special purposes: -\newcount\fastrecursecounter -\newcount\lastrecursecounter -\newcount\steprecursecounter +\newcount\fastloopindex +\newcount\fastloopfinal +\let\fastloopcs\relax -\unexpanded\def\dofastrecurse#1#2#3#4% - {\def\fastrecursebody{#4}% - \fastrecursecounter#1\relax - \lastrecursecounter#2\relax - \steprecursecounter#3\relax - \def\recurselevel{\number\fastrecursecounter}% - \dodofastrecurse} +\unexpanded\def\dofastloopcs#1#2% + {\let\fastloopcs#2 + \fastloopindex\plusone + \fastloopfinal#1\relax + \dodofastloopcs} -\unexpanded\def\resetrecurselevel{\let\recurselevel\!!zerocount} - -\unexpanded\def\dodofastrecurse - {\ifnum\fastrecursecounter>\lastrecursecounter - % \resetrecurselevel % slows down +\unexpanded\def\dodofastloopcs + {\ifnum\fastloopindex>\fastloopfinal + \let\fastloopcs\relax \else - \fastrecursebody - \advance\fastrecursecounter\steprecursecounter - \expandafter\dodofastrecurse + \fastloopcs + \advance\fastloopindex\plusone + \expandafter\dodofastloopcs \fi} -% \appendtoks \resetrecurselevel \to \everydump +% Helper: -\everydump\expandafter{\the\everydump\resetrecurselevel} +\unexpanded\def\resetrecurselevel{\let\recurselevel\!!zerocount} + +\let\recurselevel\!!zerocount -%D This alternative looks a bit different and uses a -%D pseudo counter. When this macro is nested, we have to use -%D different counters. This time we use keywords. +% \appendtoks \resetrecurselevel \to \everydump + +%D \macros +%D {doloopoverlist} %D %D \starttyping -%D \def\alfa{2} \def\beta{100} \def\gamma{3} -%D -%D \for \n=55 \to 100 \step 1 \do {... \n ...} -%D \for \n=\alfa \to \beta \step \gamma \do {... \n ...} -%D \for \n=\n \to 120 \step 1 \do {... \n ...} -%D \for \n=120 \to 100 \step -3 \do {... \n ...} -%D \for \n=55 \to 100 \step 2 \do {... \n ...} +%D \doloopoverlist {red,green,blue} { +%D \setuppalet[\recursestring] +%D \doloopoverlist {light,normal,dark} { +%D \blackrule[color=\recursestring,width=20cm,height=2cm,depth=0cm]\par +%D } +%D } %D \stoptyping %D -%D Only in the third example we need to predefine \type{\n}. -%D The use of \type{\od} as a dilimiter would have made nested -%D use more problematic. +%D or: +%D +%D \starttyping +%D \doloopoverlist {red,green,blue} { +%D \setuppalet[#1] +%D \doloopoverlist {light,normal,dark} { +%D \blackrule[color=##1,width=20cm,height=2cm,depth=0cm]\par +%D } +%D } +%D \stoptyping -% obsolete: -% -% \def\for#1=#2\to#3\step#4\do#5% -% {\dostepwiserecurse{#2}{#3}{#4} -% {\let#1\recurselevel#5\let#1\recurselevel}} +\unexpanded\def\doloopoverlist#1#2% + {\global\advance\outerrecurse\plusone + \expandafter\gdef\csname\@@arecurse\recursedepth\endcsname##1{\edef\recursestring{##1}#2}% + \expandafter\glet\csname\@@irecurse\recursedepth\endcsname\recursestring + \normalexpanded{\processcommalist[#1]{\expandafter\noexpand\csname\@@arecurse\recursedepth\endcsname}}% + \expandafter\let\expandafter\recursestring\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse\minusone} %D \macros %D {newevery,everyline,EveryLine,EveryPar} @@ -4071,7 +3821,7 @@ {\expandafter\convertcommand\csname#1\endcsname\to} \def\defconvertedvalue#1#2% less sensitive for \to - {\@EA\defconvertedcommand\@EA#1\csname#2\endcsname} + {\expandafter\defconvertedcommand\expandafter#1\csname#2\endcsname} %D \macros %D {doifassignmentelse} @@ -4093,15 +3843,22 @@ %D \doifassignmentelse {...} {then ...} {else ...} %D \stoptyping -\long\def\docheckifassignmentelse#1=#2#3\@end@{\if#2@}% +\def\docheckifassignmentelse#1=#2#3\@end@{\if#2@}% -\long\def\doifassignmentelse#1% +\def\doifassignmentelse#1% expandable {\expandafter\docheckifassignmentelse\detokenize{#1}=@@\@end@ \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} +\newif\ifassignment + +% \def\docheckassignmentindeed#1=#2#3\@end@{\if#2@\assignmentfalse\else\assignmenttrue\fi} +% +% \def\docheckassignment#1% +% {\expandafter\docheckassignmentindeed\detokenize{#1}=@@\@end@} + % D \macros % D {convertasciiafter} % D @@ -4113,7 +3870,7 @@ % D \stoptyping % % \def\convertasciiafter#1#2% -% {\@EA#1\@EA{\detokenize{#2}}} +% {\expandafter#1\expandafter{\detokenize{#2}}} %D In \ETEX\ we can use \type {\detokenize} and gain some %D speed, but in general far less that 1\% for \type @@ -4122,17 +3879,17 @@ %D something I found out when primitives like \type %D {\jobname} were fed (or something undefined). -\long\def\convertargument#1\to#2{\dodoglobal\edef#2{\detokenize{#1}}} -\long\def\convertcommand #1\to#2{\dodoglobal\edef#2{\@EA\detokenize\@EA{#1}}} % hm, only second is also ok +\def\convertargument#1\to#2{\dodoglobal\edef#2{\detokenize{#1}}} +\def\convertcommand #1\to#2{\dodoglobal\edef#2{\expandafter\detokenize\expandafter{#1}}} % hm, only second is also ok -\long\def\defconvertedargument #1#2{\edef#1{\detokenize {#2}}} -\long\def\defconvertedcommand #1#2{\edef#1{\detokenize\@EA{#2}}} -\long\def\edefconvertedargument#1#2{\edef#1{#2}% - \edef#1{\detokenize\@EA{#1}}} -\long\def\gdefconvertedargument#1#2{\xdef#1{\detokenize {#2}}} -\long\def\gdefconvertedcommand #1#2{\xdef#1{\detokenize\@EA{#2}}} -\long\def\xdefconvertedargument#1#2{\xdef#1{#2}% - \xdef#1{\detokenize\@EA{#1}}} +\def\defconvertedargument #1#2{\edef#1{\detokenize{#2}}} +\def\defconvertedcommand #1#2{\edef#1{\detokenize\expandafter{#2}}} +\def\edefconvertedargument#1#2{\edef#1{#2}% + \edef#1{\detokenize\expandafter{#1}}} +\def\gdefconvertedargument#1#2{\xdef#1{\detokenize{#2}}} +\def\gdefconvertedcommand #1#2{\xdef#1{\detokenize\expandafter{#2}}} +\def\xdefconvertedargument#1#2{\xdef#1{#2}% + \xdef#1{\detokenize\expandafter{#1}}} %D When you try to convert a primitive command, you'll find %D out that the \ETEX\ method fails on for instance \type @@ -4238,7 +3995,7 @@ %D In examples~2 and~3 both arguments equal, in~1 and~4 %D they differ. -\long\def\ConvertToConstant#1#2#3% +\def\ConvertToConstant#1#2#3% {\edef\!!stringa{\expandafter\detokenize\expandafter{#2}}% \edef\!!stringb{\expandafter\detokenize\expandafter{#3}}% #1{\!!stringa}{\!!stringb}} @@ -4271,7 +4028,7 @@ %D where \type{...} can be anything legally \TEX. \def\CheckConstantAfter#1#2% - {\@EA\convertargument\v!prefix!\to\ascii + {\expandafter\convertargument\v!prefix!\to\ascii \convertargument#1\to#2\relax \doifinstringelse\ascii{#2} {\expandafter\convertargument#1\to#2} @@ -4338,7 +4095,7 @@ %D results in: \type{\message{Hello world!}}. \def\dograbuntil#1#2% - {\long\def\next##1#1{#2{##1}}\next} + {\def\next##1#1{#2{##1}}\next} \def\grabuntil#1% {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}} @@ -4365,11 +4122,11 @@ %D is related to these commands. This one simply throws away %D everything preceding \type{\command}. -\long\def\processbetween#1#2% +\def\processbetween#1#2% {\setvalue{\s!start#1}{\grabuntil{\s!stop#1}{#2}}} \def\gobbleuntil#1% - {\long\def\next##1#1{}\next} + {\def\next##1#1{}\next} \def\gobbleuntilrelax#1\relax {} @@ -4381,7 +4138,7 @@ %D \stoptyping \def\processuntil#1% - {\long\def\next##1#1{##1}\next} + {\def\next##1#1{##1}\next} %D \macros %D {groupedcommand} @@ -4451,38 +4208,38 @@ %D extra \type{\bgroup}||\type{\egroup} is needed to keep %D \type{\AfterGroup} both into sight and local. -\long\def\HandleGroup#1#2% +\def\HandleGroup#1#2% {\bgroup - \long\def\BeforeGroup{\bgroup#1\bgroup\aftergroup\AfterGroup}% - \long\def\AfterGroup {#2\egroup\egroup}% + \def\BeforeGroup{\bgroup#1\bgroup\aftergroup\AfterGroup}% can't we remove the second \bgroup + \def\AfterGroup {#2\egroup\egroup}% % and one \egroup here? \afterassignment\BeforeGroup \let\next=} -\long\def\HandleSimpleGroup#1#2% no inner group (so no kerning interference) +\def\HandleSimpleGroup#1#2% no inner group (so no kerning interference) {\bgroup - %long\def\BeforeGroup{\bgroup#1\aftergroup\AfterGroup}% interferes - \long\def\BeforeGroup{\bgroup\aftergroup\AfterGroup#1}% - \long\def\AfterGroup {#2\egroup}% + %def\BeforeGroup{\bgroup#1\aftergroup\AfterGroup}% interferes + \def\BeforeGroup{\bgroup\aftergroup\AfterGroup#1}% + \def\AfterGroup {#2\egroup}% \afterassignment\BeforeGroup \let\next=} -% \long\def\HandleNoGroup#1#2% -% {\long\def\AfterGroup{#2\egroup}% +% \def\HandleNoGroup#1#2% +% {\def\AfterGroup{#2\egroup}% % \bgroup\aftergroup\AfterGroup#1} \def\HandleNoGroup % retrofit into mkii - {\ifnum\currentgrouptype=\@@semisimplegroup + {\ifnum\currentgrouptype=\semisimplegroupcode \expandafter\HandleNoGroupA \else \expandafter\HandleNoGroupB \fi} -\long\def\HandleNoGroupA#1#2% - {\long\def\AfterGroup{#2\endgroup}% +\def\HandleNoGroupA#1#2% + {\def\AfterGroup{#2\endgroup}% \begingroup\aftergroup\AfterGroup#1} -\long\def\HandleNoGroupB#1#2% - {\long\def\AfterGroup{#2\egroup}% +\def\HandleNoGroupB#1#2% + {\def\AfterGroup{#2\egroup}% \bgroup\aftergroup\AfterGroup#1} %D I considered it a nuisance that @@ -4497,10 +4254,10 @@ %D line||ending token is treated as a blank space. So the final %D implementation became: -\long\unexpanded\def\groupedcommand#1#2% +\unexpanded\def\groupedcommand#1#2% {\doifnextbgroupelse{\HandleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}} -\long\unexpanded\def\simplegroupedcommand#1#2% +\unexpanded\def\simplegroupedcommand#1#2% {\doifnextbgroupelse{\HandleSimpleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}} %D Users should be aware of the fact that grouping can @@ -4608,7 +4365,7 @@ {\def\dodogotopar{#1}% \redogotopar\par} -\def\GetPar +\unexpanded\def\GetPar {\expanded {\dowithpar {\the\BeforePar @@ -4617,7 +4374,7 @@ \BeforePar\emptytoks \AfterPar\emptytoks}}} -\def\GotoPar +\unexpanded\def\GotoPar {\expanded {\dogotopar {\the\BeforePar @@ -4656,7 +4413,7 @@ %D ... \par %D \stoptyping -\def\dowithpargument#1% +\unexpanded\def\dowithpargument#1% {\def\nextpar##1 \par{#1{##1}}% \def\nextarg##1{#1{##1}}% \doifnextbgroupelse\nextarg{\doifnextcharelse\par{#1{}}\nextpar}} @@ -4683,7 +4440,7 @@ %D ... %D \stoptyping -\def\dowithwargument#1% +\unexpanded\def\dowithwargument#1% {\def\nextwar##1 {#1{##1}}% \def\nextarg##1{#1{##1}}% \doifnextbgroupelse\nextarg\nextwar} @@ -4718,17 +4475,18 @@ %D a row. In both commands, the \type{n*} is optional. When this %D specification is missing, the command executes once. -\def\dorepeatwithcommand[#1]% +\unexpanded\def\dorepeatwithcommand[#1]% {\dodorepeatwithcommand#1*\empty*\relax} -\long\def\dodorepeatwithcommand#1*#2#3*#4\relax#5% +\def\dodorepeatwithcommand#1*#2#3*#4\relax#5% {\ifx#2\empty\redorepeatwithcommand[#1]#5\else\dododorepeatwithcommand{#1}{#2}{#3}#5\fi} -\long\def\dododorepeatwithcommand#1#2#3#4% +\def\dododorepeatwithcommand#1#2#3#4% {\ifx#2\empty % redundant but gives cleaner extensions #4{#1}% \else\ifnum#1<\zerocount - \normalexpanded{\dorecurse{\number-\number#1}}{#4{-#2#3}}% + %\normalexpanded{\dorecurse{\number-\number#1}}{#4{-#2#3}}% + \dorecurse{-#1}{#4{-#2#3}}% \else\ifx#2+% \dorecurse{#1}{#4{#3}}% \else @@ -4748,7 +4506,7 @@ %D \gdef\redorepeatwithcommand[#1]% %D {\redodorepeatwithcommand#1*\empty*\relax} %D -%D \long\gdef\redodorepeatwithcommand#1*#2#3*#4\relax#5% +%D \gdef\redodorepeatwithcommand#1*#2#3*#4\relax#5% %D {\dododorepeatwithcommand{#1}{#2}{#3}#5} %D %D \egroup @@ -4771,11 +4529,11 @@ %D are macros. This save some unneeded expansion. %D %D \starttyping -%D \long\def\doifstringinstringelse#1#2% -%D {\p!doifinstringelse#1#2% -%D \@EA\firstoftwoarguments +%D \def\doifstringinstringelse#1#2% +%D {\syst_helpers_do_if_in_string_else#1#2% +%D \expandafter\firstoftwoarguments %D \else -%D \@EA\secondoftwoarguments +%D \expandafter\secondoftwoarguments %D \fi} %D \stoptyping %D @@ -4783,15 +4541,15 @@ \def\pp!doifstringinstringelse#1% {\if#1@% - \@EA\secondoftwoarguments + \expandafter\secondoftwoarguments \else - \@EA\firstoftwoarguments + \expandafter\firstoftwoarguments \fi} -\long\def\doifstringinstringelse#1#2% - {\long\@EA\def\@EA\p!doifstringinstringelse\@EA##\@EA1#1##2##3\war +\def\doifstringinstringelse#1#2% + {\expandafter\def\expandafter\p!doifstringinstringelse\expandafter##\expandafter1#1##2##3\war {\pp!doifstringinstringelse##2}% - \@EA\@EA\@EA\p!doifstringinstringelse\@EA#2#1@@\war} + \expandafter\expandafter\expandafter\p!doifstringinstringelse\expandafter#2#1@@\war} %D \macros %D {appendtoks,prependtoks,appendtoksonce,prependtoksonce, @@ -4808,44 +4566,43 @@ %D \dotoks\tokenlist %D \stoptyping %D -%D Er worden eerst enkele klad||registers gedefinieerd. These -%D macros are clones of the ones implemented in page~378 of +%D These macros are clones of the ones implemented in page~378 of %D Knuth's \TeX book. \newtoks\@@scratchtoks -\def\appendtoks {\doappendtoks \relax} -\def\prependtoks {\doprependtoks \relax} -\def\appendtoksonce {\doappendtoksonce \relax} -\def\prependtoksonce{\doprependtoksonce\relax} +\unexpanded\def\appendtoks {\doappendtoks \relax} +\unexpanded\def\prependtoks {\doprependtoks \relax} +\unexpanded\def\appendtoksonce {\doappendtoksonce \relax} +\unexpanded\def\prependtoksonce{\doprependtoksonce\relax} \def\dodoappendtoks - {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@toks\the\@@scratchtoks}} + {\dodoglobal\@@toks\doubleexpandafter{\expandafter\the\expandafter\@@toks\the\@@scratchtoks}} \def\dodoprependtoks - {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@scratchtoks\the\@@toks}} + {\dodoglobal\@@toks\doubleexpandafter{\expandafter\the\expandafter\@@scratchtoks\the\@@toks}} -\long\def\doappendtoks#1\to#2% +\def\doappendtoks#1\to#2% {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoappendtoks} + \@@scratchtoks\expandafter{\gobbleoneargument#1}\dodoappendtoks} -\long\def\doprependtoks#1\to#2% +\def\doprependtoks#1\to#2% {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoprependtoks} + \@@scratchtoks\expandafter{\gobbleoneargument#1}\dodoprependtoks} -\long\def\doappendtoksonce#1\to#2% +\def\doappendtoksonce#1\to#2% {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}% + \@@scratchtoks\expandafter{\gobbleoneargument#1}% \doifintokselse\@@scratchtoks\@@toks\donothing\dodoappendtoks} -\long\def\doprependtoksonce#1\to#2% +\def\doprependtoksonce#1\to#2% {\def\@@toks{#2}% - \@@scratchtoks\@EA{\gobbleoneargument#1}% + \@@scratchtoks\expandafter{\gobbleoneargument#1}% \doifintokselse\@@scratchtoks\@@toks\donothing\dodoprependtoks} %D The test macro: -\def\doifintokselse#1#2% #1 en #2 zijn toks +\unexpanded\def\doifintokselse#1#2% #1 en #2 zijn toks {\edef\asciia{\detokenize\expandafter{\the#1}}% \edef\asciib{\detokenize\expandafter{\the#2}}% \doifstringinstringelse\asciia\asciib} @@ -4858,7 +4615,7 @@ % {\scratchtoks{xaa} \removetoks x\from\scratchtoks [\the\scratchtoks]} % {\scratchtoks{a\relax b} \removetoks \relax\from\scratchtoks [\showthe\scratchtoks]} -\def\removetoks#1\from#2% +\unexpanded\def\removetoks#1\from#2% {\def\doremovetoks##1#1##2\empty\empty\empty##3\\% {\def\!!stringa{##3}% \ifx\!!stringa\empty#2{##1}\else#2{##1##2}\fi}% @@ -4866,8 +4623,8 @@ %D Also: -\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to} -\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to} +\unexpanded\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to} +\unexpanded\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to} %D Hm. @@ -4880,45 +4637,48 @@ \let\dotoks\the -%D \macros -%D {makecounter,pluscounter,minuscounter, -%D resetcounter,setcounter,countervalue} -%D -%D Declaring, setting and resetting \COUNTERS\ can be done -%D with the next set of commands. -%D -%D \starttyping -%D \makecounter {name} -%D \pluscounter {name} -%D \minuscounter {name} -%D \resetcounter {name} -%D \setcounter {name} {value} -%D \countervalue {name} -%D \stoptyping - -\def\makecounter#1% - {\global\@EA\let\csname#1\endcsname\zerocountervalue} % see earlier - -\def\countervalue#1% - {\ifcsname#1\endcsname\csname#1\endcsname\fi} - -\def\pluscounter#1% - {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname+\plusone\relax}} - -\def\minuscounter#1% - {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname-\plusone\relax}} - -\def\resetcounter#1% - {\global\@EA\let\csname#1\endcsname\zerocountervalue} - -\def\setcounter#1#2% - {\@EA\xdef\csname#1\endcsname{\the\numexpr#2\relax}} - -\def\savecounter#1% - {\@EA\xdef\csname ! #1 !\endcsname{\the\numexpr\csname#1\endcsname\relax}} - -\def\restorecounter#1% - {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname ! #1 !\endcsname\relax}} +% The following code is obsolete (and names are reused for the more +% advanced counter mechanism and those macros are not compatible! +% +% %D \macros +% %D {makecounter,pluscounter,minuscounter, +% %D resetcounter,setcounter,countervalue} +% %D +% %D Declaring, setting and resetting \COUNTERS\ can be done +% %D with the next set of commands. +% %D +% %D \starttyping +% %D \makecounter {name} +% %D \pluscounter {name} +% %D \minuscounter {name} +% %D \resetcounter {name} +% %D \setcounter {name} {value} +% %D \countervalue {name} +% %D \stoptyping +% +% \def\makecounter#1% +% {\global\expandafter\let\csname#1\endcsname\zerocountervalue} % see earlier +% +% \def\countervalue#1% +% {\ifcsname#1\endcsname\csname#1\endcsname\fi} +% +% \def\pluscounter#1% +% {\expandafter\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname+\plusone\relax}} +% +% \def\minuscounter#1% +% {\expandafter\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname-\plusone\relax}} +% +% \def\resetcounter#1% +% {\global\expandafter\let\csname#1\endcsname\zerocountervalue} +% +% \def\setcounter#1#2% +% {\expandafter\xdef\csname#1\endcsname{\the\numexpr#2\relax}} +% +% \def\savecounter#1% +% {\expandafter\xdef\csname ! #1 !\endcsname{\the\numexpr\csname#1\endcsname\relax}} +% +% \def\restorecounter#1% +% {\expandafter\xdef\csname#1\endcsname{\the\numexpr\csname ! #1 !\endcsname\relax}} %D \macros %D {beforesplitstring,aftersplitstring} @@ -4940,12 +4700,12 @@ \def\beforesplitstring#1\at#2\to#3% {\def\dosplitstring##1#2##2#2##3\\% {\def#3{##1}}% - \@EA\dosplitstring#1#2#2\\} + \expandafter\dosplitstring#1#2#2\\} \def\aftersplitstring#1\at#2\to#3% {\def\dosplitstring##1#2##2@@@##3\\% {\def#3{##2}}% - \@EA\dosplitstring#1@@@#2@@@\\} + \expandafter\dosplitstring#1@@@#2@@@\\} %D \macros %D {splitstring,greedysplitstring} @@ -4961,7 +4721,7 @@ \else \def#4{##2}% \fi}% - \@EA\dosplitstring#1\empty\empty\empty#2\empty\empty\empty\\} + \expandafter\dosplitstring#1\empty\empty\empty#2\empty\empty\empty\\} \def\greedysplitstring#1\at#2\to#3\and#4% {\edef\asciib{#1}% @@ -4988,17 +4748,17 @@ \def\beforetestandsplitstring#1\at#2\to#3% {\def\dosplitstring##1#2##2#2##3##4\\% {\ifx##3\empty\let#3\empty\else\def#3{##1}\fi}% - \@EA\dosplitstring#1#2#2\empty\\} + \expandafter\dosplitstring#1#2#2\empty\\} \def\aftertestandsplitstring#1\at#2\to#3% {\def\dosplitstring ##1#2##2@@@##3##4\\% {\ifx##3\empty\let#3\empty\else\def#3{##2}\fi}% - \@EA\dosplitstring #1@@@#2@@@\empty\\} + \expandafter\dosplitstring #1@@@#2@@@\empty\\} \def\testandsplitstring#1\at#2\to#3\and#4% {\def\dosplitstring##1#2##2#2##3##4\\% {\ifx##3\empty\let#3\empty\let#4\empty\else\def#3{##1}\def#4{##2}\fi}% - \@EA\dosplitstring#1#2#2\empty\\} + \expandafter\dosplitstring#1#2#2\empty\\} %D \macros %D {removesubstring} @@ -5073,30 +4833,30 @@ %D %D The faster alternatives are: -\def\appendtocommalist#1#2% +\unexpanded\def\appendtocommalist#1#2% {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}} -\def\prependtocommalist#1#2% +\unexpanded\def\prependtocommalist#1#2% {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}} -\def\addtocommalist#1#2% {item} \cs +\unexpanded\def\addtocommalist#1#2% {item} \cs {\rawdoifinsetelse{#1}#2\resetglobal {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}} -\def\pretocommalist#1#2% {item} \cs +\unexpanded\def\pretocommalist#1#2% {item} \cs {\rawdoifinsetelse{#1}#2\resetglobal {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}} -\def\robustdoifinsetelse#1#2% +\unexpanded\def\robustdoifinsetelse#1#2% {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#1}}}% \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#2}}}% \rawdoifinsetelse\!!stringa\!!stringb} -\def\robustaddtocommalist#1#2% {item} \cs +\unexpanded\def\robustaddtocommalist#1#2% {item} \cs {\robustdoifinsetelse{#1}#2\resetglobal {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}} -\def\robustpretocommalist#1#2% {item} \cs +\unexpanded\def\robustpretocommalist#1#2% {item} \cs {\robustdoifinsetelse{#1}#2\resetglobal {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}} @@ -5104,13 +4864,13 @@ {\def\dosplitstring##1,#2,##2,#2,##3\\% {\edef\!!stringa{\bcleanedupcommalist##1\empty\empty\relax}% \edef\!!stringb{\acleanedupcommalist##2,,\relax}}% - \@EA\dosplitstring\@EA,#1,,#2,,#2,\\} + \expandafter\dosplitstring\expandafter,#1,,#2,,#2,\\} \def\bcleanedupcommalist#1#2#3\relax{\if#1,\else#1\fi\if#2,\else#2\fi#3} \def\bcleanedupcommalist#1#2\relax{\if#1,\else#1\fi#2} \def\acleanedupcommalist#1,,#2\relax{#1} -\def\removefromcommalist#1#2% to be sped up +\unexpanded\def\removefromcommalist#1#2% to be sped up {\rawdoifinsetelse{#1}#2% {\normalexpanded{\noexpand\xsplitstring\noexpand#2{#1}}% \dodoglobal\edef#2% @@ -5121,6 +4881,12 @@ \fi}} \resetglobal} +% \unexpanded\def\addtocommalist#1#2% upto 3 times slower +% {\dodoglobal\edef#2{\ctxcommand{addtocommalist(\!!bs#1\!!es,\!!bs#2\!!es)}}} +% +% \unexpanded\def\removefromcommalist#1#2% faster and more robust +% {\dodoglobal\edef#2{\ctxcommand{addtocommalist(\!!bs#1\!!es,\!!bs#2\!!es)}}} + %D \macros %D {substituteincommalist} %D @@ -5146,7 +4912,7 @@ \else \edef#3{#3\ifx#3\empty\else,\fi##1}% \fi}% - \@EA\rawprocesscommacommand\@EA[\!!stringa]\dosubstituteincommalist} + \expandafter\rawprocesscommacommand\expandafter[\!!stringa]\dosubstituteincommalist} %D A not so useful macro: @@ -5160,7 +4926,7 @@ \def\dofrontstrip#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \else - \@EA\dodofrontstrip\@EA[#1]#1% + \expandafter\dodofrontstrip\expandafter[#1]#1% \fi} %D \macros @@ -5194,8 +4960,9 @@ \ifx\newcommalist\empty \let\newcommalist\newcommalistelement \else - \@EA\@EA\@EA\def\@EA\@EA\@EA\newcommalist\@EA\@EA\@EA - {\@EA\newcommalist\@EA,\newcommalistelement}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter + \newcommalist\expandafter\expandafter\expandafter + {\expandafter\newcommalist\expandafter,\newcommalistelement}% \fi \fi \def\commalistelement{##1}% @@ -5208,9 +4975,9 @@ \fi \else \ifx\nexttoken\bgroup % is known -) - \@EA\def\@EA\newcommalist\@EA{\newcommalist,{##1}}% + \expandafter\def\expandafter\newcommalist\expandafter{\newcommalist,{##1}}% \else - \@EA\def\@EA\newcommalist\@EA{\newcommalist,##1}% + \expandafter\def\expandafter\newcommalist\expandafter{\newcommalist,##1}% \fi \fi \fi @@ -5218,7 +4985,7 @@ \let\commalistelement\empty \let\newcommalist\empty \commalistcounter\plusone - \@EA\processcommalist\@EA[#1]\doreplaceincommalist + \expandafter\processcommalist\expandafter[#1]\doreplaceincommalist \dodoglobal\let#1\newcommalist} %D \macros @@ -5285,16 +5052,23 @@ \def\numberofpoints #1{\the\numexpr\dimexpr#1\relax/\maxcard\relax} %D \macros -%D {swapdimens,swapcounts,swapmacros} +%D {swapdimens,swapcounts,swapmacros, +%D globalswapdimens,globalswapcounts,globalswapmacros} %D %D Simple but effective are the next two macros. There name -%D exactly states their purpose. The \type{\scratchdimen} and -%D \type{\!!stringa} can only be swapped when being the first -%D argument. +%D exactly states their purpose. + +\newdimen\d_syst_helpers_swapped +\newcount\c_syst_helpers_swapped +\let \m_syst_helpers_swapped\relax -\def\swapdimens#1#2{\scratchdimen #1\redoglobal #1#2\dodoglobal #2\scratchdimen} -\def\swapcounts#1#2{\scratchcounter#1\redoglobal #1#2\dodoglobal #2\scratchcounter} -\def\swapmacros#1#2{\let\!!stringa #1\redoglobal\let#1#2\dodoglobal\let#2\!!stringa} +\unexpanded\def\swapdimens#1#2{\d_syst_helpers_swapped #1\relax#1#2\relax#2\d_syst_helpers_swapped} +\unexpanded\def\swapcounts#1#2{\c_syst_helpers_swapped #1\relax#1#2\relax#2\c_syst_helpers_swapped} +\unexpanded\def\swapmacros#1#2{\let\m_syst_helpers_swapped#1\let #1#2\let #2\m_syst_helpers_swapped} + +\unexpanded\def\globalswapdimens#1#2{\d_syst_helpers_swapped #1\global #1#2\global #2\d_syst_helpers_swapped} +\unexpanded\def\globalswapcounts#1#2{\c_syst_helpers_swapped #1\global #1#2\global #2\c_syst_helpers_swapped} +\unexpanded\def\globalswapmacros#1#2{\let\m_syst_helpers_swapped#1\global\let#1#2\global\let#2\m_syst_helpers_swapped} %D \macros %D {pushmacro,popmacro} @@ -5316,27 +5090,27 @@ \def\globalpushmacro#1% {\xdef\@@pushedmacro{\string#1}% \ifcsname\@sg@\@@pushedmacro\endcsname \else - \@EA\newcount\csname\@sg@\@@pushedmacro\endcsname + \expandafter\newcount\csname\@sg@\@@pushedmacro\endcsname \fi \global\advance\csname\@sg@\@@pushedmacro\endcsname \plusone - \global\@EA\let\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} + \global\expandafter\let\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} \def\globalpopmacro#1% {\xdef\@@pushedmacro{\string#1}% - \global\@EA\let\@EA#1\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname + \global\expandafter\let\expandafter#1\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname \global\advance\csname\@sg@\@@pushedmacro\endcsname \minusone} \def\localpushmacro#1% this one can be used to push a value over an \egroup {\xdef\@@pushedmacro{\string#1}% \ifcsname\@sl@\@@pushedmacro\endcsname \else - \@EA\newcount\csname\@sl@\@@pushedmacro\endcsname + \expandafter\newcount\csname\@sl@\@@pushedmacro\endcsname \fi \global\advance\csname\@sl@\@@pushedmacro\endcsname \plusone - \global\@EA\let\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} + \global\expandafter\let\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} \def\localpopmacro#1% {\xdef\@@pushedmacro{\string#1}% - \@EA\let\@EA#1\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname + \expandafter\let\expandafter#1\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname \global\advance\csname\@sl@\@@pushedmacro\endcsname \minusone } \let\pushmacro\localpushmacro @@ -5359,21 +5133,48 @@ %D These examples show us that an optional can be used. The %D value provided is added to \type{\localhsize}. -\newdimen\localhsize +% todo: a fast non argument variant -\def\complexsetlocalhsize[#1]% don't change ! - {\localhsize\hsize - \ifnum\hangafter<\zerocount - \advance\localhsize\ifdim\hangindent>\zeropoint-\fi\hangindent - \fi - \advance\localhsize -\leftskip - \advance\localhsize -\rightskip - \advance\localhsize #1\relax} +\newdimen\localhsize -\def\simplesetlocalhsize - {\complexsetlocalhsize[\zeropoint]} +% \def\complexsetlocalhsize[#1]% don't change ! +% {\localhsize\hsize +% \ifnum\hangafter<\zerocount +% \advance\localhsize\ifdim\hangindent>\zeropoint-\fi\hangindent +% \fi +% \advance\localhsize -\leftskip +% \advance\localhsize -\rightskip +% \advance\localhsize #1\relax} +% +% \def\simplesetlocalhsize +% {\complexsetlocalhsize[\zeropoint]} +% +% \definecomplexorsimple\setlocalhsize + +\unexpanded\def\setlocalhsize % don't change ! + {\doifnextoptionalelse + \syst_helpers_set_local_hsize_yes + \syst_helpers_set_local_hsize_nop} + +% \def\syst_helpers_set_local_hsize_nop +% {\localhsize\hsize +% \ifnum\hangafter<\zerocount +% \advance\localhsize\ifdim\hangindent>\zeropoint-\fi\hangindent +% \fi +% \advance\localhsize -\leftskip +% \advance\localhsize -\rightskip} + +\def\syst_helpers_set_local_hsize_nop + {\localhsize\dimexpr + \hsize -\leftskip -\rightskip + \ifnum\hangafter<\zerocount + \ifdim\hangindent>\zeropoint-\else+\fi\hangindent + \fi + \relax} -\definecomplexorsimple\setlocalhsize +\def\syst_helpers_set_local_hsize_yes[#1]% + {\syst_helpers_set_local_hsize_nop + \advance\localhsize#1\relax} %D \macros %D {doifvalue,doifnotvalue,doifelsevalue, @@ -5386,40 +5187,7 @@ %D tokens per call. Anyone familiar with the not||values %D ones, can derive their meaning from the definitions. - \def\doifvalue#1{\doif {\csname#1\endcsname}} - \def\doifnotvalue#1{\doifnot {\csname#1\endcsname}} - \def\doifelsevalue#1{\doifelse{\csname#1\endcsname}} - - \def\doifnothing#1{\doif {#1}{}} - \def\doifsomething#1{\doifnot {#1}{}} - \def\doifelsenothing#1{\doifelse{#1}{}} - - \def\doifvaluenothing#1{\doif {\csname#1\endcsname}{}} - \def\doifvaluesomething#1{\doifnot {\csname#1\endcsname}{}} -\def\doifelsevaluenothing#1{\doifelse{\csname#1\endcsname}{}} - -%D Faster but spoiling inheritance (copying parameters): -%D -%D \starttyping -%D \def\doifelsevaluesomething#1#2#3% -%D {\expandafter\ifx\csname#1\endcsname\empty#3\else#2\fi} -%D -%D \def\doifvaluesomething#1#2% -%D {\expandafter\ifx\csname#1\endcsname\empty\else#2\fi} -%D -%D \def\doifvaluenothing#1#2% -%D {\expandafter\ifx\csname#1\endcsname\empty#2\fi} -%D \stoptyping -%D -%D Slightly more efficient: - - \def\doifnothing{\doif \empty} - \def\doifsomething{\doifnot \empty} -\def\doifelsenothing{\doifelse\empty} - -%D The somewhat faster alternatives are: - -\long\def\doifvalue#1#2% +\def\doifvalue#1#2% {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% \ifx\!!stringa\!!stringb \expandafter\firstofoneargument @@ -5427,7 +5195,7 @@ \expandafter\gobbleoneargument \fi} -\long\def\doifnotvalue#1#2% +\def\doifnotvalue#1#2% {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% \ifx\!!stringa\!!stringb \expandafter\gobbleoneargument @@ -5435,7 +5203,7 @@ \expandafter\firstofoneargument \fi} -\long\def\doifelsevalue#1#2% +\def\doifelsevalue#1#2% {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}% \ifx\!!stringa\!!stringb \expandafter\firstoftwoarguments @@ -5443,7 +5211,7 @@ \expandafter\secondoftwoarguments \fi} -\long\def\doifnothing#1% +\def\doifnothing#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\firstofoneargument @@ -5451,7 +5219,7 @@ \expandafter\gobbleoneargument \fi} -\long\def\doifsomething#1% +\def\doifsomething#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\gobbleoneargument @@ -5459,7 +5227,7 @@ \expandafter\firstofoneargument \fi} -\long\def\doifelsenothing#1% +\def\doifelsenothing#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\firstoftwoarguments @@ -5467,7 +5235,7 @@ \expandafter\secondoftwoarguments \fi} -\long\def\doifsomethingelse#1% +\def\doifsomethingelse#1% {\edef\!!stringa{#1}% \ifx\!!stringa\empty \expandafter\secondoftwoarguments @@ -5475,7 +5243,7 @@ \expandafter\firstoftwoarguments \fi} -\long\def\doifvaluenothing#1% +\def\doifvaluenothing#1% {\edef\!!stringa{\csname#1\endcsname}% \ifx\!!stringa\empty \expandafter\firstofoneargument @@ -5483,7 +5251,7 @@ \expandafter\gobbleoneargument \fi} -\long\def\doifvaluesomething#1% +\def\doifvaluesomething#1% {\edef\!!stringa{\csname#1\endcsname}% \ifx\!!stringa\empty \expandafter\gobbleoneargument @@ -5491,7 +5259,7 @@ \expandafter\firstofoneargument \fi} -\long\def\doifelsevaluenothing#1% +\def\doifelsevaluenothing#1% {\edef\!!stringa{\csname#1\endcsname}% \ifx\!!stringa\empty \expandafter\firstoftwoarguments @@ -5505,21 +5273,21 @@ %D Also handy: \def\doifemptyelsevalue#1% - {\@EA\ifx\csname#1\endcsname\empty + {\expandafter\ifx\csname#1\endcsname\empty \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} \def\doifemptyvalue#1% - {\@EA\ifx\csname#1\endcsname\empty + {\expandafter\ifx\csname#1\endcsname\empty \expandafter\firstofoneargument \else \expandafter\gobbleoneargument \fi} \def\doifnotemptyvalue#1% - {\@EA\ifx\csname#1\endcsname\empty + {\expandafter\ifx\csname#1\endcsname\empty \expandafter\gobbleoneargument \else \expandafter\firstofoneargument @@ -5532,22 +5300,17 @@ %D \type {\doifallcommonelse}, where the first two %D arguments are sets. -\def\@@doifallcommonelse#1#2#3#4% slow - {\def\p!docommoncheck##1% +\def\syst_helpers_do_if_all_common_else#1#2#3#4% slow + {\def\syst_helpers_do_common_check_all##1% {\doifnotinset{##1}{#4}\donefalse \ifdone\else\expandafter\quitcommalist\fi}% \donetrue - \processcommalist[#3]\p!docommoncheck + \processcommalist[#3]\syst_helpers_do_common_check_all \ifdone\expandafter#1\else\expandafter#2\fi} -\def\doifallcommonelse - {\@@doifallcommonelse\firstoftwoarguments\secondoftwoarguments} - -\def\doifallcommon - {\@@doifallcommonelse\firstofonearguments\gobbleoneargument} - -\def\doifnotallcommon - {\@@doifallcommonelse\gobbleoneargument\firstofonearguments} +\def\doifallcommonelse{\syst_helpers_do_if_all_common_else\firstoftwoarguments\secondoftwoarguments} +\def\doifallcommon {\syst_helpers_do_if_all_common_else\firstofonearguments\gobbleoneargument } +\def\doifnotallcommon {\syst_helpers_do_if_all_common_else\gobbleoneargument \firstofonearguments } %D \macros %D {DOIF,DOIFELSE,DOIFNOT} @@ -5566,38 +5329,38 @@ %D We have to use a two||step implementation, because the %D expansion has to take place outside \type{\uppercase}. -\unexpanded\def\DOIF#1#2% +\unexpanded\def\syst_helpers_do_IF#1#2% {\uppercase{{$#1$}{$#2$}}% \expandafter\firstofoneargument \else \expandafter\gobbleoneargument \fi} -\unexpanded\def\DOIFNOT#1#2% +\unexpanded\def\syst_helpers_do_IF_NOT#1#2% {\uppercase{{$#1$}{$#2$}}% \expandafter\gobbleoneargument \else \expandafter\firstofoneargument \fi} -\unexpanded\def\DOIFELSE#1#2% +\unexpanded\def\syst_helpers_do_IF_ELSE#1#2% {\uppercase{{$#1$}{$#2$}}% \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} -\unexpanded\def\DOIFINSTRINGELSE#1#2% +\unexpanded\def\syst_helpers_do_IF_INSTRING_ELSE#1#2% {\uppercase{{$#1$}{$#2$}}% \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} -\def\DOIF #1#2{\normalexpanded{\p!DOIF {#1}{#2}}} -\def\DOIFNOT #1#2{\normalexpanded{\p!DOIFNOT {#1}{#2}}} -\def\DOIFELSE #1#2{\normalexpanded{\p!DOIFELSE {#1}{#2}}} -\def\DOIFINSTRINGELSE #1#2{\normalexpanded{\p!DOIFINSTRINGELSE{#1}{#2}}} +\unexpanded\def\DOIF #1#2{\normalexpanded{\syst_helpers_do_IF {#1}{#2}}} +\unexpanded\def\DOIFNOT #1#2{\normalexpanded{\syst_helpers_do_IF_NOT {#1}{#2}}} +\unexpanded\def\DOIFELSE #1#2{\normalexpanded{\syst_helpers_do_IF_ELSE {#1}{#2}}} +\unexpanded\def\DOIFINSTRINGELSE #1#2{\normalexpanded{\syst_helpers_do_IF_INSTRING_ELSE{#1}{#2}}} %D \macros %D {dosingleargumentwithset, @@ -5684,7 +5447,7 @@ \doifnotempty{##2}{\dostripcharacter##2\end}}% \let\!!strippedstring\empty \edef\!!stringa{#2}% - \@EA\dostripcharacter\!!stringa#1\end + \expandafter\dostripcharacter\!!stringa#1\end \dodoglobal\let#3\!!strippedstring} \def\stripspaces\from#1\to#2% will become \unspacestring#1\from#2 @@ -5749,62 +5512,62 @@ \def\p!doifsomespaceelse#1 #2#3\war{\if\noexpand#2@} -\long\def\doifsomespaceelse#1% % #2#3% +\def\doifsomespaceelse#1% % #2#3% {\p!doifsomespaceelse#1 @ @\war % #3\else#2\fi} \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} -%D \macros -%D {adaptdimension,balancedimensions} -%D -%D Again we introduce some macros that are closely related to -%D an interface aspect of \CONTEXT. The first command can be -%D used to adapt a \DIMENSION. -%D -%D \starttyping -%D \adaptdimension {dimension} {value} -%D \stoptyping -%D -%D When the value is preceed by a \type{+} or minus, the -%D dimension is advanced accordingly, otherwise it gets the -%D value. - -\def\doadaptdimension#1#2\\#3\\% - {\if#1+% - \dodoglobal\advance - \else\if#1-% - \dodoglobal\advance - \else - \dodoglobal - \fi\fi - #3 #1#2\relax} - -\def\adaptdimension#1#2% - {\expandafter\doadaptdimension#2\\#1\\} - -%D A second command takes two \DIMENSIONS. Both are adapted, -%D depending on the sign of the given value. -%D maat. This time we take the value as it is, and don't look -%D explicitly at the preceding sign. -%D -%D \starttyping -%D \balancedimensions {dimension 1} {dimension 2} {value} -%D \stoptyping -%D -%D When a positive value is given, the first dimension is -%D incremented, the second ond is decremented. A negative value -%D has the opposite result. - -\def\balancedimensions#1#2#3% - {\scratchdimen#3\relax - \redoglobal\advance#1 \scratchdimen - \dodoglobal\advance#2 -\scratchdimen} - -%D Both commands can be preceded by \type{\doglobal}. Here we -%D use \type{\redo} first, because \type{\dodo} resets the -%D global character. +% %D \macros +% %D {adaptdimension,balancedimensions} +% %D +% %D Again we introduce some macros that are closely related to +% %D an interface aspect of \CONTEXT. The first command can be +% %D used to adapt a \DIMENSION. +% %D +% %D \starttyping +% %D \adaptdimension {dimension} {value} +% %D \stoptyping +% %D +% %D When the value is preceed by a \type{+} or minus, the +% %D dimension is advanced accordingly, otherwise it gets the +% %D value. +% +% \def\doadaptdimension#1#2\\#3\\% +% {\if#1+% +% \dodoglobal\advance +% \else\if#1-% +% \dodoglobal\advance +% \else +% \dodoglobal +% \fi\fi +% #3 #1#2\relax} +% +% \def\adaptdimension#1#2% +% {\expandafter\doadaptdimension#2\\#1\\} +% +% %D A second command takes two \DIMENSIONS. Both are adapted, +% %D depending on the sign of the given value. +% %D maat. This time we take the value as it is, and don't look +% %D explicitly at the preceding sign. +% %D +% %D \starttyping +% %D \balancedimensions {dimension 1} {dimension 2} {value} +% %D \stoptyping +% %D +% %D When a positive value is given, the first dimension is +% %D incremented, the second ond is decremented. A negative value +% %D has the opposite result. +% +% \def\balancedimensions#1#2#3% +% {\scratchdimen#3\relax +% \redoglobal\advance#1 \scratchdimen +% \dodoglobal\advance#2 -\scratchdimen} +% +% %D Both commands can be preceded by \type{\doglobal}. Here we +% %D use \type{\redo} first, because \type{\dodo} resets the +% %D global character. %D \macros %D {processseparatedlist} @@ -5850,7 +5613,7 @@ #4{##1##2}% \fi\fi\fi \dodoprocessseparatedlist}% - \@EA\dodoprocessseparatedlist\gobbleoneargument#1#3]#3} + \expandafter\dodoprocessseparatedlist\gobbleoneargument#1#3]#3} \def\processseparatedlist[% {\doprocessseparatedlist\relax} @@ -5872,7 +5635,7 @@ %D \processlist(){=>}\docommand(a=>b=>c=>d) %D \stoptyping -\long\def\processlist#1#2#3#4% no blank skipping ! +\def\processlist#1#2#3#4% no blank skipping ! {\def\doprocesslist##1#2% {\def\dodoprocesslist####1####2#3% {\ifx#2####1% @@ -5931,7 +5694,7 @@ \escapechar\minusone \dountexsomething} -\long\def\dountexsomething#1#2\to#3% +\def\dountexsomething#1#2\to#3% {\doglobal#1#2\to\untexedargument \endgroup \let#3\untexedargument} @@ -6017,7 +5780,7 @@ \newbox\@@dlhbox -\unexpanded \def\dontleavehmode +\unexpanded\def\dontleavehmode {\ifhmode\else \ifmmode\else \setbox\@@dlhbox\hbox{\mathsurround\zeropoint\everymath\emptytoks$ $}\unhbox\@@dlhbox \fi \fi} @@ -6039,11 +5802,11 @@ %D %D the first argument may be a \type{\macro}. -\def\uppercasestring#1\to#2% first @EA redundant - {\uppercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}} +\def\uppercasestring#1\to#2% + {\uppercase\expandafter{\expandafter\dodoglobal\expandafter\edef\expandafter#2\expandafter{\normalexpanded{#1}}}} -\def\lowercasestring#1\to#2% first @EA redundant - {\lowercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}} +\def\lowercasestring#1\to#2% + {\lowercase\expandafter{\expandafter\dodoglobal\expandafter\edef\expandafter#2\expandafter{\normalexpanded{#1}}}} %D \macros %D {handletokens} @@ -6108,7 +5871,7 @@ %D Consider for instance the macro for which I originally %D wrote this token handler. -\long\def\splitofftokens#1\from#2\to#3% slow but hardly used +\def\splitofftokens#1\from#2\to#3% slow but hardly used {\ifnum#1>\zerocount \scratchcounter#1\relax \def\dosplitofftokens##1% @@ -6117,8 +5880,8 @@ \edef#3{#3##1}% \fi}% % \let#3\empty % #3 can be #2, so: - \@EA\let\@EA#3\@EA\empty - \@EA\handletokens#2\with\dosplitofftokens + \expandafter\let\expandafter#3\expandafter\empty + \expandafter\handletokens#2\with\dosplitofftokens \else \edef#3{#2}% \fi} @@ -6135,11 +5898,11 @@ %D mysterious way of expanding. Look at this: %D %D \startbuffer[next] -%D \def\next{a} \edef\test{\next} [\test] -%D \let\next=b \edef\test{\test\next} [\test] -%D \let\next=c \edef\test{\next} [\test] -%D \let\next=d \edef\test{\test\next} [\test] -%D \let\next=e \@EA\edef\@EA\test\@EA{\test\next} [\test] +%D \def\next{a} \edef\test{\next} [\test] +%D \let\next=b \edef\test{\test\next} [\test] +%D \let\next=c \edef\test{\next} [\test] +%D \let\next=d \edef\test{\test\next} [\test] +%D \let\next=e \expandafter\edef\expandafter\test\expandafter{\test\next} [\test] %D \stopbuffer %D %D \typebuffer[next] @@ -6158,7 +5921,7 @@ \def\dohandletokens % \nexthandledtoken is part of interface {\futurelet\nexthandledtoken\dodohandletokens} -\long\def\handletokens#1\with#2% +\def\handletokens#1\with#2% {\gdef\dododohandletokens{#2}% permits more complex #2's \dohandletokens#1\end} @@ -6174,7 +5937,7 @@ \def\dodohandletokensone * % {\dododohandletokens{ }\dohandletokens} -\long\def\dodohandletokenstwo *#1% +\def\dodohandletokenstwo *#1% {\dododohandletokens{#1}\dohandletokens} %D This macro is tested on: @@ -6217,41 +5980,6 @@ \appendtoks \let\iftrialtypesetting\iffalse \to \everyresettrialtypesetting %D \macros -%D {startlocal, startglobal} -%D -%D The next four macros are rather self explaining: -%D -%D \starttyping -%D \startlocal -%D whatever assignments -%D \stoplocal -%D -%D \startglobal -%D whatever assignments -%D \stopglobal -%D \stoptyping -%D -%D These macros are meant for those who know the difference -%D between local and global assignments and are aware of the -%D possible unwanted side effect - -\def\dostartglobaldefs#1#2% - {\scratchcounter\globaldefs - \ifnum\globaldefs#1\zerocount - \globaldefs-\globaldefs - \fi - \advance\globaldefs#2\plusone - \expandafter\chardef\csname@gd@\the\globaldefs\endcsname\scratchcounter} - -\def\dostopglobaldefs - {\globaldefs\ifcsname @gd@\the\globaldefs\endcsname\zerocount} - -\unexpanded\def\startlocal {\dostartglobaldefs>-} -\unexpanded\def\stoplocal {\dostopglobaldefs} -\unexpanded\def\startglobal {\dostartglobaldefs<+} -\unexpanded\def\stopglobal {\dostopglobaldefs} - -%D \macros %D {twodigitrounding} %D %D When using \type {\special}s or \type {\pdfliteral}s, it @@ -6259,19 +5987,24 @@ %D macro rounds a real number to two digits. It takes one %D argument and only works in \ETEX. -\def\dointegerrounding #1.#2\relax {#1} -\def\doonedigitrounding #1.#2#3\relax {\ifx#2*#1\else#1.#2\fi} -\def\dotwodigitrounding #1.#2#3#4\relax {\ifx#2*#1\else#1.#2#3\fi} -\def\dothreedigitrounding#1.#2#3#4#5\relax{\ifx#2*#1\else#1.#2#3#4\fi} +% \def\dointegerrounding #1.#2\relax {#1} +% \def\doonedigitrounding #1.#2#3\relax {\ifx#2*#1\else#1.#2\fi} +% \def\dotwodigitrounding #1.#2#3#4\relax {\ifx#2*#1\else#1.#2#3\fi} +% \def\dothreedigitrounding#1.#2#3#4#5\relax{\ifx#2*#1\else#1.#2#3#4\fi} +% +% \def\integerrounding#1% +% {\expandafter\expandafter\expandafter\dointegerrounding \expandafter\WITHOUTPT\the\dimexpr#1\points+.5\points \relax .\relax} +% \def\onedigitrounding#1% +% {\expandafter\expandafter\expandafter\doonedigitrounding \expandafter\WITHOUTPT\the\dimexpr#1\points+.05\points \relax 00.*0\relax} +% \def\twodigitrounding#1% +% {\expandafter\expandafter\expandafter\dotwodigitrounding \expandafter\WITHOUTPT\the\dimexpr#1\points+.005\points \relax 000.*00\relax} +% \def\threedigitrounding#1% +% {\expandafter\expandafter\expandafter\dothreedigitrounding\expandafter\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax0000.*00\relax} -\def\integerrounding#1% - {\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.5\points \relax .\relax} -\def\onedigitrounding#1% - {\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.05\points \relax 00.*0\relax} -\def\twodigitrounding#1% - {\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.005\points \relax 000.*00\relax} -\def\threedigitrounding#1% - {\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax0000.*00\relax} +\def\integerrounding #1{\cldcontext{"\letterpercent 0.0f",#1}} +\def\onedigitrounding #1{\cldcontext{"\letterpercent 0.1f",#1}} +\def\twodigitrounding #1{\cldcontext{"\letterpercent 0.2f",#1}} +\def\threedigitrounding#1{\cldcontext{"\letterpercent 0.3f",#1}} %D \macros %D {processcontent} @@ -6287,12 +6020,12 @@ %D %D This macro is first used in the tabulation macros. -\def\processcontent#1% - {\begingroup\@EA\doprocesscontent\csname#1\endcsname} +\unexpanded\def\processcontent#1% + {\begingroup\expandafter\doprocesscontent\csname#1\endcsname} -\def\doprocesscontent#1#2#3% - {\long\def\doprocesscontent##1#1% - {\endgroup\long\def#2{##1}#3}% +\unexpanded\def\doprocesscontent#1#2#3% + {\unexpanded\def\doprocesscontent##1#1% + {\endgroup\def#2{##1}#3}% \doprocesscontent} %D \macros @@ -6343,7 +6076,7 @@ \newcount\comparedresult \def\sortcommacommand[#1]% - {\@EA\sortcommalist\@EA[#1]} + {\expandafter\sortcommalist\expandafter[#1]} \def\sortcommalist[#1]#2% {\getcommalistsize[#1]% @@ -6362,8 +6095,8 @@ \def\!!tempa{#1}% \ifx\!!tempa\empty\else \scratchcounter\plusone - \@EA\getcommalistsize\@EA[\sortedcommalist]% - \@EA\processcommalist\@EA[\sortedcommalist]\docompareitems + \expandafter\getcommalistsize\expandafter[\sortedcommalist]% + \expandafter\processcommalist\expandafter[\sortedcommalist]\docompareitems \fi \fi} @@ -6372,20 +6105,22 @@ \def\docompareitems#1% {\doifnotempty{#1} - {\@EA\comparecommand\@EA{\!!tempa}{#1}\relax + {\expandafter\comparecommand\expandafter{\!!tempa}{#1}\relax %\ifcase\compareresult % equal \ifnum\comparedresult<2 \ifnum\scratchcounter=\commalistsize - \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist - \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\sortedcommalist + \expandafter\expandafter\expandafter{\expandafter\sortedcommalist\expandafter,\!!tempa}% \fi %\or % new element larger % \ifnum\scratchcounter=\commalistsize - % \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist - % \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}% + % \expandafter\expandafter\expandafter\def + % \expandafter\expandafter\expandafter\sortedcommalist + % \expandafter\expandafter\expandafter{\expandafter\sortedcommalist\expandafter,\!!tempa}% % \fi \else % old element larger - \@EA\def\@EA\newcommalistelement\@EA{\!!tempa,#1}% + \expandafter\def\expandafter\newcommalistelement\expandafter{\!!tempa,#1}% \replaceincommalist\sortedcommalist\scratchcounter \expandafter\quitcommalist \fi}% @@ -6412,8 +6147,8 @@ \def\@True {00} \def\@False {01} -\def\@Not #1{0\ifcase#11 \or\@EA 1\else \@EA 0\fi} -\def\@And #1#2{0\ifcase#1#2 \@EA 0\else \@EA 1\fi} +\def\@Not #1{0\ifcase#11 \or\expandafter 1\else \expandafter 0\fi} +\def\@And #1#2{0\ifcase#1#2 \expandafter 0\else \expandafter 1\fi} %D \macros %D {setdimensionwithunit, freezedimensionwithunit} @@ -6439,27 +6174,43 @@ {\setdimensionwithunit\scratchdimen#1{#2}\edef#1{\the\scratchdimen}} %D \macros -%D {doifsometokselse} +%D {doifsometokselse, doifsometoks} %D %D Not that fast I guess, but here's a way to test for token %D registers being empty. -\def\doifsometokselse#1% % #2#3% - {\edef\!!stringa{\the#1}% - \ifx\!!stringa\empty % #3\else#2\fi} +\def\doifsometokselse#1% + {\edef\!!stringa{\the#1}% one level expansion so quite ok + \ifx\!!stringa\empty \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} +\def\doifsometoks#1% + {\edef\!!stringa{\the#1}% one level expansion so quite ok + \ifx\!!stringa\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\def\doifemptytoks#1% + {\edef\!!stringa{\the#1}% one level expansion so quite ok + \ifx\!!stringa\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + %D \macros %D {startstrictinspectnextcharacter} %D %D This one if for Taco's bibliography module: -\let\normalinspectnextcharacter\inspectnextcharacter +\let\syst_helpers_normal_inspect_next_character\syst_helpers_inspect_next_character -\def\strictinspectnextcharacter% no user macro ! +\def\syst_helpers_strict_inspect_next_character% no user macro ! {\ifx\nexttoken\charactertoken \expandafter\!!stringa \else @@ -6469,10 +6220,10 @@ % better: push/pop \unexpanded\def\startstrictinspectnextcharacter - {\let\inspectnextcharacter\strictinspectnextcharacter} + {\let\syst_helpers_inspect_next_character\syst_helpers_strict_inspect_next_character} \unexpanded\def\stopstrictinspectnextcharacter - {\let\inspectnextcharacter\normalinspectnextcharacter} + {\let\syst_helpers_inspect_next_character\syst_helpers_normal_inspect_next_character} \def\strictdoifnextoptionalelse#1#2% {\startstrictinspectnextcharacter @@ -6500,16 +6251,16 @@ %D These are needed in ordinal number conversions: \def\lastdigit#1% - {\@EA\thelastdigit\number#1\relax} + {\expandafter\thelastdigit\number#1\relax} \def\thelastdigit#1#2% - {\ifx#2\relax#1\else\@EA\thelastdigit\@EA#2\fi} + {\ifx#2\relax#1\else\expandafter\thelastdigit\expandafter#2\fi} \def\lasttwodigits#1% - {\@EA\thelasttwodigits\@EA0\number#1\relax} + {\expandafter\thelasttwodigits\expandafter0\number#1\relax} \def\thelasttwodigits#1#2#3% 0 dig ... \relax - {\ifx#3\relax#1#2\else\@EA\thelasttwodigits\@EA#2\@EA#3\fi} + {\ifx#3\relax#1#2\else\expandafter\thelasttwodigits\expandafter#2\expandafter#3\fi} %D \macros %D {serializecommalist} @@ -6537,7 +6288,7 @@ %D macro works ok with \type {\the}, \type {\number} as well %D as \ETEX's \type {\numexpr}. -\def\purenumber#1{\@EA\firstofoneargument\@EA{\number#1}} +\def\purenumber#1{\expandafter\firstofoneargument\expandafter{\number#1}} %D \macros %D {filterfromvalue} @@ -6593,8 +6344,8 @@ \fi} \def\filterfromvalue#1#2#3% value max n - {\@EA\@EAEAEA\csname % we use the fact that an - \@EA\ifx\csname#1\endcsname\relax % undefined cs has become \relax + {\expandafter\doubleexpandafter\csname % we use the fact that an + \expandafter\ifx\csname#1\endcsname\relax % undefined cs has become \relax \strippedcsname\gobbleoneargument % which we then gobble here \else \dofilterfromstr{#2}{#3}% @@ -6627,12 +6378,12 @@ % \setmeasure {xx} {1cm} % \setmeasure {xxx}{1cm} -\def\setmeasure #1#2{\expandafter\def \csname\??dm#1\endcsname{#2}} % quick way -\def\setemeasure#1#2{\expandafter\edef\csname\??dm#1\endcsname{#2}} % quick way -\def\setgmeasure#1#2{\expandafter\gdef\csname\??dm#1\endcsname{#2}} % quick way -\def\setxmeasure#1#2{\expandafter\xdef\csname\??dm#1\endcsname{#2}} % quick way +\unexpanded\def\setmeasure #1#2{\expandafter\def \csname\??dm#1\endcsname{#2}} % quick way +\unexpanded\def\setemeasure#1#2{\expandafter\edef\csname\??dm#1\endcsname{#2}} % quick way +\unexpanded\def\setgmeasure#1#2{\expandafter\gdef\csname\??dm#1\endcsname{#2}} % quick way +\unexpanded\def\setxmeasure#1#2{\expandafter\xdef\csname\??dm#1\endcsname{#2}} % quick way -\def\measure#1% +\def\measure#1% maybe \dimexpr ... \relax {\ifcsname\??dm#1\endcsname\csname\??dm#1\endcsname\else\zeropoint\fi} %D \macros @@ -6751,28 +6502,28 @@ % \copycsname xxx\endcsname\csname ..\endcsname -\def\copycsname{\@EA\@EA\@EA\let\@EA\@EA\csname} +\def\copycsname{\expandafter\expandafter\expandafter\let\expandafter\expandafter\csname} % \letcscsname \crap \csname ..\endcsname % \letcsnamecs \csname ..\endcsname\crap % \letcsnamecsname\csname ..\endcsname\csname ..\endcsname -\def\letcscsname {\@EA\let\@EA} -\def\letcsnamecs {\@EA\let} -\def\letcsnamecsname{\@EA\@EA\@EA\let\@EA\@EA} +\def\letcscsname {\expandafter\let\expandafter} +\def\letcsnamecs {\expandafter\let} +\def\letcsnamecsname{\expandafter\expandafter\expandafter\let\expandafter\expandafter} % another one, add an item to a commalist \def\addvalue#1#2% cs item {\ifcsname#1\endcsname\else\expandafter\let\csname#1\endcsname\empty\fi - \normalexpanded{\noexpand\addtocommalist{#2}\@EA\noexpand\csname#1\endcsname}} + \normalexpanded{\noexpand\addtocommalist{#2}\expandafter\noexpand\csname#1\endcsname}} \def\unspaced#1% {\dounspaced#1\end} \def\dounspaced#1% {\ifx#1\end - \@EA\gobbleoneargument + \expandafter\gobbleoneargument \else \ifx#1\blankspace\else#1\fi \fi @@ -6796,44 +6547,44 @@ \def\dodoifhasspaceelse#1 #2#3\relax % \space\empty\relax {\ifx\!!stringa\space - \@EA\firstoftwoarguments + \expandafter\firstoftwoarguments \else\ifx#2\empty - \@EAEAEA\secondoftwoarguments + \doubleexpandafter\secondoftwoarguments \else - \@EAEAEA\firstoftwoarguments + \doubleexpandafter\firstoftwoarguments \fi\fi} % this will replace loadfile once and alike !!! todo \def\@flg@{@flg@} -\def\setflag #1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\zerocount} -\def\resetflag#1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\plusone} +\def\setflag #1{\expandafter\dodoglobal\expandafter\let\csname\@flg@#1\endcsname\zerocount} +\def\resetflag#1{\expandafter\dodoglobal\expandafter\let\csname\@flg@#1\endcsname\plusone} \let\ifflagged\ifcase \def\flag#1{\csname\@flg@#1\endcsname} \def\doifelseflagged#1% - {\@EA\ifx\csname\@flg@#1\endcsname\relax - \@EA\secondoftwoarguments + {\expandafter\ifx\csname\@flg@#1\endcsname\relax + \expandafter\secondoftwoarguments \else\ifcase\csname\@flg@#1\endcsname - \@EAEAEA\firstoftwoarguments + \doubleexpandafter\firstoftwoarguments \else - \@EAEAEA\secondoftwoarguments + \doubleexpandafter\secondoftwoarguments \fi\fi} \def\doifnotflagged#1% - {\@EA\ifx\csname\@flg@#1\endcsname\relax - \@EA\firstofoneargument + {\expandafter\ifx\csname\@flg@#1\endcsname\relax + \expandafter\firstofoneargument \else\ifcase\csname\@flg@#1\endcsname - \@EAEAEA\gobbleoneargument + \doubleexpandafter\gobbleoneargument \else - \@EAEAEA\firstofoneargument + \doubleexpandafter\firstofoneargument \fi\fi} -\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey % [bypasses k!prefix] - {\@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#1#5\endcsname}} +\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey + {\expandafter\def\csname#1#3\expandafter\endcsname\expandafter{\csname#1#5\endcsname}} % \buildarray[test][aa,bb,cc,dd,ee,ff] % \setarrayelement{test}{1}{qq} @@ -6869,14 +6620,14 @@ {\ifx#1\relax \ifcase\scratchcounter \endgroup - \@EAEAEA\secondoftwoarguments + \doubleexpandafter\secondoftwoarguments \else \endgroup - \@EAEAEA\firstoftwoarguments + \doubleexpandafter\firstoftwoarguments \fi \else \endgroup - \@EA\secondoftwoarguments + \expandafter\secondoftwoarguments \fi} \def\doifnonzeropositiveelse#1% @@ -6884,10 +6635,10 @@ % here ? -\def\dosetrawvalue #1#2#3{\@EA \def\csname#1#2\endcsname{#3}} -\def\dosetrawevalue#1#2#3{\@EA\edef\csname#1#2\endcsname{#3}} -\def\dosetrawgvalue#1#2#3{\@EA\gdef\csname#1#2\endcsname{#3}} -\def\dosetrawxvalue#1#2#3{\@EA\xdef\csname#1#2\endcsname{#3}} +\def\dosetrawvalue #1#2#3{\expandafter \def\csname#1#2\endcsname{#3}} +\def\dosetrawevalue#1#2#3{\expandafter\edef\csname#1#2\endcsname{#3}} +\def\dosetrawgvalue#1#2#3{\expandafter\gdef\csname#1#2\endcsname{#3}} +\def\dosetrawxvalue#1#2#3{\expandafter\xdef\csname#1#2\endcsname{#3}} \def\getrawparameters {\dogetparameters\dosetrawvalue } \def\getraweparameters {\dogetparameters\dosetrawevalue} @@ -6934,7 +6685,7 @@ \newcount\featuretest -\def\testfeature#1#2% +\unexpanded\def\testfeature#1#2% {\def\dotestfeature {\advance\featuretest \plusone \ifnum\featuretest>#1\else#2\expandafter\dotestfeature\fi}% @@ -6950,11 +6701,14 @@ \wait \egroup} -\def\showtimer#1% +\unexpanded\def\showtimer#1% {\writestatus{runtime}{\elapsedseconds\space s / #1}} -\def\testfeatureonce#1#2% - {\let\wait\relax\testfeature{#1}{#2}\end} +\unexpanded\def\testfeatureonce#1#2% + {\begingroup + \let\wait\relax + \testfeature{#1}{#2}% + \endgroup} %D \macros %D {freezedimenmacro} @@ -6984,10 +6738,10 @@ {\afterassignment\gobbleassigndimen#1=#2\!!zeropoint\\} \def\setusage#1% - {\@EA\let\csname#1\endcsname\iftrue} + {\expandafter\let\csname#1\endcsname\iftrue} \def\resetusage#1% - {\@EA\let\csname#1\endcsname\iffalse} + {\expandafter\let\csname#1\endcsname\iffalse} \def\ifusage#1% {\ifcsname#1\endcsname\else @@ -7002,12 +6756,12 @@ % The following macros are used in XML handling. -\long\setvalue{@u@s@"}#1#2"{#2} \long\setvalue{@g@s@"}#1#2"{\scratchtoks{#2}} -\long\setvalue{@u@s@'}#1#2'{#2} \long\setvalue{@g@s@'}#1#2'{\scratchtoks{#2}} -\long\setvalue{@u@s@ }#1#2 {#2} \long\setvalue{@g@s@ }#1#2 {\scratchtoks{#2}} +\setvalue{@u@s@"}#1#2"{#2} \setvalue{@g@s@"}#1#2"{\scratchtoks{#2}} +\setvalue{@u@s@'}#1#2'{#2} \setvalue{@g@s@'}#1#2'{\scratchtoks{#2}} +\setvalue{@u@s@ }#1#2 {#2} \setvalue{@g@s@ }#1#2 {\scratchtoks{#2}} -\long\def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1} -\long\def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1} +\def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1} +\def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1} \def\dowithgrabbedstring#1% {\def\@@dowithgrabbedstring{#1}% @@ -7019,31 +6773,35 @@ \def\@@ifequal#1#2\@@and#3% {\ifx#1\relax \ifx#3\relax - \@EAEAEA\@@if@@equal@@true + \doubleexpandafter\@@if@@equal@@true \else - \@EAEAEA\@@if@@equal@@false + \doubleexpandafter\@@if@@equal@@false \fi \else \ifx#3\relax - \@EAEAEAEAEAEA\@@if@@equal@@false + \tripleexpandafter\@@if@@equal@@false \else\ifx#1#3% % go on \else - \@EAEAEAEAEAEA\@@if@@equal@@false + \tripleexpandafter\@@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} +\def\@@if@@equal@@true #1\@@then#2#3{#2} +\def\@@if@@equal@@false#1\@@then#2#3{#3} -\def\appended#1#2#3{\@EA#1\@EA#2\@EA{#2#3}} -\def\appendvalue #1{\@EA\appended\@EA \def\csname#1\endcsname} -\def\appendgvalue#1{\@EA\appended\@EA\gdef\csname#1\endcsname} +\def\appended#1#2#3{\expandafter#1\expandafter#2\expandafter{#2#3}} +\def\appendvalue #1{\expandafter\appended\expandafter \def\csname#1\endcsname} +\def\appendgvalue#1{\expandafter\appended\expandafter\gdef\csname#1\endcsname} -\def\prepended#1#2#3{\scratchtoks{#3}\@EA\@EA\@EA#1\@EA\@EA\@EA#2\@EA\@EA\@EA{\@EA\the\@EA\scratchtoks#2}} -\def\prependvalue #1{\@EA\prepended\@EA \def\csname#1\endcsname} -\def\prependgvalue#1{\@EA\prepended\@EA\gdef\csname#1\endcsname} +\def\prepended#1#2#3% + {\scratchtoks{#3}% + \expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter#2\expandafter\expandafter\expandafter + {\expandafter\the\expandafter\scratchtoks#2}} + +\def\prependvalue #1{\expandafter\prepended\expandafter \def\csname#1\endcsname} +\def\prependgvalue#1{\expandafter\prepended\expandafter\gdef\csname#1\endcsname} %D \macros %D {compresscommacommandnrs,compresscommalistnrs,compressedcommalistnrs, @@ -7087,7 +6845,7 @@ \def\dodocompresslistnrs {\edef\compressedlist {\ifx\compressedlist\empty\else\compressedlist,\fi - {\the\!!counta}{\ifnum\!!countb>\!!counta\the\!!countb\fi}}} + {\the\!!counta}{\ifnum\!!countb>\!!counta\the\!!countb\fi}}} %D \def\test#1{{\tttf#1->\compresscommalistnrs[#1]\defconvertedcommand\ascii\compressedlist\ascii}} %D \startlines @@ -7198,9 +6956,9 @@ \def\uncompresslist[#1]% by TH {\let\uncompressedlist\empty \def\docompressedlistitem##1-##2-% - {\@EA\dorecurse\@EA + {\expandafter\dorecurse\expandafter {\the\numexpr1+##2-##1\relax}% - {\@EA\appendtocommalist\@EA{\the\numexpr##1-1+####1\relax}\uncompressedlist}}% + {\expandafter\appendtocommalist\expandafter{\the\numexpr##1-1+####1\relax}\uncompressedlist}}% \def\douncompresslist##1% {\doifinstringelse{-}{##1} {\docompressedlistitem##1-} @@ -7302,4 +7060,117 @@ \unexpanded\def\signalcharacter{\char\zerocount} % \zwj +%D Here are some nasty helpers: + +\def\constantnumber#1% + {\ifcase#1\zerocount + \or \plusone + \or \plustwo + \or \plusthree + \or \plusfour + \or \plusfive + \or \plussix + \or \plusseven + \or \pluseight + \or \plusnine + \or \plusten + \else \number#1\relax\fi} + +\def\constantnumberargument#1% + {\ifcase#1\zerocount + \or \plusone + \or \plustwo + \or \plusthree + \or \plusfour + \or \plusfive + \or \plussix + \or \plusseven + \or \pluseight + \or \plusnine + \or \plusten + \else {\number#1}\fi} + +\def\constantdimen#1% + {\ifdim#1=\zeropoint + \zeropoint + \else + \the#1\relax + \fi} + +\def\constantdimenargument#1% + {\ifdim#1=\zeropoint + \zeropoint + \else + {\the#1}% + \fi} + +\def\constantemptyargument#1% + {\ifx#1\empty + \noexpand\empty + \else + {#1}% + \fi} + +%D These can be used when constructing often reused token lists, +%D as we do with tabulates. + \protect \endinput + +% \edef\choicetokenyes{+} +% \edef\choicetokennop{-} +% +% \unexpanded\def\startchoice#1% +% {\pushmacro\currentchoicevalue +% \edef\currentchoicevalue{#1}% +% \checkchoicetoken} +% +% \unexpanded\def\checkchoicetoken#1% +% {\edef\choicetoken{#1}% +% \ifx\choicetoken\choicetokenyes +% \singleexpandafter\checkchoiceyes +% \else\ifx\choicetoken\choicetokennop +% \doubleexpandafter\checkchoicenop +% \else +% \doubleexpandafter\choicequit +% \fi\fi} +% +% \def\checkchoiceyes#1% +% {\edef\choicevalue{#1}% +% \ifx\currentchoicevalue\choicevalue +% \expandafter\choiceindeed +% \else +% \expandafter\choiceignore +% \fi} +% +% \def\checkchoicenop +% {\choiceindeed} +% +% \def\choiceabort#1\stopchoice +% {\popmacro\currentchoicevalue} +% +% \def\choicequit +% {\popmacro\currentchoicevalue} +% +% \def\choiceindeed#1#2\stopchoice +% {\popmacro\currentchoicevalue +% #1} +% +% \def\choiceignore#1% +% {\checkchoicetoken} +% +% \let\stopchoice\relax +% +% \def\xxx{3} +% \def\xxx{x} +% +% \startchoice {\xxx} +% + {1} { +% first +% } + {2} { +% second +% } + {3} { +% third +% } - { +% nothing +% } +% \stopchoice |