summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/syst-aux.mkxl
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/syst-aux.mkxl')
-rw-r--r--tex/context/base/mkiv/syst-aux.mkxl6678
1 files changed, 0 insertions, 6678 deletions
diff --git a/tex/context/base/mkiv/syst-aux.mkxl b/tex/context/base/mkiv/syst-aux.mkxl
deleted file mode 100644
index 5410590a6..000000000
--- a/tex/context/base/mkiv/syst-aux.mkxl
+++ /dev/null
@@ -1,6678 +0,0 @@
-%D \module
-%D [ file=syst-aux, % merge of syst-gen cum suis
-%D version=1996.03.20,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=General,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%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
-%C details.
-
-%D In the process of being adapted to \LMTX\ flags so a bit of a mess now. Also
-%D our playground.
-
-\registerctxluafile{syst-aux}{autosuffix}
-\registerctxluafile{syst-mac}{autosuffix}
-
-%D This file is a follow up in \type {syst-aux.mkii} and \type {syst-aux.mkiv} where
-%D you can find some more pure \TEX\ or \LUATEX\ variants. There are quite some
-%D helpers here and many no longer are used but we keep them around because they
-%D have always been there. However, the implementation in \LMTX\ can be somewhat
-%D different that in \MKIV, because it's also a kind of a playground for new
-%D features. Of course nostalgia also plays a role.
-%D
-%D For the original code we refer to \type {syst-aux.mkii} and its follow up \type
-%D {syst-aux.mkiv}. These also have historic versions. As usual, the upgrade went
-%D through stages. First I wrote variants usign the new \type {\ignorearguments}
-%D feature, then I decided to implement a few more conditionals and new fancy code
-%D could be ditched before it was even published. I kept some as examples.
-%D
-%D Of course I couldn't do this without Wolfgang looking over my shoulder. Changing
-%D core code is kind of tricky.
-
-\unprotect
-
-%D \macros
-%D {unexpanded}
-%D
-%D Because we use this module only in \MKIV, we have removed the old protection
-%D code.
-%D
-%D \starttyping
-%D \protected\def\somecommand{... ... ...}
-%D \stoptyping
-%D
-%D This overloads the \ETEX\ primitive but as we already had an \MKII\ solution we
-%D keep the same name for a similar mechanism. So, effectively we have two ways to
-%D protect a macro.
-
-\pushoverloadmode
-
-\aliased\let\unexpanded\normalprotected
-
-\popoverloadmode
-
-%D We're definitely in \LMTX\ mode here.
-
-\aliased \let\startlmtxmode\relax
-\aliased \let\stoplmtxmode \relax
-\permanent\def\startmkivmode#-\stopmkivmode{}
-\permanent\let\stopmkivmode \relax
-
-%D As we don't have namespace definers yet, we use a special one. Later we will
-%D do a better job.
-
-\ifdefined\c_syst_helpers_n_of_namespaces
-
- % lets plug in a better error message
-
-\else
-
- \newcount\c_syst_helpers_n_of_namespaces \c_syst_helpers_n_of_namespaces\pluseight % 1-8 reserved for catcodes
-
- \def\v_interfaces_prefix_template_system{\number \c_syst_helpers_n_of_namespaces>>}
- %def\v_interfaces_prefix_template_system{\characters\c_syst_helpers_n_of_namespaces>>} % no \characters yet
-
-\fi
-
-\permanent\protected\def\installsystemnamespace#1% maybe move this to syst-ini
- {\ifcsname ??#1\endcsname
- \writestatus\m!system{duplicate system namespace '#1'}\wait
- \else
- \global\advance\c_syst_helpers_n_of_namespaces\plusone
- \expandafter\edef\csname ??#1\endcsname{\v_interfaces_prefix_template_system}%
- \fi}
-
-%D \macros
-%D {normalspace}
-%D
-%D There is already \type{\space} but just to be sure we also provide this one:
-
-\def\normalspace{ }
-
-\newif\if!!donea \newif\if!!doneb \newif\if!!donec % soon obsolete in lmtx
-\newif\if!!doned \newif\if!!donee \newif\if!!donef % soon obsolete in lmtx
-
-\immutable\def\!!zerocount {0} % alongside \zerocount
-\immutable\def\!!minusone {-1} % ...
-\immutable\def\!!plusone {1} % ...
-\immutable\def\!!plustwo {2} % ...
-\immutable\def\!!plusthree {3} % ...
-\immutable\def\!!plusfour {4} % ...
-\immutable\def\!!plusfive {5} % ...
-\immutable\def\!!plussix {6} % ...
-\immutable\def\!!plusseven {7} % ...
-\immutable\def\!!pluseight {8} % ...
-\immutable\def\!!plusnine {9} % alongside \plusnine
-
-\setnewconstant \uprotationangle 0
-\setnewconstant\rightrotationangle 90
-\setnewconstant \downrotationangle 180
-\setnewconstant \leftrotationangle 270
-
-\ifdefined\data \else \let\data \relax \fi % dep checker
-
-%D \macros
-%D {s!,c!,e!,p!,v!,@@,??}
-%D
-%D To save memory, we use constants (sometimes called variables). Redefining these
-%D constants can have disastrous results. Of course, expanding them costs time, so
-%D that's the price to pay. More are defined elsewhere. Of course we later pay a
-%D price when they need to be expanded.
-
-% \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!do {do}
-% \def\s!dodo {dodo}
-%
-% \def\s!complex {complex}
-% \def\s!simple {simple}
-%
-% \def\s!start{start}
-% \def\s!stop {stop}
-
-% \immutable\def\s!empty {empty}
-
-%D Sometimes we pass macros as arguments to commands that don't expand them before
-%D interpretation. Such commands can be enclosed with \type {\expanded}, like:
-%D
-%D \starttyping
-%D \expanded{\setupsomething[\alfa]}
-%D \stoptyping
-%D
-%D Such situations occur for instance when \type {\alfa} is a commalist or when data
-%D stored in macros is fed to index of list commands. If needed, one should use
-%D \type {\noexpand} inside the argument. Later on we will meet some more clever
-%D alternatives to this command. Beware, only the simple one has \type {\noexpand}
-%D before its argument.
-
-\let\m_syst_helpers_expanded\empty
-
-\pushoverloadmode
-
-\permanent\protected\def\expanded#1%
- {\xdef\m_syst_helpers_expanded{\noexpand#1}\m_syst_helpers_expanded}
-
-\popoverloadmode
-
-\permanent\protected\def\startexpanded#1\stopexpanded
- {\xdef\m_syst_helpers_expanded{#1}\m_syst_helpers_expanded}
-
-\aliased\let\stopexpanded\relax
-
-%D Recent \TEX\ engines have a primitive \type {\expanded} and we will use that when
-%D possible. After all, we can make not expandable macros now. The name clash is an
-%D unfortunate fact and in retrospect I should nto have agreed to a primitive having
-%D that same name.
-
-% We cannot use the next variant as first we need to adapt \type {##}'s in callers:
-%
-% \def\expanded#1%
-% {\normalexpanded{\noexpand#1}}
-%
-% \def\startexpanded#1\stopexpanded
-% {\normalexpanded{#1}}
-
-%D \macros
-%D {gobbleoneargument,gobble...arguments}
-%D
-%D The next set of macros just do nothing, except that they get rid of a number of
-%D arguments. These zero references prevent intermediate storage. In principle that
-%D is more efficient but it probably won't be noticed. It's anyway cheaper on memory
-%D access. We use versions that don't even store the arguments.
-
-%permanent\def\gobbleoneargument #-{}
-\permanent\def\gobbletwoarguments #-#-{}
-\permanent\def\gobblethreearguments #-#-#-{}
-\permanent\def\gobblefourarguments #-#-#-#-{}
-\permanent\def\gobblefivearguments #-#-#-#-{}
-\permanent\def\gobblesixarguments #-#-#-#-{}
-\permanent\def\gobblesevenarguments #-#-#-#-#-{}
-\permanent\def\gobbleeightarguments #-#-#-#-#-#-{}
-\permanent\def\gobbleninearguments #-#-#-#-#-#-#-{}
-
-\permanent\tolerant\def\gobbleoneoptional [#-]{}
-\permanent\tolerant\def\gobbletwooptionals [#-]#*[#-]{}
-\permanent\tolerant\def\gobblethreeoptionals[#-]#*[#-]#*[#-]{}
-\permanent\tolerant\def\gobblefouroptionals [#-]#*[#-]#*[#-]#*[#-]{}
-\permanent\tolerant\def\gobblefiveoptionals [#-]#*[#-]#*[#-]#*[#-]#*[#-]{}
-
-%D Reserved macros for tests:
-
-\aliased\let\donothing\empty
-
-\let\m_syst_string_one \empty
-\let\m_syst_string_two \empty
-\let\m_syst_string_three\empty
-\let\m_syst_string_four \empty
-
-\let\m_syst_action_yes \empty
-\let\m_syst_action_nop \empty
-
-%D \macros
-%D {doifnextcharelse}
-%D
-%D This macro has a long history. Among the things we had to deal with was ignoring
-%D blank spaces but in the meantime we can use some \LUATEX\ trickery. Older versions
-%D use more code and can be find in the \MKIV\ and \MKII\ files.
-
-% \mutable\let\next \relax
-% \mutable\let\nextnext \relax % kind of obsolete
-% \mutable\let\nextnextnext \relax % kind of obsolete
-% \mutable\let\nexttoken \relax
-
-\permanent\protected\def\doifelsenextchar#1#2#3% #1 should not be {} !
- {\def\m_syst_action_yes{#2}%
- \def\m_syst_action_nop{#3}%
- \futureexpandis#1\m_syst_action_yes\m_syst_action_nop}
-
-\permanent\protected\def\doifelsenextcharcs % #1#2#3% #1 should not be {} !
- {\futureexpandis}
-
-\aliased\let\doifnextcharelse \doifelsenextchar
-\aliased\let\doifnextcharcselse\doifelsenextcharcs
-
-%D Because we will mostly use this macro for testing if the next character is \type
-%D {[}, we also make a slightly faster variant as it is not uncommon to have tens of
-%D thousands of calls to this test in a run. Of course it also is more convenient to
-%D read a trace then. Here we use a lookahead primitive that ignores (blank) spaces
-%D which makes for less tracing clutter than the original definition. It's also
-%D faster bit that will probably go unnoticed. Of course, hard||core \TEX ies whose
-%D reputations depends on understanding obscure macro definitions will love the more
-%D low level variants.
-
-\permanent\protected\def\doifelsenextoptional#1#2%
- {\def\m_syst_action_yes{#1}%
- \def\m_syst_action_nop{#2}%
- \futureexpandis[\m_syst_action_yes\m_syst_action_nop}
-
-\permanent\protected\def\doifelsenextoptionalcs
- {\futureexpandis[}
-
-\aliased\let\doifnextoptionalelse \doifelsenextoptional
-\aliased\let\doifnextoptionalcselse\doifelsenextoptionalcs
-
-\permanent\protected\def\doifelsenextbgroup#1#2%
- {\def\m_syst_action_yes{#1}%
- \def\m_syst_action_nop{#2}%
- \futureexpandis\bgroup\m_syst_action_yes\m_syst_action_nop}
-
-\permanent\protected\def\doifelsenextbgroupcs % #1#2
- {\futureexpandis\bgroup}
-
-\aliased\let\doifnextbgroupelse \doifelsenextbgroup
-\aliased\let\doifnextbgroupcselse\doifelsenextbgroupcs
-
-\permanent\protected\def\doifelsenextparenthesis#1#2%
- {\def\m_syst_action_yes{#1}%
- \def\m_syst_action_nop{#2}%
- \futureexpandis(\m_syst_action_yes\m_syst_action_nop}
-
-\aliased\let\doifnextparenthesiselse\doifelsenextparenthesis
-
-%D The next one is handy in predictable situations:
-
-\def\syst_helpers_do_if_fast_optional_check_else
- {\ifx\nexttoken\syst_helpers_next_optional_character_token
- \expandafter\m_syst_action_yes
- \else
- \expandafter\m_syst_action_nop
- \fi}
-
-\permanent\protected\def\doifelsefastoptionalcheck#1#2%
- {\def\m_syst_action_yes{#1}%
- \def\m_syst_action_nop{#2}%
- \futureexpandis[\m_syst_action_yes\m_syst_action_nop}
-
-\permanent\protected\def\doifelsefastoptionalcheckcs
- {\futureexpandis[}
-
-\aliased\let\doiffastoptionalcheckelse \doifelsefastoptionalcheck
-\aliased\let\doiffastoptionalcheckcselse\doifelsefastoptionalcheckcs
-
-%D Here's one for skipping spaces and pars, handy for:
-%D
-%D \starttyping
-%D \hbox
-%D
-%D {a few lines later}
-%D \stoptyping
-%D
-%D like:
-%D
-%D \starttyping
-%D \def\somecommand{\dowithnextbox{\box\nextbox}\ruledhbox}
-%D
-%D \assumelongusagecs\somecommand
-%D
-%D \bgroup
-%D oeps
-%D \egroup
-%D \stoptyping
-%D
-%D The original kind of clumsy but working version is now replaced by a simple
-%D macro. And it can be even less code in \LUAMETATEX:
-
-\aliased\let\assumelongusagecs\expandafterpars % so we can replace it
-
-%D It's used to skip over empty lines in some constructs that we like to set up
-%D spacy. We already permit par tokens (and equivalents) in math and some other
-%D places visa engine features. And, \type {\long} stuff has been dropped for a long
-%D time already (it is still optional in \lUATEX). But the \quote {long} in the
-%D name kind of stuck.
-
-%D \macros
-%D {blankspace}
-%D
-%D Here is how this works. The \type {\let} primitive first picks up the to be let
-%D name. Then it scans for an optional equal and when that is found it will skip the
-%D next space, which is why we need an extra one to achieve our goal. Such a \type
-%D {\blankspace} has the meaning \typ {blank space}. A typical \TEX ie definition:
-
-\normalexpanded{\permanent\let\noexpand\blankspace=\space\space}
-
-%D \macros
-%D {setvalue,setgvalue,setevalue,setxvalue,
-%D letvalue,letgvalue,getvalue,resetvalue,
-%D undefinevalue,ignorevalue}
-%D
-%D \TEX's primitive \type {\csname} can be used to construct all kind of commands
-%D that cannot be defined with \type {\def} and \type {\let}. Every macro programmer
-%D sooner or later wants macros like these.
-%D
-%D \starttyping
-%D \setvalue {name}{...} = \def\name{...}
-%D \setgvalue {name}{...} = \gdef\name{...}
-%D \setevalue {name}{...} = \edef\name{...}
-%D \setxvalue {name}{...} = \xdef\name{...}
-%D \letvalue {name}=\... = \let\name=\...
-%D \letgvalue {name}=\... = \glet\name=\...
-%D \getvalue {name} = \name
-%D \resetvalue {name} = \def\name{}
-%D \stoptyping
-%D
-%D As we will see, \CONTEXT\ uses these commands many times, which is mainly due to
-%D its object oriented and parameter driven character.
-
-\permanent\def\setvalue #1{\expandafter\defcsname#1\endcsname}
-\permanent\def\setgvalue #1{\global\defcsname#1\endcsname}
-\permanent\def\setevalue #1{\edefcsname#1\endcsname}
-\permanent\def\setxvalue #1{\global\edefcsname#1\endcsname}
-\permanent\def\getvalue #1{\csname#1\endcsname} % maybe: \begincsname#1\endcsname
-\permanent\def\letvalue #1{\letcsname#1\endcsname}
-\permanent\def\letgvalue #1{\global\letcsname#1\endcsname}
-\permanent\def\resetvalue #1{\letcsname#1\endcsname\empty}
-\permanent\def\undefinevalue#1{\letcsname#1\endcsname\undefined}
-\permanent\def\ignorevalue#1#2{\letcsname#1\endcsname\empty}
-
-\permanent\def\setuvalue #1{\protected\defcsname#1\endcsname}
-\permanent\def\setuevalue #1{\protected\edefcsname#1\endcsname}
-\permanent\def\setugvalue #1{\protected\global\defcsname#1\endcsname}
-\permanent\def\setuxvalue #1{\protected\global\edefcsname#1\endcsname}
-
-\permanent\protected\def\getuvalue#1{\csname#1\endcsname}
-
-%D \macros
-%D {globallet,glet}
-%D
-%D In \CONTEXT\ of May 2000 using \type {\globallet} instead of the two tokens will
-%D save us some $300\times4=1200$ bytes of format file on a 32~bit system. Not that
-%D it matters much today. But nowadays we can just alias to a primitive:
-
-\aliased\let\globallet\glet
-
-%D \macros
-%D {doifundefined,doifdefined,
-%D doifundefinedelse,doifdefinedelse,
-%D doifalldefinedelse}
-%D
-%D The standard way of testing if a macro is defined is comparing its meaning with
-%D another undefined one, usually \type {\undefined}. To garantee correct working of
-%D the next set of macros, \type {\undefined} may never be defined!
-%D
-%D \starttyping
-%D \doifundefined {string} {...}
-%D \doifdefined {string} {...}
-%D \doifundefinedelse {string} {then ...} {else ...}
-%D \doifdefinedelse {string} {then ...} {else ...}
-%D \doifalldefinedelse {commalist} {then ...} {else ...}
-%D \stoptyping
-%D
-%D Every macroname that \TEX\ builds gets an entry in the hash table, which is of
-%D limited size. It is expected that \ETEX\ will offer a less memory||consuming
-%D alternative.
-%D
-%D Although it will probably never be a big problem, it is good to be aware of the
-%D difference between testing on a macro name to be build by using \type {\csname} and
-%D \type {\endcsname} and testing the \type {\name} directly.
-%D
-%D \starttyping
-%D \expandafter\ifx\csname NameA\endcsname\relax ... \else ... \fi
-%D
-%D \ifundefined\NameB ... \else ... \fi
-%D \stoptyping
-%D
-%D Suppression of errors while constructing a control sequence is one of the (few)
-%D things that I remember being discussed in the perspective of \ETEX\ but it was
-%D rejected because it was not considered useful. Well, in \LUATEX\ we can surpress
-%D it and that is what we do in \MKIV. We're probably the only macro package that
-%D needs it. That kind of configuration happens elsewhere. These macros are (mostly
-%D for historic reasons) fully expandable.
-
-\permanent\def\doifelseundefined#1%
- {\ifcsname#1\endcsname
- \expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments
- \fi}
-
-\permanent\def\doifelsedefined#1%
- {\ifcsname#1\endcsname
- \expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments
- \fi}
-
-\permanent\def\doifundefined#1%
- {\ifcsname#1\endcsname
- \expandafter\gobbleoneargument\else\expandafter\firstofoneargument
- \fi}
-
-\permanent\def\doifdefined#1%
- {\ifcsname#1\endcsname
- \expandafter\firstofoneargument\else\expandafter\gobbleoneargument
- \fi}
-
-\aliased\let\doifundefinedelse\doifelseundefined
-\aliased\let\doifdefinedelse \doifelsedefined
-
-%D \macros
-%D {letbeundefined}
-%D
-%D Testing for being undefined comes down to testing on \type {\relax} when we use
-%D \type {\csname}, but when using \type {\ifx}, we test on being \type
-%D {\undefined}! In \ETEX\ we have \type {\ifcsname} and that way of testing on
-%D existance is not the same as the one described here. Therefore we introduce:
-
-\permanent\protected\def\letbeundefined#1%
- {\letcsname#1\endcsname\undefined} % or use \undefinevalue to match \setvalue
-
-\permanent\protected\def\localundefine#1% conditional
- {\ifcsname#1\endcsname\letcsname#1\endcsname\undefined\fi}
-
-\permanent\protected\def\globalundefine#1% conditional
- {\ifcsname#1\endcsname\global\letcsname#1\endcsname\undefined\fi}
-
-%D Beware, being \type {\undefined} in \ETEX\ means that the macro {\em is} defined!
-%D
-%D When we were developing the scientific units module, we encountered different
-%D behavior in text and math mode, which was due to this grouping subtilities. We
-%D therefore decided to use \type {\begingroup} instead of \type {\bgroup}.
-
-\permanent\protected\def\doifelsealldefined#1%
- {\begingroup
- \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}
-
-\aliased\let\doifalldefinedelse\doifelsealldefined
-
-\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
-%D Programming in \TEX\ differs from programming in procedural languages like
-%D \MODULA. This means that one --- well, let me speek for myself --- tries to do
-%D the things in the well known way. Therefore the next set of \type {ifthenelse}
-%D commands were between the first ones we needed. A few years later, the opposite
-%D became true: when programming in \MODULA, I sometimes miss handy things like
-%D grouping, runtime redefinition, expansion etc. While \MODULA\ taught me to
-%D structure, \TEX\ taught me to think recursive.
-%D
-%D \starttyping
-%D \doif {string1} {string2} {...}
-%D \doifnot {string1} {string2} {...}
-%D \doifelse {string1} {string2} {then ...}{else ...}
-%D \stoptyping
-%D
-%D Again, we use some of the new primitives in \LUAMETATEX. Using straightforward
-%D \type {\edef}'s and \type {\ifx} comparison works as well, but this saves tokens
-%D and, more important, tracing clutter.
-
-\permanent\protected\def\doifelse#1#2%
- {\iftok{#1}{#2}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\permanent\protected\def\doif#1#2%
- {\iftok{#1}{#2}%
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\doifnot#1#2%
- {\iftok{#1}{#2}%
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-%D \macros
-%D {doifempty,doifemptyelse,doifnotempty}
-%D
-%D We complete our set of conditionals with:
-%D
-%D \starttyping
-%D \doifempty {string} {...}
-%D \doifnotempty {string} {...}
-%D \doifemptyelse {string} {then ...} {else ...}
-%D \stoptyping
-%D
-%D This time, the string is not expanded, but we use the dedicated empty checker
-%D here.
-
-\permanent\protected\def\doifelseempty#1%
- {\def\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifemptyelse\doifelseempty
-
-\permanent\protected\def\doifempty#1%
- {\def\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\doifnotempty#1%
- {\def\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-%D \macros
-%D {doifinset,doifnotinset,doifinsetelse}
-%D
-%D We can check if a string is present in a comma separated set of strings.
-%D Depending on the result, some action is taken.
-%D
-%D \starttyping
-%D \doifinset {string} {string,...} {...}
-%D \doifnotinset {string} {string,...} {...}
-%D \doifinsetelse {string} {string,...} {then ...} {else ...}
-%D \stoptyping
-
-% !0nop=\doifinsetelse{ccc}{,}{yes}{nop}
-% !0nop=\doifinsetelse{ccc}{,,}{yes}{nop}
-% !0nop=\doifinsetelse{ccc}{,,,}{yes}{nop}
-
-% !1nop=\doifinsetelse{}{}{yes}{nop}
-% !2yes=\doifinsetelse{aaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop}
-% !3nop=\doifinsetelse{aaa}{bbb}{yes}{nop}
-% !4yes=\doifinsetelse{aaa}{aaa}{yes}{nop}
-% !5nop=\doifinsetelse{aaaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop}
-% !6nop=\doifinsetelse{}{}{yes}{nop}
-% !7nop=\doifinsetelse{}{aaa}{yes}{nop}
-% !8nop=\doifinsetelse{aaa}{}{yes}{nop}
-
-% !1=\doifinset{}{}{yes}
-% !2yes=\doifinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes}
-% !3=\doifinset{aaa}{bbb}{yes}
-% !4yes=\doifinset{aaa}{aaa}{yes}
-% !5=\doifinset{}{}{yes}
-% !6=\doifinset{aaa}{}{yes}
-
-% !1yes=\doifnotinset{}{}{yes}
-% !2=\doifnotinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes}
-% !3yes=\doifnotinset{aaa}{bbb}{yes}
-% !4=\doifnotinset{aaa}{aaa}{yes}
-% !5yes=\doifnotinset{}{}{yes}
-% !6yes=\doifnotinset{aaa}{}{yes}
-
-%D These are normally only used for keywords, i.e.\ strings so we can delegate
-%D the work to \LUA:
-
-%unexpanded\def\doifelseinset#1#2{\clf_doifelseinset{#1}{#2}}
-%unexpanded\def\doifinset #1#2{\clf_doifinset {#1}{#2}}
-%unexpanded\def\doifnotinset #1#2{\clf_doifnotinset {#1}{#2}}
-% % \let\firstinset \clf_firstinset
-
-% These don't accept spaces after commas:
-%
-% \protected\def\doifelseinset#1#2%
-% {\ifhasxtoks{,#1,}{,#2,}%
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-
-% \protected\def\doifinset#1#2%
-% {\ifhasxtoks{,#1,}{,#2,}%
-% \expandafter\firstofoneargument
-% \else
-% \expandafter\gobbleoneargument
-% \fi}
-
-% \protected\def\doifnotinset#1#2%
-% {\ifhasxtoks{,#1,}{,#2,}%
-% \expandafter\gobbleoneargument
-% \else
-% \expandafter\firstofoneargument
-% \fi}
-
-% But these do:
-
-\immutable\edef\a!comma{\expandtoken \ignorecatcode \commaasciicode}
-\immutable\edef\a!space{\expandtoken \ignorecatcode \spaceasciicode}
-
-\normalexpanded {
-
- \permanent \protected \def \noexpand \doifelseinset#1#2%
- {\noexpand\ifhasxtoks{,\a!space#1,}{,#2,}%
- \noexpand\expandafter\noexpand\firstoftwoarguments
- \noexpand\else
- \noexpand\expandafter\noexpand\secondoftwoarguments
- \noexpand\fi}
-
- \permanent \protected \def \noexpand \doifinset#1#2%
- {\noexpand\ifhasxtoks{,\a!space#1,}{,#2,}%
- \noexpand\expandafter\noexpand\firstofoneargument
- \noexpand\else
- \noexpand\expandafter\noexpand\gobbleoneargument
- \noexpand\fi}
-
- \permanent \protected \def \noexpand \doifnotinset#1#2%
- {\noexpand\ifhasxtoks{,\a!space#1,}{,#2,}%
- \noexpand\expandafter\noexpand\gobbleoneargument
- \noexpand\else
- \noexpand\expandafter\noexpand\firstofoneargument
- \noexpand\fi}
-
-}
-
-%D Done.
-
-\aliased\let\doifinsetelse\doifelseinset
-
-%D \macros
-%D {doifcommon,doifnotcommon,doifcommonelse}
-%D
-%D Probably the most time consuming tests are those that test for overlap in sets
-%D of strings.
-%D
-%D \starttyping
-%D \doifcommon {string,...} {string,...} {...}
-%D \doifnotcommon {string,...} {string,...} {...}
-%D \doifcommonelse {string,...} {string,...} {then ...} {else ...}
-%D \stoptyping
-
-% !1yes=\doifcommonelse{aaa,bbb,ccc}{aaa,bbb,ccc}{yes}{nop}
-% !2nop=\doifcommonelse{aaa,bbb,ccc}{ddd,eee,fff}{yes}{nop}
-% !3nop=\doifcommonelse{aaa}{ddd,eee,fff}{yes}{nop}
-% !4yes=\doifcommonelse{aaa}{aaa}{yes}{nop}
-% !5nop=\doifcommonelse{bbb}{aaa}{yes}{nop}
-% !6nop=\doifcommonelse{}{aaa,bbb,ccc}{yes}{nop}
-% !7nop=\doifcommonelse{aaa,bbb,ccc}{}{yes}{nop}
-% !8nop=\doifcommonelse{}{}{yes}{nop}
-
-% !9nop=\doifcommonelse{,,}{,,}{yes}{nop}
-% !9yes=\doifcommonelse{,a,}{,a,}{yes}{nop}
-% !9yes=\doifcommonelse{,,a,}{,a,}{yes}{nop}
-% !9yes=\doifcommonelse{,a,}{,,a,}{yes}{nop}
-% !9yes=\doifcommonelse{,a,}{,,,a,}{yes}{nop}
-% !9yes=\doifcommonelse{,,a,}{,,,a,}{yes}{nop}
-
-\permanent\protected\def\doifelsecommon#1#2{\clf_doifelsecommon{#1}{#2}} % todo: define in lua
-\permanent\protected\def\doifcommon #1#2{\clf_doifcommon {#1}{#2}} % todo: define in lua
-\permanent\protected\def\doifnotcommon #1#2{\clf_doifnotcommon {#1}{#2}} % todo: define in lua
-
-\aliased\let\doifcommonelse\doifelsecommon
-
-%D \macros
-%D {processcommalist,processcommacommand,quitcommalist,
-%D processcommalistwithparameters}
-%D
-%D We've already seen some macros that take care of comma separated lists. Such
-%D list can be processed with
-%D
-%D \starttyping
-%D \processcommalist[string,string,...]\commando
-%D \stoptyping
-%D
-%D The user supplied command \type{\commando} receives one argument: the string.
-%D This command permits nesting and spaces after commas are skipped. Empty sets
-%D are no problem.
-%D
-%D \startbuffer
-%D \def\dosomething#1{(#1)}
-%D
-%D 1: \processcommalist [\hbox{$a,b,c,d,e,f$}] \dosomething \par
-%D 2: \processcommalist [{a,b,c,d,e,f}] \dosomething \par
-%D 3: \processcommalist [{a,b,c},d,e,f] \dosomething \par
-%D 4: \processcommalist [a,b,{c,d,e},f] \dosomething \par
-%D 5: \processcommalist [a{b,c},d,e,f] \dosomething \par
-%D 6: \processcommalist [{a,b}c,d,e,f] \dosomething \par
-%D 7: \processcommalist [] \dosomething \par
-%D 8: \processcommalist [{[}] \dosomething \par
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Or expanded:
-%D
-%D \blank \getbuffer \blank
-%D
-%D The original definitions can be found elsewhere and need a bit more code. In case of
-%D issues, consult the \MKIV\ variant or previous \LMTX\ variants in the repository.
-%D
-%D When a list is saved in a macro, we can use a construction like:
-%D
-%D \starttyping
-%D \expandafter\processcommalist\expandafter[\list]\command
-%D \stoptyping
-%D
-%D Such solutions suit most situations, but we wanted a bit more.
-%D
-%D \starttyping
-%D \processcommacommand[string,\stringset,string]\commando
-%D \stoptyping
-%D
-%D where \type{\stringset} is a predefined set, like:
-%D
-%D \starttyping
-%D \def\first{aap,noot,mies}
-%D \def\second{laatste}
-%D
-%D \processcommacommand[\first]\message
-%D \processcommacommand[\first,second,third]\message
-%D \processcommacommand[\first,between,\second]\message
-%D \stoptyping
-%D
-%D Commands that are part of the list are expanded, so the use of this macro has its
-%D limits. We use a new \LUAMETATEX\ feature that intercepts invalid macro arguments
-%D by quitting when \type {\ignorearguments} is seen. That's why we act on the
-%D arguments state. Again it permits leaner and meaner macro definitions with a bit
-%D less clutter in tracing.
-
-\let\commalistcommand\empty
-
-\protected\def\syst_helpers_process_comma_item#+,%
- {\ifarguments
- \expandafter\syst_helpers_process_comma_item_gobble
- \orelse\ifparameter#1\or
- \commalistcommand{#1}%
- \expandafter\syst_helpers_process_comma_item_next
- \else
- \expandafter\syst_helpers_process_comma_item_gobble
- \fi}
-
-% \def\syst_helpers_process_comma_item_next
-% {\expandafterspaces\syst_helpers_process_comma_item}
-
-% \protected\def\processcommalist[#1]#2%
-% {\pushmacro\commalistcommand
-% \def\commalistcommand{#2}%
-% \expandafterspaces\syst_helpers_process_comma_item#1,\ignorearguments\ignorearguments\ignorearguments
-% \popmacro\commalistcommand}
-
-% \protected\def\processcommacommand[#1]#2%
-% {\pushmacro\commalistcommand
-% \def\commalistcommand{#2}%
-% \normalexpanded{\noexpand\expandafterspaces\syst_helpers_process_comma_item#1,}\ignorearguments\ignorearguments\ignorearguments
-% \popmacro\commalistcommand}
-
-% \permanent\protected\def\processcommalist[#*#+]#2%
-% {\pushmacro\commalistcommand
-% \def\commalistcommand{#2}%
-% \expandafterspaces\syst_helpers_process_comma_item#1,\ignorearguments\ignorearguments\ignorearguments
-% \popmacro\commalistcommand}
-%
-% \permanent\protected\def\processcommacommand[#*#+]#2%
-% {\pushmacro\commalistcommand
-% \def\commalistcommand{#2}%
-% \normalexpanded{\noexpand\expandafterspaces\syst_helpers_process_comma_item#1,}\ignorearguments\ignorearguments\ignorearguments
-% \popmacro\commalistcommand}
-
-\tolerant\protected\def\syst_helpers_process_comma_item#*#1,%
- {\ifarguments\or
- \commalistcommand{#1}%
- \expandafter\syst_helpers_process_comma_item_next
- \fi}
-
-\def\syst_helpers_process_comma_item_next
- {\expandafterspaces\syst_helpers_process_comma_item}
-
-\permanent\protected\def\processcommalist[#1]#2%
- {\pushmacro\commalistcommand
- \def\commalistcommand{#2}%
- \syst_helpers_process_comma_item#1\ignorearguments\ignorearguments\ignorearguments
- \popmacro\commalistcommand}
-
-\permanent\protected\def\processcommacommand[#1]#2%
- {\pushmacro\commalistcommand
- \def\commalistcommand{#2}%
- \normalexpanded{\syst_helpers_process_comma_item#1}\ignorearguments\ignorearguments\ignorearguments
- \popmacro\commalistcommand}
-
-% \let\syst_helpers_process_comma_item_next_a \syst_helpers_process_comma_item_next
-% \def\syst_helpers_process_comma_item_next_b#0\ignorearguments{\let\syst_helpers_process_comma_item_next\syst_helpers_process_comma_item_next_a}
-% \def\syst_helpers_process_comma_item_next_c#0\ignorearguments{\let\syst_helpers_process_comma_item_next\syst_helpers_process_comma_item_next_b}
-% \def\syst_helpers_process_comma_item_gobble#0\ignorearguments{}
-
-\let\syst_helpers_process_comma_item_next_a \syst_helpers_process_comma_item_next
-\def\syst_helpers_process_comma_item_next_b#-\ignorearguments{\let\syst_helpers_process_comma_item_next\syst_helpers_process_comma_item_next_a}
-\def\syst_helpers_process_comma_item_next_c#-\ignorearguments{\let\syst_helpers_process_comma_item_next\syst_helpers_process_comma_item_next_b}
-\def\syst_helpers_process_comma_item_gobble#-\ignorearguments{}
-
-\permanent\protected\def\quitcommalist {\let\syst_helpers_process_comma_item_next\syst_helpers_process_comma_item_next_b}
-\permanent\protected\def\quitprevcommalist{\let\syst_helpers_process_comma_item_next\syst_helpers_process_comma_item_next_c}
-
-%D \startbuffer
-%D \def\foo#1{(#1)}
-%D <\processcommalist[a,b,c,d]\foo>
-%D
-%D \def\foo#1{(#1)}
-%D \def\oof#1{<\processcommalist[#1]\foo>}
-%D <\processcommalist[{a,b},{c,d}]\oof>
-%D
-%D \def\foo#1{(#1)\quitcommalist}
-%D <\processcommalist[a,b,c,d]\foo>
-%D
-%D \def\foo#1{(#1)}
-%D \def\oof#1{<\processcommalist[#1]\foo\quitcommalist>}
-%D <\processcommalist[{a,b},{c,d}]\oof>
-%D
-%D \def\foo#1{(#1)\quitcommalist}
-%D \def\oof#1{<\processcommalist[#1]\foo>}
-%D <\processcommalist[{a,b},{c,d},{e,f}]\oof>
-%D
-%D \def\foo#1{(#1)\quitprevcommalist}
-%D \def\oof#1{<\processcommalist[#1]\foo>}
-%D <\processcommalist[{a,b},{c,d},{e,f}]\oof>
-%D \stopbuffer
-%D
-%D \typebuffer \blank \getbuffer \blank
-
-%D The argument to \type{\command} is not delimited. Because we often use \type {[]}
-%D as delimiters, we also have:
-%D
-%D \starttyping
-%D \processcommalistwithparameters[string,string,...]\command
-%D \stoptyping
-%D
-%D where \type{\command} looks like:
-%D
-%D \starttyping
-%D \def\command[#1]{... #1 ...}
-%D \stoptyping
-
-\permanent\protected\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:
-
-\let\syst_helpers_comma_list_step\relax
-
-\permanent\protected\def\startprocesscommalist[#1]#2\stopprocesscommalist
- {\def\syst_helpers_comma_list_step##1{\def\currentcommalistitem{##1}#2}%
- \processcommalist[#1]\syst_helpers_comma_list_step}
-
-\permanent\protected\def\startprocesscommacommand[#1]#2\stopprocesscommacommand
- {\def\syst_helpers_comma_list_step##1{\def\currentcommalistitem{##1}#2}%
- \normalexpanded{\processcommalist[#1]}\syst_helpers_comma_list_step}
-
-\aliased\let\stopprocesscommalist \relax
-\aliased\let\stopprocesscommacommand\relax
-
-%D \macros
-%D {processaction,
-%D processfirstactioninset,
-%D processallactionsinset}
-%D
-%D \CONTEXT\ makes extensive use of a sort of case or switch command. Depending of
-%D the presence of one or more provided items, some actions is taken. These macros
-%D can be nested without problems.
-%D
-%D \starttyping
-%D \processaction [x] [x=>a,y=>b,z=>c]
-%D \processfirstactioninset [x,y,z] [x=>a,y=>b,z=>c]
-%D \processallactionsinset [x,y,z] [x=>a,y=>b,z=>c]
-%D \stoptyping
-%D
-%D We can supply both a \type {default} action and an action to be undertaken when
-%D an \type {unknown} value is met:
-%D
-%D \starttyping
-%D \processallactionsinset
-%D [x,y,z]
-%D [ a=>\a,
-%D b=>\b,
-%D c=>\c,
-%D default=>\default,
-%D unknown=>\unknown{... \commalistelement ...}]
-%D \stoptyping
-%D
-%D When \type {#1} is empty, this macro scans list \type {#2} for the keyword \type
-%D {default} and executed the related action if present. When \type {#1} is non
-%D empty and not in the list, the action related to \type {unknown} is executed.
-%D Both keywords must be at the end of list \type{#2}. Afterwards, the actually
-%D found keyword is available in \type {\commalistelement}. An advanced example of
-%D the use of this macro can be found in \PPCHTEX, where we completely rely on \TEX\
-%D for interpreting user supplied keywords like \type {SB}, \type {SB1..6}, \type
-%D {SB125} etc.
-%D
-%D In the meantime we follow a different approach, often somewhat more heavy on the
-%D number of control sequences used, but that is no lomger a real issue. The code
-%D has been simplified and nwo uses the macro stack mechanism. If needed I can make
-%D this more hip and a bit faster now but \unknown\ it's seldom used nowadays as we
-%D have better ways now.
-
-\protected\def\syst_helpers_do_compare_process_action_a[#1=>#2][#3]%
- {\edef\m_syst_string_two{#1}%
- \ifx\m_syst_string_two\s!default
- \let\commalistelement\empty
- #2%
- \fi}
-
-\protected\def\syst_helpers_do_compare_process_action_b[#1=>#2][#3]%
- {\edef\m_syst_string_two{#1}%
- \ifx\m_syst_string_one\m_syst_string_two
- \def\commalistelement{#3}%
- #2%
- \expandafter\quitcommalist
- \orelse\ifx\m_syst_string_two\s!unknown
- \def\commalistelement{#3}% beware of loops
- #2%
- \fi}
-
-\permanent\protected\def\processaction[#1]#2[%
- {\edef\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \let\syst_helpers_do_compare_process_action\syst_helpers_do_compare_process_action_a
- \else
- \let\syst_helpers_do_compare_process_action\syst_helpers_do_compare_process_action_b
- \fi
- \edef\syst_helpers_do_process_action##1{\syst_helpers_do_compare_process_action[##1][#1]}% expands #1
- \processnextcommalist\syst_helpers_do_process_action[}
-
-\protected\def\syst_helpers_do_compare_process_action_c[#1=>#2][#3]%
- {\edef\m_syst_string_one{#1}%
- \edef\m_syst_string_two{#3}%
- \ifx\m_syst_string_one\m_syst_string_two
- \def\commalistelement{#3}%
- #2%
- \expandafter\quitprevcommalist
- \else
- \edef\m_syst_string_one{#1}%
- \ifx\m_syst_string_one\s!unknown
- \def\commalistelement{#3}%
- #2%
- \fi
- \fi}
-
-\permanent\protected\def\processfirstactioninset[#1]%
- {\edef\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \expandafter\processaction
- \else
- \expandafter\syst_helpers_process_first_action_in_set_indeed
- \fi
- [#1]}
-
-\tolerant\protected\def\syst_helpers_process_first_action_in_set_indeed[#1]#*[#2]%
- {\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[#2]\syst_helpers_do_do_process_action}%
- \normalexpanded{\processcommalist[#1]}\syst_helpers_do_process_action}
-
-\protected\def\syst_helpers_do_compare_process_action_d[#1=>#2][#3]%
- {\edef\m_syst_string_one{#1}%
- \edef\m_syst_string_two{#3}%
- \ifx\m_syst_string_one\m_syst_string_two
- \def\commalistelement{#3}%
- #2%
- \expandafter\quitcommalist
- \else
- \edef\m_syst_string_one{#1}%
- \ifx\m_syst_string_one\s!unknown
- \def\commalistelement{#3}%
- #2%
- \fi
- \fi}
-
-\tolerant\protected\def\syst_helpers_process_all_actions_in_set_indeed[#1]#*[#2]%
- {\globalpushmacro\syst_process_action_in_set_all
- \def\syst_process_action_in_set##1%
- {\def\syst_process_action_in_set_one####1{\syst_helpers_do_compare_process_action_d[####1][##1]}%
- \processcommalist[#2]\syst_process_action_in_set_one}%
- \processcommacommand[#1]\syst_process_action_in_set
- \globalpopmacro\syst_process_action_in_set_all}
-
-\permanent\protected\def\processallactionsinset[#1]%
- {\edef\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \expandafter\processaction
- \else
- \expandafter\syst_helpers_process_all_actions_in_set_indeed
- \fi[#1]}
-
-%D These macros use:
-
-% \protected\def\processnextcommalist#1[#2#3]%
-% {\pushmacro\commalistcommand
-% \def\commalistcommand{#1}%
-% \expandafterspaces\syst_helpers_process_comma_item#2#3\ignorearguments\ignorearguments\ignorearguments
-% \popmacro\commalistcommand}
-
-\permanent\protected\def\processnextcommalist#1[#2#3]%
- {\pushmacro\commalistcommand
- \def\commalistcommand{#1}%
- \expandafterspaces\syst_helpers_process_comma_item#2#3\ignorearguments\ignorearguments\ignorearguments
- \popmacro\commalistcommand}
-
-%D \macros
-%D {getfirstcharacter, firstcharacter, remainingcharacters, doiffirstcharacter}
-%D
-%D Sometimes the action to be undertaken depends on the next character. This macro
-%D get this character and puts it in \type {\firstcharacter}.
-%D
-%D \starttyping
-%D \getfirstcharacter {string}
-%D \stoptyping
-%D
-%D A two step expansion is used to prevent problems with complicated arguments, for
-%D instance arguments that consist of two or more expandable tokens.
-
-\let\firstcharacter \empty
-\let\remainingcharacters\empty
-
-\permanent\protected\def\getfirstcharacter #1{\clf_getfirstcharacter{#1}}
-\permanent\protected\def\doifelsefirstchar #1#2{\clf_doifelsefirstchar{#1}{#2}}
-\permanent\protected\def\thefirstcharacter #1{\clf_thefirstcharacter{#1}}
-\permanent\protected\def\theremainingcharacters#1{\clf_theremainingcharacters{#1}}
-
-\aliased\let\doiffirstcharelse\doifelsefirstchar
-
-%D \macros
-%D {doifinstringelse, doifincsnameelse}
-%D
-%D We can check for the presence of a substring in a given sequence of characters.
-%D
-%D \starttyping
-%D \doifinstringelse {substring} {string} {then ...} {else ...}
-%D \stoptyping
-%D
-%D \startbuffer
-%D \doifinstringelse{abc}{foo bar abc}{Y}{N}=Y\par
-%D \doifinstringelse{abc}{foo bar cab}{Y}{N}=N\par
-%D \doifinstring {abc}{foo bar abc}{Y}=Y\par
-%D \doifinstring {abc}{foo bar cab}{Y}\par
-%D \doifnotinstring {abc}{foo bar abc}{Y}\par
-%D \doifnotinstring {abc}{foo bar cab}{Y}=Y\par
-%D \doifinstringelse{}{foo bar abc}{Y}{N}=N\par
-%D \doifinstring {}{foo bar abc}{N}\par
-%D \doifnotinstring {}{foo bar abc}{Y}=Y\par
-%D \doifinstringelse{x}{}{Y}{N}=N\par
-%D \doifinstring {x}{}{N}\par
-%D \doifnotinstring {x}{}{Y}=Y\par
-%D \doifinstringelse{}{}{Y}{N}=N\par
-%D \doifinstring {}{}{N}\par
-%D \doifnotinstring {}{}{Y}=Y\par
-%D \stopbuffer
-%D
-%D \typebuffer \blank \getbuffer \blank
-
-%D I keep the following as example code:
-
-% \let\syst_helpers_do_do_if_in_string_else\relax
-% \let\syst_helpers_do_do_if_in_string \relax
-% \let\syst_helpers_do_do_if_not_in_string \relax
-%
-% \let\m_syst_sub_string \empty
-%
-% \protected\def\doifelseinstring#1%
-% {\edef\m_syst_sub_string{#1}% expand #1 here
-% \ifempty\m_syst_sub_string
-% \expandafter\thirdofthreearguments
-% \else
-% \expandafter\syst_helpers_do_if_in_string_else
-% \fi}
-%
-% \let\doifinstringelse\doifelseinstring
-%
-% \protected\def\syst_helpers_do_if_in_string_else#1% ##2 can be {abc}
-% {\normalexpanded{\protected\def\syst_helpers_do_do_if_in_string_else##1\m_syst_sub_string##2}%
-% {\ifarguments
-% \or
-% \expandafter\syst_helpers_do_if_in_string_else_nop
-% \or
-% \expandafter\syst_helpers_do_if_in_string_else_yes
-% \fi}%
-% \normalexpanded{\syst_helpers_do_do_if_in_string_else#1}\e_o_t\ignorearguments\ignorearguments}
-%
-% \protected\def\syst_helpers_do_if_in_string_else_delimited#1% ##2 can be {abc}
-% {\normalexpanded{\protected\def\syst_helpers_do_do_if_in_string_else##1,\m_syst_sub_string,##2}%
-% {\ifarguments
-% \or
-% \expandafter\syst_helpers_do_if_in_string_else_nop
-% \or
-% \expandafter\syst_helpers_do_if_in_string_else_yes
-% \fi}%
-% \normalexpanded{\syst_helpers_do_do_if_in_string_else,#1,}\e_o_t\ignorearguments\ignorearguments}
-%
-% \protected\def\doifinstring#1%
-% {\edef\m_syst_sub_string{#1}% expand #1 here
-% \ifempty\m_syst_sub_string
-% \expandafter\gobbletwoarguments
-% \else
-% \expandafter\syst_helpers_do_if_in_string
-% \fi}
-%
-% \protected\def\syst_helpers_do_if_in_string#1% ##2 can be {abc}
-% {\normalexpanded{\protected\def\syst_helpers_do_do_if_in_string##1\m_syst_sub_string##2}%
-% {\ifarguments
-% \or
-% \expandafter\syst_helpers_do_if_in_string_nop
-% \or
-% \expandafter\syst_helpers_do_if_in_string_yes
-% \fi}%
-% \normalexpanded{\syst_helpers_do_do_if_in_string#1}\e_o_t\ignorearguments\ignorearguments}
-%
-% \protected\def\doifnotinstring#1%
-% {\edef\m_syst_sub_string{#1}% expand #1 here
-% \ifempty\m_syst_sub_string
-% \expandafter\secondoftwoarguments
-% \else
-% \expandafter\syst_helpers_do_if_not_in_string
-% \fi}
-%
-% \protected\def\syst_helpers_do_if_not_in_string#1% ##2 can be {abc}
-% {\normalexpanded{\protected\def\syst_helpers_do_do_if_not_in_string##1\m_syst_sub_string##2}%
-% {\ifarguments
-% \or
-% \expandafter\syst_helpers_do_if_not_in_string_nop
-% \or
-% \expandafter\syst_helpers_do_if_not_in_string_yes
-% \fi}%
-% \normalexpanded{\syst_helpers_do_do_if_not_in_string#1}\e_o_t\ignorearguments\ignorearguments}
-%
-% \def\syst_helpers_do_if_in_string_else_yes#0\ignorearguments\ignorearguments#2#0{#2}
-% \def\syst_helpers_do_if_in_string_else_nop#0\ignorearguments#0#3{#3}
-% \def\syst_helpers_do_if_in_string_yes #0\ignorearguments\ignorearguments#2{#2}
-% \def\syst_helpers_do_if_in_string_nop #0\ignorearguments#0{}
-% \def\syst_helpers_do_if_not_in_string_yes #0\ignorearguments\ignorearguments#0{}
-% \def\syst_helpers_do_if_not_in_string_nop #0\ignorearguments#2{#2}
-
-\permanent\protected\def\doifelseinstring#1#2%
- {\ifhasxtoks{#1}{#2}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\permanent\protected\def\doifinstring#1#2%
- {\ifhasxtoks{#1}{#2}%
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\doifnotinstring#1#2%
- {\ifhasxtoks{#1}{#2}%
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\aliased\let\doifinstringelse\doifelseinstring
-
-%D The next one one of those variants that we used when speed was more of an issue
-%D that today. Now we just expand the lot. We just use an alias now:
-
-\aliased\let\doifelseincsname\doifelseinstring
-\aliased\let\doifincsnameelse\doifinstringelse
-
-%D \macros
-%D {doifnumberelse,doifnumber,doifnotnumber}
-%D
-%D The next macro executes a command depending of the outcome of a test on numerals.
-%D We now use a \LUATEX\ feature that permits a more robust checking, but you might
-%D want to take a look at the originals. It's typically one of these new features
-%D that probably only \CONTEXT\ will use, which is probably true for more such
-%D features that no one ever asked for (but they are pretty generic in nature
-%D anyway).
-
-\permanent\def\doifelsenumber#1%
- {\ifchknum#1\or
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\permanent\def\doifnumber#1%
- {\ifchknum#1\or
- \expandafter\firstoftwoarguments
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\def\doifnotnumber#1%
- {\ifchknum#1\or
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\let\doifnumberelse\doifelsenumber
-
-%D \macros
-%D {setpercentdimen}
-%D
-%D \starttyping
-%D \scratchdimen=100pt \setpercentdimen\scratchdimen{10\letterpercent}
-%D \scratchdimen=100pt \setpercentdimen\scratchdimen{5pt}
-%D \scratchdimen \percentdimen \hsize {10\letterpercent}
-%D \stoptyping
-
-% todo: use the push back dimen trickery
-
-\permanent\def\percentdimen#1#2% dimen percentage (with %)
- {\dimexpr\clf_percentageof{#2}\dimexpr#1\relax}
-
-\permanent\protected\def\setpercentdimen#1#2% dimen percentage (with %)
- {#1=\clf_percentageof{#2}\dimexpr#1\relax}
-
-%D \macros
-%D {makerawcommalist,
-%D rawdoinsetelse,
-%D rawprocesscommalist,
-%D rawprocessaction}
-%D
-%D Some of the commands mentioned earlier are effective but slow. When one is
-%D desperately in need of faster alternatives and when the conditions are
-%D predictable safe, the \type {\raw} alternatives come into focus. A major drawback
-%D is that they do not take \type {\c!constants} into account, simply because no
-%D expansion is done. This is no problem with \type {\rawprocesscommalist}, because
-%D this macro does not compare anything. Expandable macros are permitted as search
-%D string.
-%D
-%D \starttyping
-%D \makerawcommalist[string,string,...]\stringlist
-%D \rawdoifelseinset{string}{string,...}{...}{...}
-%D \rawprocesscommalist[string,string,...]\commando
-%D \rawprocessaction[x][a=>\a,b=>\b,c=>\c]
-%D \stoptyping
-%D
-%D Spaces embedded in the list, for instance after commas, spoil the search process.
-%D The gain in speed depends on the length of the argument (the longer the argument,
-%D the less we gain). The question is: do we still need these raw variants?
-
-\permanent\protected\def\makerawcommalist[#1]#2% use \processnext ... here
- {\scratchtoks\emptytoks
- \def\syst_helpers_do_make_raw_comma_list##1{\iftok\scratchtoks\emptytoks\scratchtoks{##1}\else\toksapp\scratchtoks{,##1}\fi}%
- \processcommalist[#1]\syst_helpers_do_make_raw_comma_list
- \edef#2{\the\scratchtoks}}
-
-% beware: in mkiv { } were lost so it was not compatible with the non raw
-
-\aliased\let\rawprocesscommalist \processcommalist % can go
-\aliased\let\rawprocesscommacommand\processcommacommand % can go
-
-%D Here is one without nesting .. still needed?
-
-\protected\def\syst_helpers_process_fast_comma_item#1,%
- {\ifarguments
- \expandafter\syst_helpers_process_comma_item_gobble
- \or
- \fastcommalistcommand{#1}%
- \expandafter\syst_helpers_process_fast_comma_item_next
- \fi}
-
-\protected\def\syst_helpers_process_fast_comma_item_next
- {\expandafterspaces\syst_helpers_process_fast_comma_item}
-
-\permanent\protected\def\fastprocesscommalist[#1]#2%
- {\let\fastcommalistcommand#2%
- \expandafterspaces\syst_helpers_process_fast_comma_item#1\ignorearguments\ignorearguments\ignorearguments}
-
-\permanent\protected\def\fastprocesscommacommand[#1]#2%
- {\let\fastcommalistcommand#2%
- \normalexpanded{\noexpand\expandafterspaces\syst_helpers_process_fast_comma_item#1}\ignorearguments\ignorearguments\ignorearguments}
-
-% \def\rawdoifelseinset#1#2{\doifinstringelse{,#1,}{,#2,}}
-% \def\rawdoifinset #1#2{\doifinstring {,#1,}{,#2,}}
-
-\def\syst_helpers_do_if_else_in_set#1%
- {\ifhasxtoks{,\m_syst_sub_string,}{,#1,}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\protected\def\rawdoifelseinset#1%
- {\edef\m_syst_sub_string{#1}% expand #1 here
- \ifempty\m_syst_sub_string
- \expandafter\thirdofthreearguments
- \else
- \expandafter\syst_helpers_do_if_else_in_set
- \fi}
-
-\aliased\let\rawdoifinsetelse\rawdoifelseinset
-
-\def\syst_helpers_do_if_in_set#1%
- {\ifhasxtoks{,\m_syst_sub_string,}{,#1,}%
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\rawdoifinset#1% or just alias this one
- {\edef\m_syst_sub_string{#1}% expand #1 here
- \ifx\m_syst_sub_string\m_syst_two_commas
- \expandafter\gobbletwoarguments
- \else
- \expandafter\syst_helpers_do_if_in_set
- \fi}
-
-%D Some more raw material:
-
-\def\syst_helpers_raw_process_action#1=>#2,%
- {\ifarguments
- %\expandafter\syst_helpers_raw_process_action_gobble
- \or
- \expandafter\syst_helpers_raw_process_action_gobble
- \or
- \edef\m_syst_string_two{#1}%
- \ifx\m_syst_string_one\m_syst_string_two
- \def\m_syst_helpers_process_action{#2}%
- \expandafter\expandafter\expandafter\syst_helpers_raw_process_action_gobble
- \else
- \ifx\s!unknown\m_syst_string_two
- \def\m_syst_helpers_process_action_unknown{#2}%
- \fi
- \expandafter\expandafter\expandafter\syst_helpers_raw_process_action_next
- \fi
- \fi}
-
-\def\syst_helpers_raw_process_action_gobble#-\ignorearguments
- {}
-
-\def\syst_helpers_raw_process_action_next
- {\expandafterspaces\syst_helpers_raw_process_action}
-
-\protected\def\xrawprocessaction[#1]#2[#3]%
- {\edef\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one
- \let\m_syst_string_one\s!default
- \fi
- \let\m_syst_helpers_process_action\relax
- \let\m_syst_helpers_process_action_unknown\relax
- \syst_helpers_raw_process_action#3\ignorearguments\ignorearguments\ignorearguments
- \ifx\m_syst_helpers_process_action\relax
- \m_syst_helpers_process_action_unknown
- \else
- \m_syst_helpers_process_action
- \fi}
-
-%D When we process the list \type {a,b,c,d,e}, the raw routine takes over 30\% less
-%D time, when we feed $20+$ character strings we gain about 20\%. Alternatives which
-%D use \type {\futurelet} perform worse. Part of the speedup is due to the \type
-%D {\let} and \type {\expandafter} in the test.
-%D
-%D \macros
-%D {dosetvalue,dosetevalue,dosetgvalue,docopyvalue,doresetvalue,
-%D dogetvalue}
-%D
-%D When we are going to do assignments, we have to take multi||linguality into account.
-%D For the moment we keep things simple and single||lingual.
-%D
-%D \starttyping
-%D \dosetvalue {label} {variable} {value}
-%D \dosetevalue {label} {variable} {value}
-%D \dosetgvalue {label} {variable} {value}
-%D \docopyvalue {to label} {from label} {variable}
-%D \doresetvalue {label} {variable}
-%D \stoptyping
-%D
-%D These macros are in fact auxiliary ones and are not meant for use outside the
-%D assignment macros.
-
-\def\dosetvalue #1#2{\defcsname #1#2\endcsname} % takes #3
-\def\dosetevalue #1#2{\edefcsname #1#2\endcsname} % takes #3
-\def\dosetgvalue #1#2{\global\edefcsname#1#2\endcsname} % takes #3
-\def\doresetvalue #1#2{\letcsname #1#2\endcsname\empty}
-\def\doignorevalue#1#2#3{\letcsname #1#2\endcsname\empty}
-\def\docopyvalue #1#2#3{\defcsname #1#3\endcsname{\csname#2#3\endcsname}}
-
-%D \macros
-%D {doassign,undoassign,doassignempty}
-%D
-%D Assignments are the backbone of \CONTEXT. Abhorred by the concept of style file
-%D hacking, we took a considerable effort in building a parameterized system.
-%D Unfortunately there is a price to pay in terms of speed. Compared to other
-%D packages and taking the functionality of \CONTEXT\ into account, the total size
-%D of the format file is still very acceptable. Now how are these assignments done.
-%D
-%D Assignments can be realized with:
-%D
-%D \starttyping
-%D \doassign[label][variable=value]
-%D \undoassign[label][variable=value]
-%D \stoptyping
-%D
-%D and:
-%D
-%D \starttyping
-%D \doassignempty[label][variable=value]
-%D \stoptyping
-%D
-%D Assignments like \type{\doassign} are compatible with:
-%D
-%D \starttyping
-%D \def\labelvariable{value}
-%D \stoptyping
-%D
-%D We do check for the presence of an \type{=} and loudly complain of it's missed. We
-%D will redefine this macro later on, when a more advanced message mechanism is
-%D implemented.
-
-\protected\def\showassignerror#1#2%
- {\writestatus{setup}{missing or ungrouped '=' after '#1' in line #2}}
-
-\protected\def\doassignempty[#1][#2=#3]%
- {\ifcsname#1#2\endcsname\else\dosetvalue{#1}{#2}{#3}\fi}
-
-%D \macros
-%D {getparameters,geteparameters,getgparameters,
-%D forgetparameters}
-%D
-%D Using the assignment commands directly is not our ideal of user friendly interfacing,
-%D so we take some further steps.
-%D
-%D \starttyping
-%D \getparameters [label] [...=...,...=...]
-%D \forgetparameters [label] [...=...,...=...]
-%D \stoptyping
-%D
-%D Again, the label identifies the category a variable belongs to. The second argument
-%D can be a comma separated list of assignments.
-%D
-%D \starttyping
-%D \getparameters
-%D [demo]
-%D [alfa=1,
-%D beta=2]
-%D \stoptyping
-%D
-%D is equivalent to
-%D
-%D \starttyping
-%D \def\demoalfa{1}
-%D \def\demobeta{2}
-%D \stoptyping
-%D
-%D
-%D In the pre||multi||lingual stadium \CONTEXT\ took the next approach. With
-%D
-%D \starttyping
-%D \def\??demo {@@demo}
-%D \def\!!alfa {alfa}
-%D \def\!!beta {beta}
-%D \stoptyping
-%D
-%D calling
-%D
-%D \starttyping
-%D \getparameters
-%D [\??demo]
-%D [\!!alfa=1,
-%D \!!beta=2]
-%D \stoptyping
-%D
-%D lead to:
-%D
-%D \starttyping
-%D \def\@@demoalfa{1}
-%D \def\@@demobeta{2}
-%D \stoptyping
-%D
-%D Because we want to be able to distinguish the \type{!!} pre||tagged user supplied
-%D variables from internal counterparts, we will introduce a slightly different tag
-%D in the multi||lingual modules. There we will use \type{c!} or \type{v!},
-%D depending on the context.
-%D
-%D By calling \type{doassign} directly, we save ourselves some argument passing
-%D and gain some speed. Whatever optimizations we do, this command will always be
-%D one of the bigger bottlenecks. The alternative \type{\geteparameters} --- it's
-%D funny to see that this alternative saw the light so lately --- can be used to do
-%D expanded assigments.
-
-\let\currentvalue\empty
-
-\permanent\protected\def\getparameters {\dogetparameters\dosetvalue}
-\permanent\protected\def\geteparameters {\dogetparameters\dosetevalue}
-\permanent\protected\def\getgparameters {\dogetparameters\dosetgvalue}
-\permanent\protected\def\getxparameters {\dogetparameters\dosetxvalue}
-\permanent\protected\def\forgetparameters{\dogetparameters\doignorevalue}
-
-\aliased\let\getexpandedparameters\geteparameters
-
-\def\syst_helpers_grab_parameter_error#1%
- {\showassignerror{#1}{\the\inputlineno\space(\m_syst_parameter_n)}}
-
-\def\syst_helpers_grab_parameter#1,%
- {\ifarguments
- % done
- \else
- \syst_helpers_grab_parameter_okay#1,\ignorearguments
- \expandafter\syst_helpers_grab_parameter_next
- \fi}
-
-\def\syst_helpers_grab_parameter_okay#1=#2,%
- {\ifarguments
- \or
- \syst_helpers_grab_parameter_error{#1}%
- \or
- \m_syst_parameter_s\m_syst_parameter_n{#1}{#2}%
- \fi}
-
-\def\syst_helpers_grab_parameter_next
- {\expandafterspaces\syst_helpers_grab_parameter}
-
-\permanent\protected\def\dogetparameters#1[#2]#*[#3]%
- {\def\m_syst_parameter_n{#2}%
- \let\m_syst_parameter_s#1%
- \expandafterspaces\syst_helpers_grab_parameter#3\ignorearguments\ignorearguments}
-
-%D \macros
-%D {getemptyparameters}
-%D
-%D Sometimes we explicitly want variables to default to an empty string, so we
-%D welcome:
-%D
-%D \starttyping
-%D \getemptyparameters [label] [...=...,...=...]
-%D \stoptyping
-
-\permanent\protected\def\getemptyparameters[#1]#*[#2]%
- {\def\syst_helpers_get_empty_parameters##1{\doassignempty[#1][##1]}%
- \processcommalist[#2]\syst_helpers_get_empty_parameters}
-
-%D We now just alias these as there is no need for a speedup. These have not been used
-%D for a long time in core code.
-
-\let\doassign \getparameters
-\let\doeassign \geteparameters
-\let\undoassign\forgetparameters
-
-%D \macros
-%D {processassignmentlist,processassignmentcommand,
-%D startprocessassignmentlist,startprocessassignmentcommand}
-%D
-%D For Wolfgang:
-%D
-%D \starttyping
-%D \def\showpair#1#2{key:#1, value:#2\par}
-%D \processassignmentlist[a=1,b=2]\showpair
-%D \stoptyping
-%D
-%D We can optimize this one if needed but it's not a core macro so hardly worth the
-%D trouble and tokens.
-
-\permanent\protected\def\processassignmentlist[#1]#2% #2 == \command{key}{value]
- {\def\syst_helpers_process_assignment_entry##1{#2}% {##2}{##3} % namespace is ignored
- \dogetparameters\syst_helpers_process_assignment_entry[][#1]}
-
-\permanent\protected\def\processassignmentcommand[#1]%
- {\normalexpanded{\processassignmentlist[#1]}}
-
-\permanent\protected\def\startprocessassignmentlist[#1]#2\stopprocessassignmentlist
- {\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}%
- \processassignmentlist[#1]\currentassignmentlistcommand}
-
-\permanent\protected\def\startprocessassignmentcommand[#1]#2\stopprocessassignmentcommand
- {\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}%
- \normalexpanded{\processassignmentlist[#1]}\currentassignmentlistcommand}
-
-%D \macros
-%D {currentvalue}
-%D
-%D Just in case a \type{\getparameter} argument itself ends up inside a \type
-%D {\write} or other expandable location, our new macro needs a default value.
-%D
-%D \starttyping
-%D \getparameters[xxx][aaa=bbb]\par
-%D \getparameters[xxx][=bbb]\par
-%D \getparameters[xxx][aaa=]\par
-%D \getparameters[xxx][=]\par
-%D \getparameters[xxx][aaa]\par
-%D \stoptyping
-
-%D \macros
-%D {copyparameters}
-%D
-%D Some \CONTEXT\ commands take their default setups from others. All commands that
-%D are able to provide backgounds or rules around some content, for instance default
-%D to the standard command for ruled boxes. Is situations like this we can use:
-%D
-%D \starttyping
-%D \copyparameters [to-label] [from-label] [name1,name2,...]
-%D \stoptyping
-%D
-%D For instance
-%D
-%D \starttyping
-%D \copyparameters
-%D [internal][external]
-%D [alfa,beta]
-%D \stoptyping
-%D
-%D Leads to:
-%D
-%D \starttyping
-%D \def\internalalfa {\externalalfa}
-%D \def\internalbeta {\externalbeta}
-%D \stoptyping
-%D
-%D By using \type {\docopyvalue} we've prepared this command for use in a
-%D multi||lingual environment.
-
-\permanent\protected\def\copyparameters[#1]#*[#2]#*[#3]%
- {\doifnot{#1}{#2}
- {\def\syst_helpers_copy_parameter{\docopyvalue{#1}{#2}}% ##1
- \processcommalist[#3]\syst_helpers_copy_parameter}}
-
-% %D \macros
-% %D {ifparameters,checkparameters}
-% %D
-% %D A slightly different one is \type {\checkparameters}, which also checks on the
-% %D presence of a~\type {=}.
-% %D
-% %D The boolean \type {\ifparameters} can be used afterwards. Combining both in one
-% %D \type {\if}||macro would lead to problems with nested \type {\if}'s.
-% %D
-% %D \starttyping
-% %D \checkparameters[argument]
-% %D \stoptyping
-%
-% \newif\ifparameters
-%
-% \protected\def\checkparameters[#1]%
-% {\ifhastok={#1}\parameterstrue\else\parametersfalse\fi}
-
-%D \macros
-%D {getfromcommalist,getfromcommacommand,
-%D commalistelement,
-%D getcommalistsize,getcommacommandsize}
-%D
-%D It's possible to get an element from a commalist or a command representing
-%D a commalist.
-%D
-%D \starttyping
-%D \getfromcommalist [string] [n]
-%D \getfromcommacommand [string,\strings,string,...] [n]
-%D \stoptyping
-%D
-%D The difference betwee the two of them is the same as the difference between
-%D \type {\processcomma...}. The found string is stored in \type
-%D {\commalistelement}.
-%D
-%D We can calculate the size of a comma separated list by using:
-%D
-%D \starttyping
-%D \getcommalistsize [string,string,...]
-%D \getcommacommandsize [string,\strings,string,...]
-%D \stoptyping
-%D
-%D Afterwards, the length is available in the macro \type {\commalistsize}
-%D (not a \COUNTER).
-
-\newcount\commalistcounter
-
-\def\commalistsize{0}
-
-\def\syst_helpers_get_comma_list_size#0,% no #- as we need to count
- {\ifarguments\or
- \advance\commalistcounter\plusone
- \expandafter\syst_helpers_get_comma_list_size
- \fi}
-
-\protected\def\getcommalistsize[%
- {\futureexpand]\syst_helpers_get_comma_list_size_nop\syst_helpers_get_comma_list_size_yes}
-
-\def\syst_helpers_get_comma_list_size_yes#+]%
- {\commalistcounter\zerocount
- \syst_helpers_get_comma_list_size #1,\ignorearguments\ignorearguments
- \edef\commalistsize{\the\commalistcounter}}
-
-\def\syst_helpers_get_comma_list_size_nop]%
- {\commalistcounter\zerocount
- \let\commalistsize\!!zerocount}
-
-\permanent\protected\def\getcommacommandsize[#1]%
- {\normalexpanded{\getcommalistsize[#1]}}
-
-%D Filters:
-
-% \def\syst_helpers_gobble_comma_list#0\ignorearguments{}
-
-\def\syst_helpers_gobble_comma_list#-\ignorearguments{}
-
-\def\syst_helpers_get_from_comma_list#1,%
- {\ifarguments \or
- \advance\commalistcounter \minusone
- \ifcase\commalistcounter
- \def\commalistelement{#1}%
- \expandafter\expandafter\expandafter\syst_helpers_gobble_comma_list
- \else
- \expandafter\expandafter\expandafter\syst_helpers_get_from_comma_list_next
- \fi
- \fi}
-
-\def\syst_helpers_get_from_comma_list_next
- {\expandafterspaces\syst_helpers_get_from_comma_list}
-
-\permanent\protected\def\getfromcommalist[#1]#*[#2]%
- {\let\commalistelement\empty
- \commalistcounter#2\relax
- \expandafterspaces\syst_helpers_get_from_comma_list#1\ignorearguments\ignorearguments}
-
-\permanent\protected\def\getfromcommacommand[#1]%
- {\normalexpanded{\getfromcommalist[#1]}}
-
-%D Watertight (and efficient) solutions are hard to find, due to the handling of
-%D braces during parameters passing and scanning. Nevertheless:
-%D
-%D \startbuffer
-%D \def\dosomething#1{(#1=\commalistsize) }
-%D
-%D \getcommalistsize [\hbox{$a,b,c,d,e,f$}] \dosomething 1
-%D \getcommalistsize [{a,b,c,d,e,f}] \dosomething 1
-%D \getcommalistsize [{a,b,c},d,e,f] \dosomething 4
-%D \getcommalistsize [a,b,{c,d,e},f] \dosomething 4
-%D \getcommalistsize [a{b,c},d,e,f] \dosomething 4
-%D \getcommalistsize [{a,b}c,d,e,f] \dosomething 4
-%D \getcommalistsize [] \dosomething 0
-%D \getcommalistsize [{[}] \dosomething 1
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D reports:
-%D
-%D \getbuffer
-
-%D \macros
-%D {dogetcommalistelement,dogetcommacommandelement}
-%D
-%D For low level (fast) purposes, we can also use the next alternative, which can
-%D handle 9~elements at most.
-%D
-%D \starttyping
-%D \dogetcommalistelement1\from a,b,c\to\commalistelement
-%D \stoptyping
-
-\def\syst_helpers_get_comma_list_element#1,#2,#3,#4,#5,#6,#7,#8,#9,%
- {\ifcase\scratchcounter\or#1\or#2\or#3\or#4\or#5\or#6\or#7\or#8\or#9\fi
- \syst_helpers_gobble_comma_list}
-
-\permanent\protected\def\dogetcommacommandelement#1\from#2\to#3%
- {\scratchcounter#1\relax
- \edef#3{\normalexpanded{\syst_helpers_get_comma_list_element#2\ignorearguments\ignorearguments}}}
-
-%D \macros
-%D {dosingleargument,dodoubleargument,dotripleargument,
-%D doquadrupleargument,doquintupleargument,dosixtupleargument,
-%D doseventupleargument}
-%D
-%D When working with delimited arguments, spaces and lineendings can interfere. The
-%D next set of macros uses \TEX' internal scanner for grabbing everything between
-%D arguments. Forgive me the funny names.
-%D
-%D \starttyping
-%D \dosingleargument \command = \command[#1]
-%D \dodoubleargument \command = \command[#1][#2]
-%D \dotripleargument \command = \command[#1][#2][#3]
-%D \doquadrupleargument \command = \command[#1][#2][#3][#4]
-%D \doquintupleargument \command = \command[#1][#2][#3][#4][#5]
-%D \dosixtupleargument \command = \command[#1][#2][#3][#4][#5][#6]
-%D \doseventupleargument\command = \command[#1][#2][#3][#4][#5][#6][#7]
-%D \stoptyping
-%D
-%D These macros can be used in the following way:
-%D
-%D \starttyping
-%D \def\dosetupsomething[#1][#2]%
-%D {... #1 ... #2 ...}
-%D
-%D \protected\def\setupsomething
-%D {\dodoubleargument\dosetupsomething}
-%D \stoptyping
-%D
-%D The implementation can be surprisingly simple and needs no further explanation,
-%D like:
-%D
-%D \starttyping
-%D \def\dosingleargument#1[#2]%
-%D {#1[#2]}
-%D \def\dotripleargument#1[#2]#3[#4]#5[#6]%
-%D {#1[#2][#4][#6]}
-%D \def\doquintupleargument#1%
-%D {\def\dodoquintupleargument[##1]##2[##3]##4[##5]##6[##7]##8[##9]%
-%D {#1[##1][##3][##5][##7][##9]}%
-%D \dodoquintupleargument}
-%D \stoptyping
-%D
-%D Because \TEX\ accepts 9~arguments at most, we have to use two||step solution when
-%D getting five or more arguments.
-%D
-%D When developing more and more of the real \CONTEXT, we started using some
-%D alternatives that provided empty arguments (in fact optional ones) whenever the
-%D user failed to supply them. Because this more complicated macros enable us to do
-%D some checking, we reimplemented the non||empty ones.
-
-%D \macros
-%D {iffirstagument,ifsecondargument,ifthirdargument,
-%D iffourthargument,iffifthargument,ifsixthargument,
-%D ifseventhargument}
-%D
-%D We use some signals for telling the calling macros if all wanted arguments are
-%D indeed supplied by the user.
-
-\newcount\nofarguments
-
-\newif\iffirstargument
-\newif\ifsecondargument
-\newif\ifthirdargument
-\newif\iffourthargument
-\newif\iffifthargument
-\newif\ifsixthargument
-\newif\ifseventhargument
-
-%D \macros
-%D {dosingleempty,dodoubleempty,dotripleempty,
-%D doquadrupleempty,doquintupleempty,dosixtupeempty,
-%D doseventupleempty}
-%D
-%D The empty argument supplying macros mentioned before, look like:
-%D
-%D \starttyping
-%D \dosingleempty \command
-%D \dodoubleempty \command
-%D \dotripleempty \command
-%D \doquadrupleempty \command
-%D \doquintupleempty \command
-%D \dosixtuple_empty \command
-%D \doseventupleempty\command
-%D \stoptyping
-%D
-%D So \type{\dodoubleempty} leads to:
-%D
-%D \starttyping
-%D \command[#1][#2]
-%D \command[#1][]
-%D \command[][]
-%D \stoptyping
-%D
-%D Depending of the generousity of the user. Afterwards one can use the \type
-%D {\if...argument} boolean. For novice: watch the stepwise doubling of \type {#}'s.
-
-%D NB : experimental versions in cont-exp.mkiv
-
-%D Common:
-
-\newtoks\t_syst_aux
-
-% \def\syst_helpers_single_empty_one_yes {\firstargumenttrue \the\t_syst_aux}
-% \def\syst_helpers_double_empty_two_yes {\secondargumenttrue \the\t_syst_aux}
-% \def\syst_helpers_triple_empty_three_yes {\thirdargumenttrue \the\t_syst_aux}
-% \def\syst_helpers_quadruple_empty_four_yes {\fourthargumenttrue \the\t_syst_aux}
-% \def\syst_helpers_quintuple_empty_five_yes {\fifthargumenttrue \the\t_syst_aux}
-% \def\syst_helpers_sixtuple_empty_six_yes {\sixthargumenttrue \the\t_syst_aux}
-% \def\syst_helpers_seventuple_empty_seven_yes{\seventhargumenttrue\the\t_syst_aux}
-%
-% %D Single:
-%
-% \protected\def\dosingleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_single_empty_one_yes\syst_helpers_single_empty_one_nop}
-%
-% \def\syst_helpers_single_empty_one_nop
-% {\firstargumentfalse
-% \the\t_syst_aux[]}
-%
-% %D Double
-%
-% \protected\def\dodoubleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_double_empty_one_yes\syst_helpers_double_empty_one_nop}
-%
-% % \def\syst_helpers_double_empty_one_yes[#1]%
-% % {\firstargumenttrue
-% % \toksapp\t_syst_aux{[{#1}]}%
-% % \futureexpand[\syst_helpers_double_empty_two_yes\syst_helpers_double_empty_two_nop}
-% %
-% % nicer is:
-%
-% \def\syst_helpers_double_empty_one_yes[#+]%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_double_empty_two_yes\syst_helpers_double_empty_two_nop}
-%
-% \def\syst_helpers_double_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \the\t_syst_aux[][]}
-%
-% \def\syst_helpers_double_empty_two_nop
-% {\secondargumentfalse
-% \the\t_syst_aux[]}
-%
-% % Triple
-%
-% \protected\def\dotripleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_triple_empty_one_yes\syst_helpers_triple_empty_one_nop}
-%
-% \def\syst_helpers_triple_empty_one_yes[#+]%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_triple_empty_two_yes\syst_helpers_triple_empty_two_nop}
-%
-% \def\syst_helpers_triple_empty_two_yes[#+]%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_triple_empty_three_yes\syst_helpers_triple_empty_three_nop}
-%
-% \def\syst_helpers_triple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \the\t_syst_aux[][][]}
-%
-% \def\syst_helpers_triple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \the\t_syst_aux[][]}
-%
-% \def\syst_helpers_triple_empty_three_nop
-% {\thirdargumentfalse
-% \the\t_syst_aux[]}
-%
-% %D Quadruple:
-%
-% \protected\def\doquadrupleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_quadruple_empty_one_yes\syst_helpers_quadruple_empty_one_nop}
-%
-% \def\syst_helpers_quadruple_empty_one_yes[#+]%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quadruple_empty_two_yes\syst_helpers_quadruple_empty_two_nop}
-%
-% \def\syst_helpers_quadruple_empty_two_yes[#+]%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quadruple_empty_three_yes\syst_helpers_quadruple_empty_three_nop}
-%
-% \def\syst_helpers_quadruple_empty_three_yes[#+]%
-% {\thirdargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quadruple_empty_four_yes\syst_helpers_quadruple_empty_four_nop}
-%
-% \def\syst_helpers_quadruple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \the\t_syst_aux[][][][]}
-%
-% \def\syst_helpers_quadruple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \the\t_syst_aux[][][]}
-%
-% \def\syst_helpers_quadruple_empty_three_nop
-% {\thirdargumentfalse
-% \fourthargumentfalse
-% \the\t_syst_aux[][]}
-%
-% \def\syst_helpers_quadruple_empty_four_nop
-% {\fourthargumentfalse
-% \the\t_syst_aux[]}
-%
-% %D Quintuple:
-%
-% \protected\def\doquintupleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_quintuple_empty_one_yes\syst_helpers_quintuple_empty_one_nop}
-%
-% \def\syst_helpers_quintuple_empty_one_yes[#+]%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quintuple_empty_two_yes\syst_helpers_quintuple_empty_two_nop}
-%
-% \def\syst_helpers_quintuple_empty_two_yes[#+]%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quintuple_empty_three_yes\syst_helpers_quintuple_empty_three_nop}
-%
-% \def\syst_helpers_quintuple_empty_three_yes[#+]%
-% {\thirdargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quintuple_empty_four_yes\syst_helpers_quintuple_empty_four_nop}
-%
-% \def\syst_helpers_quintuple_empty_four_yes[#+]%
-% {\fourthargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_quintuple_empty_five_yes\syst_helpers_quintuple_empty_five_nop}
-%
-% \def\syst_helpers_quintuple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux[][][][][]}
-%
-% \def\syst_helpers_quintuple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux[][][][]}
-%
-% \def\syst_helpers_quintuple_empty_three_nop
-% {\thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux[][][]}
-%
-% \def\syst_helpers_quintuple_empty_four_nop
-% {\fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux[][]}
-%
-% \def\syst_helpers_quintuple_empty_five_nop
-% {\fifthargumentfalse
-% \the\t_syst_aux[]}
-%
-% %D Sixtuple:
-%
-% \protected\def\dosixtupleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_sixtuple_empty_one_yes\syst_helpers_sixtuple_empty_one_nop}
-%
-% \def\syst_helpers_sixtuple_empty_one_yes[#+]%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_sixtuple_empty_two_yes\syst_helpers_sixtuple_empty_two_nop}
-%
-% \def\syst_helpers_sixtuple_empty_two_yes[#+]%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_sixtuple_empty_three_yes\syst_helpers_sixtuple_empty_three_nop}
-%
-% \def\syst_helpers_sixtuple_empty_three_yes[#+]%
-% {\thirdargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_sixtuple_empty_four_yes\syst_helpers_sixtuple_empty_four_nop}
-%
-% \def\syst_helpers_sixtuple_empty_four_yes[#+]%
-% {\fourthargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_sixtuple_empty_five_yes\syst_helpers_sixtuple_empty_five_nop}
-%
-% \def\syst_helpers_sixtuple_empty_five_yes[#+]%
-% {\fifthargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_sixtuple_empty_six_yes\syst_helpers_sixtuple_empty_six_nop}
-%
-% \def\syst_helpers_sixtuple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \the\t_syst_aux[][][][][][]}
-%
-% \def\syst_helpers_sixtuple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \the\t_syst_aux[][][][][]}
-%
-% \def\syst_helpers_sixtuple_empty_three_nop
-% {\thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \the\t_syst_aux[][][][]}
-%
-% \def\syst_helpers_sixtuple_empty_four_nop
-% {\fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \the\t_syst_aux[][][]}
-%
-% \def\syst_helpers_sixtuple_empty_five_nop
-% {\fifthargumentfalse
-% \sixthargumentfalse
-% \the\t_syst_aux[][]}
-%
-% \def\syst_helpers_sixtuple_empty_six_nop
-% {\sixthargumentfalse
-% \the\t_syst_aux[]}
-%
-% %D Seventuple:
-%
-% \protected\def\doseventupleempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand[\syst_helpers_seventuple_empty_one_yes\syst_helpers_seventuple_empty_one_nop}
-%
-% \def\syst_helpers_seventuple_empty_one_yes[#+]%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_seventuple_empty_two_yes\syst_helpers_seventuple_empty_two_nop}
-%
-% \def\syst_helpers_seventuple_empty_two_yes[#+]%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_seventuple_empty_three_yes\syst_helpers_seventuple_empty_three_nop}
-%
-% \def\syst_helpers_seventuple_empty_three_yes[#+]%
-% {\thirdargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_seventuple_empty_four_yes\syst_helpers_seventuple_empty_four_nop}
-%
-% \def\syst_helpers_seventuple_empty_four_yes[#+]%
-% {\fourthargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_seventuple_empty_five_yes\syst_helpers_seventuple_empty_five_nop}
-%
-% \def\syst_helpers_seventuple_empty_five_yes[#+]%
-% {\fifthargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_seventuple_empty_six_yes\syst_helpers_seventuple_empty_six_nop}
-%
-% \def\syst_helpers_seventuple_empty_six_yes[#+]%
-% {\sixthargumenttrue
-% \toksapp\t_syst_aux{[#1]}%
-% \futureexpand[\syst_helpers_seventuple_empty_seven_yes\syst_helpers_seventuple_empty_seven_nop}
-%
-% \def\syst_helpers_seventuple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \seventhargumentfalse
-% \the\t_syst_aux[][][][][][][]}
-%
-% \def\syst_helpers_seventuple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \seventhargumentfalse
-% \the\t_syst_aux[][][][][][]}
-%
-% \def\syst_helpers_seventuple_empty_three_nop
-% {\thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \seventhargumentfalse
-% \the\t_syst_aux[][][][][]}
-%
-% \def\syst_helpers_seventuple_empty_four_nop
-% {\fourthargumentfalse
-% \fifthargumentfalse
-% \sixthargumentfalse
-% \seventhargumentfalse
-% \the\t_syst_aux[][][][]}
-%
-% \def\syst_helpers_seventuple_empty_five_nop
-% {\fifthargumentfalse
-% \sixthargumentfalse
-% \seventhargumentfalse
-% \the\t_syst_aux[][][]}
-%
-% \def\syst_helpers_seventuple_empty_six_nop
-% {\sixthargumentfalse
-% \seventhargumentfalse
-% \the\t_syst_aux[][]}
-%
-% \def\syst_helpers_seventuple_empty_seven_nop
-% {\seventhargumentfalse
-% \the\t_syst_aux[]}
-
-%tolerant\def\syst_single_empty#1\relax[#+]%
-\tolerant\def\syst_single_empty#1\relax[#2]%
- {\ifarguments
- \or\firstargumentfalse
- \or\firstargumenttrue
- \fi
- #1[#2]}
-
-%tolerant\def\syst_double_empty#1\relax[#2]#*[#3]%
-\tolerant\def\syst_double_empty#1\relax[#+]#*[#+]%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse
- \or\firstargumenttrue \secondargumentfalse
- \or\firstargumenttrue \secondargumenttrue
- \fi
- #1[#2][#3]}
-
-%tolerant\def\syst_triple_empty#1\relax[#2]#*[#3]#*[#4]%
-\tolerant\def\syst_triple_empty#1\relax[#+]#*[#+]#*[#+]%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue
- \fi
- #1[#2][#3][#4]}
-
-%tolerant\def\syst_quadruple_empty#1\relax[#2]#*[#3]#*[#4]#*[#5]%
-\tolerant\def\syst_quadruple_empty#1\relax[#+]#*[#+]#*[#+]#*[#+]%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse\fourthargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse\fourthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse\fourthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue
- \fi
- #1[#2][#3][#4][#5]}
-
-%\tolerant\def\syst_quintuple_empty#1\relax[#2]#*[#3]#*[#4]#*[#5]#*[#6]%
-\tolerant\def\syst_quintuple_empty#1\relax[#+]#*[#+]#*[#+]#*[#+]#*[#+]%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse\fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue
- \fi
- #1[#2][#3][#4][#5][#6]}
-
-%tolerant\def\syst_sixtuple_empty#1\relax[#2]#*[#3]#*[#4]#*[#5]#*[#6]#*[#7]%
-\tolerant\def\syst_sixtuple_empty#1\relax[#+]#*[#+]#*[#+]#*[#+]#*[#+]#*[#+]%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse\sixthargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse\sixthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse\fourthargumentfalse\fifthargumentfalse\sixthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumentfalse\fifthargumentfalse\sixthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumentfalse\sixthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue \sixthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue \sixthargumenttrue
- \fi
- #1[#2][#3][#4][#5][#6][#7]}
-
-%tolerant\def\syst_seventuple_empty#1\relax[#2]#*[#3]#*[#4]#*[#5]#*[#6]#*[#7]#*[#8]%
-\tolerant\def\syst_seventuple_empty#1\relax[#+]#*[#+]#*[#+]#*[#+]#*[#+]#*[#+]#*[#+]%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse\sixthargumentfalse\seventhargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse\sixthargumentfalse\seventhargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse\fourthargumentfalse\fifthargumentfalse\sixthargumentfalse\seventhargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumentfalse\fifthargumentfalse\sixthargumentfalse\seventhargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumentfalse\sixthargumentfalse\seventhargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue \sixthargumentfalse\seventhargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue \sixthargumenttrue \seventhargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue \sixthargumenttrue \seventhargumenttrue
- \fi
- #1[#2][#3][#4][#5][#6][#7][#8]}
-
-\permanent\protected\def\dosingleempty #1{\syst_single_empty #1\relax}
-\permanent\protected\def\dodoubleempty #1{\syst_double_empty #1\relax}
-\permanent\protected\def\dotripleempty #1{\syst_triple_empty #1\relax}
-\permanent\protected\def\doquadrupleempty #1{\syst_quadruple_empty #1\relax}
-\permanent\protected\def\doquintupleempty #1{\syst_quintuple_empty #1\relax}
-\permanent\protected\def\dosixtupleempty #1{\syst_sixtuple_empty #1\relax}
-\permanent\protected\def\doseventupleempty#1{\syst_seventuple_empty#1\relax}
-
-%D Aliases:
-
-\aliased\let\dosingleargument \dosingleempty
-\aliased\let\dodoubleargument \dodoubleempty
-\aliased\let\dotripleargument \dotripleempty
-\aliased\let\doquadrupleargument \doquadrupleempty
-\aliased\let\doquintupleargument \doquintupleempty
-\aliased\let\dosixtupleargument \dosixtupleempty
-\aliased\let\doseventupleargument\doseventupleempty
-
-%D \macros
-%D {strippedcsname}
-%D
-%D The next macro can be very useful when using \type{\csname} like in:
-%D
-%D \starttyping
-%D \csname if\strippedcsname\something\endcsname
-%D \stoptyping
-%D
-%D This expands to \type{\ifsomething}.
-
-\aliased\let\strippedcsname\csstring
-
-%D \macros
-%D {complexorsimple,complexorsimpleempty}
-%D
-%D Setups can be optional. A command expecting a setup is prefixed by \type
-%D {\complex}, a command without one gets the prefix \type {\simple}. Commands like
-%D this can be defined by:
-%D
-%D \starttyping
-%D \complexorsimple\command
-%D \stoptyping
-%D
-%D When \type{\command} is followed by a \type{[setup]}, then
-%D
-%D \starttyping
-%D \complexcommand [setup]
-%D \stoptyping
-%D
-%D executes, else we get
-%D
-%D \starttyping
-%D \simplecommand
-%D \stoptyping
-%D
-%D An alternative for \type{\complexorsimple} is:
-%D
-%D \starttyping
-%D \complexorsimpleempty {command}
-%D \stoptyping
-%D
-%D Depending on the presence of \type{[setup]}, this one leads to one of:
-%D
-%D \starttyping
-%D \complexcommando [setup]
-%D \complexcommando []
-%D \stoptyping
-%D
-%D Many \CONTEXT\ commands started as complex or simple ones, but changed into more
-%D versatile (more object oriented) ones using the \type {\get..argument} commands.
-
-\permanent\protected\def\complexorsimple#1%
- {\doifelsenextoptional
- {\firstargumenttrue \csname\s!complex\csstring#1\endcsname}
- {\firstargumentfalse\csname\s!simple \csstring#1\endcsname}}
-
-\permanent\protected\def\complexorsimpleempty#1%
- {\doifelsenextoptional
- {\firstargumenttrue \csname\s!complex\csstring#1\endcsname}
- {\firstargumentfalse\csname\s!complex\csstring#1\endcsname[]}}
-
-%D \macros
-%D {definecomplexorsimple,definecomplexorsimpleempty}
-%D
-%D The previous commands are used that often that we found it worthwile to offer two
-%D more alternatives. Watch the build in protection.
-
-\protected\def\syst_helpers_complex_or_simple#1#2%
- {\doifelsenextoptional{\firstargumenttrue#1}{\firstargumentfalse#2}}
-
-\protected\def\syst_helpers_complex_or_simple_empty#1%
- {\doifelsenextoptional{\firstargumenttrue#1}{\firstargumentfalse#1[]}}
-
-\permanent\protected\def\definecomplexorsimple#1%
- {\protected\edef#1{\syst_helpers_complex_or_simple
- \expandafter\noexpand\csname\s!complex\csstring#1\endcsname
- \expandafter\noexpand\csname\s!simple \csstring#1\endcsname}}
-
-\permanent\protected\def\definecomplexorsimpleempty#1%
- {\protected\edef#1{\syst_helpers_complex_or_simple_empty
- \expandafter\noexpand\csname\s!complex\csstring#1\endcsname}}
-
-%D These commands are called as:
-%D
-%D \starttyping
-%D \definecomplexorsimple\command
-%D \stoptyping
-%D
-%D Of course, we must have available
-%D
-%D \starttyping
-%D \def\complexcommand[#1]{...}
-%D \def\simplecommand {...}
-%D \stoptyping
-%D
-%D Using this construction saves a few string now and then.
-
-%D \macros
-%D {dosinglegroupempty,dodoublegroupempty,dotriplegroupempty,
-%D doquadruplegroupempty, doquintuplegroupempty}
-%D
-%D We've already seen some commands that take care of
-%D optional arguments between \type{[]}. The next two commands
-%D handle the ones with \type{{}}. They are called as:
-%D
-%D \starttyping
-%D \dosinglegroupempty \ineedONEargument
-%D \dodoublegroupempty \ineedTWOarguments
-%D \dotriplegroupempty \ineedTHREEarguments
-%D \doquadruplegroupempty \ineedFOURarguments
-%D \doquintuplegroupempty \ineedFIVEarguments
-%D \stoptyping
-%D
-%D We can add additional definitions later when we have defined \type {\appendtoks}.
-
-\newconditional\c_syst_helpers_permit_spaces_between_groups
-
-\permanent\protected\def \permitspacesbetweengroups{\settrue \c_syst_helpers_permit_spaces_between_groups}
-\permanent\protected\def\dontpermitspacesbetweengroups{\setfalse\c_syst_helpers_permit_spaces_between_groups}
-
-\dontpermitspacesbetweengroups
-
-%D We can avoid the nasty if handling in \type {syst-gen} by splitting the lot in
-%D pieces so that we have no nested \type {\nextarguments} potentially being an
-%D \type {conditional} token. Okay, these macros are not called that often but it
-%D saves crap when tracing.
-
-% \protected\def\dosinglegroupempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_single_empty_one_yes\syst_helpers_single_group_empty_one_nop}
-%
-% \def\syst_helpers_single_group_empty_one_nop
-% {\firstargumentfalse
-% \the\t_syst_aux{}}
-%
-% \protected\def\dodoublegroupempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_double_empty_one_yes\syst_helpers_group_double_empty_one_nop}
-%
-% % \def\syst_helpers_group_double_empty_one_yes#1%
-% % {\firstargumenttrue
-% % \toksapp\t_syst_aux{{#1}}%
-% % \futureexpand\bgroup\syst_helpers_double_empty_two_yes\syst_helpers_group_double_empty_two_nop}
-% %
-% % nicer is:
-%
-% \def\syst_helpers_group_double_empty_one_yes#+%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_double_empty_two_yes\syst_helpers_group_double_empty_two_nop}
-%
-% \def\syst_helpers_group_double_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \the\t_syst_aux{}{}}
-%
-% \def\syst_helpers_group_double_empty_two_nop
-% {\secondargumentfalse
-% \the\t_syst_aux{}}
-%
-% \protected\def\dotriplegroupempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_triple_empty_one_yes\syst_helpers_group_triple_empty_one_nop}
-%
-% \def\syst_helpers_group_triple_empty_one_yes#+%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_triple_empty_two_yes\syst_helpers_group_triple_empty_two_nop}
-%
-% \def\syst_helpers_group_triple_empty_two_yes#+%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_triple_empty_three_yes\syst_helpers_group_triple_empty_three_nop}
-%
-% \def\syst_helpers_group_triple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \the\t_syst_aux{}{}{}}
-%
-% \def\syst_helpers_group_triple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \the\t_syst_aux{}{}}
-%
-% \def\syst_helpers_group_triple_empty_three_nop
-% {\thirdargumentfalse
-% \the\t_syst_aux{}}
-%
-% \protected\def\doquadruplegroupempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quadruple_empty_one_yes\syst_helpers_group_quadruple_empty_one_nop}
-%
-% \def\syst_helpers_group_quadruple_empty_one_yes#+%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quadruple_empty_two_yes\syst_helpers_group_quadruple_empty_two_nop}
-%
-% \def\syst_helpers_group_quadruple_empty_two_yes#+%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quadruple_empty_three_yes\syst_helpers_group_quadruple_empty_three_nop}
-%
-% \def\syst_helpers_group_quadruple_empty_three_yes#+%
-% {\thirdargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_quadruple_empty_four_yes\syst_helpers_group_quadruple_empty_four_nop}
-%
-% \def\syst_helpers_group_quadruple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \the\t_syst_aux{}{}{}{}}
-%
-% \def\syst_helpers_group_quadruple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \the\t_syst_aux{}{}{}}
-%
-% \def\syst_helpers_group_quadruple_empty_three_nop
-% {\thirdargumentfalse
-% \fourthargumentfalse
-% \the\t_syst_aux{}{}}
-%
-% \def\syst_helpers_group_quadruple_empty_four_nop
-% {\fourthargumentfalse
-% \the\t_syst_aux{}}
-%
-% \protected\def\doquintuplegroupempty#1%
-% {\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quintuple_empty_one_yes\syst_helpers_group_quintuple_empty_one_nop}
-%
-% \def\syst_helpers_group_quintuple_empty_one_yes#+%
-% {\firstargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quintuple_empty_two_yes\syst_helpers_group_quintuple_empty_two_nop}
-%
-% \def\syst_helpers_group_quintuple_empty_two_yes#+%
-% {\secondargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quintuple_empty_three_yes\syst_helpers_group_quintuple_empty_three_nop}
-%
-% \def\syst_helpers_group_quintuple_empty_three_yes#+%
-% {\thirdargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_group_quintuple_empty_four_yes\syst_helpers_group_quintuple_empty_four_nop}
-%
-% \def\syst_helpers_group_quintuple_empty_four_yes#+%
-% {\fourthargumenttrue
-% \toksapp\t_syst_aux{#1}%
-% \futureexpand\bgroup\syst_helpers_quintuple_empty_five_yes\syst_helpers_group_quintuple_empty_five_nop}
-%
-% \def\syst_helpers_group_quintuple_empty_one_nop
-% {\firstargumentfalse
-% \secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux{}{}{}{}{}}
-%
-% \def\syst_helpers_group_quintuple_empty_two_nop
-% {\secondargumentfalse
-% \thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux{}{}{}{}}
-%
-% \def\syst_helpers_group_quintuple_empty_three_nop
-% {\thirdargumentfalse
-% \fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux{}{}{}}
-%
-% \def\syst_helpers_group_quintuple_empty_four_nop
-% {\fourthargumentfalse
-% \fifthargumentfalse
-% \the\t_syst_aux{}{}}
-%
-% \def\syst_helpers_group_quintuple_empty_five_nop
-% {\fifthargumentfalse
-% \the\t_syst_aux{}}
-
-\tolerant\def\syst_single_group_empty#1\relax#_%
- {\ifarguments
- \or\firstargumentfalse
- \or\firstargumenttrue
- \fi
- #1#2}
-
-\tolerant\def\syst_double_group_empty#1\relax#_#*#_%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse
- \or\firstargumenttrue \secondargumentfalse
- \or\firstargumenttrue \secondargumenttrue
- \fi
- #1#2#3}
-
-\tolerant\def\syst_triple_group_empty#1\relax#_#*#_#*#_%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue
- \fi
- #1#2#3#4}
-
-\tolerant\def\syst_quadruple_group_empty#1\relax#_#*#_#*#_#*#_%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse\fourthargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse\fourthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse\fourthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue
- \fi
- #1#2#3#4#5}
-
-\tolerant\def\syst_quintuple_group_empty#1\relax#_#*#_#*#_#*#_#*#_%
- {\ifarguments
- \or\firstargumentfalse\secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumentfalse\thirdargumentfalse\fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumentfalse\fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumentfalse\fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumentfalse
- \or\firstargumenttrue \secondargumenttrue \thirdargumenttrue \fourthargumenttrue \fifthargumenttrue
- \fi
- #1#2#3#4#5#6}
-
-\permanent\protected\def\dosinglegroupempty #1{\syst_single_group_empty #1\relax}
-\permanent\protected\def\dodoublegroupempty #1{\syst_double_group_empty #1\relax}
-\permanent\protected\def\dotriplegroupempty #1{\syst_triple_group_empty #1\relax}
-\permanent\protected\def\doquadruplegroupempty #1{\syst_quadruple_group_empty #1\relax}
-\permanent\protected\def\doquintuplegroupempty #1{\syst_quintuple_group_empty #1\relax}
-
-%D These macros can explictly take care of spaces, which means that the next
-%D definition and calls are valid:
-%D
-%D \starttyping
-%D \def\test#1#2#3{[#1#2#3]}
-%D
-%D \dotriplegroupempty\test {a}{b}{c}
-%D \dotriplegroupempty\test {a}{b}
-%D \dotriplegroupempty\test {a}
-%D \dotriplegroupempty\test
-%D \dotriplegroupempty\test {a} {b} {c}
-%D \dotriplegroupempty\test {a} {b}
-%D \dotriplegroupempty\test
-%D {a}
-%D {b}
-%D \stoptyping
-%D
-%D And alike.
-
-%D \macros
-%D {firstofoneargument, firstoftwoarguments, firstofthreearguments
-%D secondoftwoarguments, secondofthreearguments,
-%D thirdofthreearguments}
-%D
-%D The next six macros (dedicated to Taco) can conveniently used to select
-%D arguments. Their names explain their functionality.
-
-\permanent\def\firstofoneargument #1{#1}
-
-\permanent\def\firstoftwoarguments #1#-{#1}
-\permanent\def\secondoftwoarguments #-#1{#1}
-
-\permanent\def\firstofthreearguments #1#-#-{#1}
-\permanent\def\secondofthreearguments #-#1#-{#1}
-\permanent\def\thirdofthreearguments #-#-#1{#1}
-
-\permanent\def\firstoffourarguments #1#-#-#-{#1}
-\permanent\def\secondoffourarguments #-#1#-#-{#1}
-\permanent\def\thirdoffourarguments #-#-#1#-{#1}
-\permanent\def\fourthoffourarguments #-#-#-#1{#1}
-
-\permanent\def\firstoffivearguments #1#-#-#-#-{#1}
-\permanent\def\secondoffivearguments #-#1#-#-#-{#1}
-\permanent\def\thirdoffivearguments #-#-#1#-#-{#1}
-\permanent\def\fourthoffivearguments #-#-#-#1#-{#1}
-\permanent\def\fifthoffivearguments #-#-#-#-#1{#1}
-
-\permanent\def\firstofsixarguments #1#-#-#-#-#-{#1}
-\permanent\def\secondofsixarguments#-#1#-#-#-#-{#1}
-\permanent\def\thirdofsixarguments #-#-#1#-#-#-{#1}
-\permanent\def\fourthofsixarguments#-#-#-#1#-#-{#1}
-\permanent\def\fifthofsixarguments #-#-#-#-#1#-{#1}
-\permanent\def\sixthofsixarguments #-#-#-#-#-#1{#1}
-
-\permanent\protected\def\firstofoneunexpanded #1{#1}
-
-\permanent\protected\def\firstoftwounexpanded #1#-{#1}
-\permanent\protected\def\secondoftwounexpanded #-#1{#1}
-
-\permanent\protected\def\firstofthreeunexpanded #1#-#-{#1}
-\permanent\protected\def\secondofthreeunexpanded#-#1#-{#1}
-\permanent\protected\def\thirdofthreeunexpanded #-#-#1{#1}
-
-%D \macros
-%D {globalletempty,letempty,
-%D letvalueempty,letgvalueempty,
-%D letvaluerelax,letgvaluerelax}
-%D
-%D Trivial:
-
-\permanent\protected\def\letempty #1{\let #1\empty}
-\permanent\protected\def\globalletempty#1{\glet#1\empty}
-
-\permanent\protected\def\letvalueempty #1{\letcsname #1\endcsname\empty}
-\permanent\protected\def\letgvalueempty#1{\global\letcsname#1\endcsname\empty}
-\permanent\protected\def\letvaluerelax #1{\letcsname #1\endcsname\relax}
-\permanent\protected\def\letgvalurelax #1{\global\letcsname#1\endcsname\relax}
-
-\permanent\protected\def\relaxvalueifundefined#1%
- {\ifcsname#1\endcsname \else
- \letcsname#1\endcsname\relax
- \fi}
-
-%D \macros
-%D {wait}
-%D
-%D The next macro hardly needs explanation. Because no nesting is to be expected, we
-%D can reuse \type {\wait} within \type {\wait} itself.
-
-\protected\def\wait
- {\begingroup
- \read16 to \wait
- \endgroup}
-
-%D \macros
-%D {writestring,writeline,
-%D writestatus,statuswidth,normalwritestatus}
-%D
-%D Maybe one didn't notice, but we've already introduced a macro for showing
-%D messages. In the multi||lingual modules, we will also introduce a mechanism for
-%D message passing. For the moment we stick to the core macros:
-%D
-%D \starttyping
-%D \writestring {string}
-%D \writeline
-%D \writestatus {category} {message}
-%D \stoptyping
-%D
-%D Messages are formatted. One can provide the maximum with of the identification
-%D string with the macro \type {\statuswidth}.
-
-\setnewconstant\statuswidth 15
-%setnewconstant\statuswrite 128 % \pluscxxviii
-
-\ifdefined\writestring \else
-
- \protected\def\writestring{\immediate\write\statuswrite}
- \protected\def\writeline {\writestring{}}
-
-\fi
-
-\protected\def\normalwritestatus#1#2%
- {\writestring{\expandafter\syst_helpers_split_status_yes\expandafter\statuswidth#1%
- \space\space\space\space\space\space\space
- \space\space\space\space\space\space\space
- \space\space\space\space\space\space\end
- \space:\space#2}}
-
-\def\syst_helpers_split_status_yes#1#2%
- {\ifcase#1 \expandafter\syst_helpers_split_status_nop\fi#2%
- \expandafter\syst_helpers_split_status_yes\expandafter{\the\numexpr#1+\minusone\relax}}
-
-\def\syst_helpers_split_status_nop#1\end
- {}
-
-%D \macros
-%D {immediatemessage}
-%D
-%D A fully expandable message:
-
-\let\immediatemessage\clf_immediatemessage % {} mandate / todo permanent at lua end
-
-%D \macros
-%D {rawgetparameters}
-%D
-%D A raw and dirty alternative for \type {\getparameters}; no checking is done!
-
-\def\syst_helpers_grab_raw_parameter#1=#2,%
- {\ifarguments\or\or
- \defcsname\m_syst_parameter_n#1\endcsname{#2}%
- \expandafter\syst_helpers_grab_raw_parameter_next
- \fi}
-
-\def\syst_helpers_grab_raw_parameter_next
- {\expandafterspaces\syst_helpers_grab_raw_parameter}
-
-\permanent\protected\def\rawgetparameters#1[#2]#*[#3]%
- {\def\m_syst_parameter_n{#2}%
- %\expandafterspaces\syst_helpers_grab_raw_parameter#3\ignorearguments\ignorearguments}
- \expandafter\expandafterspaces\expandafter\syst_helpers_grab_raw_parameter#3\ignorearguments\ignorearguments}
-
-%D \macros
-%D {doglobal,
-%D redoglobal,dodoglobal,resetglobal}
-%D
-%D The two macros \type {\redoglobal} and \type{\dodoglobal} are used in this and
-%D some other modules to enforce a user specified \type {\doglobal} action. The last
-%D and often only global assignment in a macro is done with \type {\dodoglobal}, but
-%D all preceding ones with \type {\redoglobal}. When using only alternatives, one
-%D can reset this mechanism with \type {\resetglobal}.
-
-\permanent\protected\def\resetglobal
- {\enforced\let\redoglobal\relax
- \enforced\let\dodoglobal\relax}
-
-\resetglobal
-
-\permanent\protected\def\doglobal
- {\ifx\redoglobal\relax
- \enforced\let\redoglobal\global
- \enforced\let\dodoglobal\syst_helpers_dodo_global
- \fi}
-
-\def\syst_helpers_dodo_global
- {\resetglobal\global}
-
-\def\saveglobal
- {\let\syst_helpers_dodo_global\dodoglobal
- \let\syst_helpers_redo_global\redoglobal}
-
-\def\restoreglobal
- {\enforced\let\redoglobal\syst_helpers_redo_global
- \enforced\let\dodoglobal\syst_helpers_dodo_global}
-
-%D Whatever (will be overtoaded):
-
-\protected\def\define#1%
- {\ifdefined#1%
- \message{[\noexpand#1is already defined]}%
- \protected\expandafter\def\expandafter\gobbleddefinition
- \else
- \protected\expandafter\def
- \fi#1}
-
-\permanent\protected\def\redefine#1%
- {\ifdefined#1%
- \message{[\noexpand#1is redefined]}%
- \fi
- \protected\def#1}
-
-\permanent\protected\def\definemacro#1%
- {\ifdefined#1%
- \message{[\noexpand#1is already defined]}%
- \protected\expandafter\def\expandafter\gobbleddefinition
- \else
- \protected\expandafter\def
- \fi#1}
-
-% \define\hans{hans}
-% \redefine\hans{hans}
-% \define\hans#1[]#2#3{hans}
-
-%D The next variant fits nicely in the setups syntax:
-%D
-%D \starttyping
-%D \starttexdefinition bagger [#1] #2
-%D oeps
-%D #1
-%D oeps
-%D \stoptexdefinition
-%D
-%D \bagger [a] {b}
-%D \stoptyping
-
-% \starttexdefinition test
-% oeps
-% \stoptexdefinition
-%
-% [\test]
-
-\bgroup \obeylines
-
-\permanent\protected\gdef\starttexdefinition%
- {\bgroup%
- \obeylines%
- \syst_helpers_start_tex_definition}
-
-\gdef\syst_helpers_start_tex_definition#1
- {\catcode\endoflineasciicode\ignorecatcode%
- \clf_texdefinition_one{#1}}
-
-\aliased\glet\stoptexdefinition\relax
-
-\permanent\gdef\dostarttexdefinition#1\stoptexdefinition%
- {\egroup%
- \clf_texdefinition_two{#1}}
-
-\egroup
-
-% \protected\def\texdefinition#1{\csname\ifcsname#1\endcsname#1\else donothing\fi\endcsname} % todo: a nop cs: char 0 or some corenamespace
-
-\permanent\protected\def\texdefinition#1{\begincsname#1\endcsname}
-
-%D \macros
-%D {newcounter,
-%D increment,decrement}
-%D
-%D Unfortunately the number of \COUNTERS\ in \TEX\ is limited, but fortunately we
-%D can store numbers in a macro. We can increment such pseudo \COUNTERS\ with \type
-%D {\increment}.
-%D
-%D \starttyping
-%D \increment(\counter,20)
-%D \increment(\counter,-4)
-%D \increment(\counter)
-%D \increment\counter
-%D \stoptyping
-%D
-%D After this sequence of commands, the value of \type {\counter} is 20, 16, 17
-%D and~18. Of course there is also the complementary command \type {\decrement}.
-%D
-%D Global assignments are possible too, using \type{\doglobal}:
-%D
-%D \starttyping
-%D \doglobal\increment\counter
-%D \stoptyping
-%D
-%D When \type {\counter} is undefined, it's value is initialized at~0. It is
-%D nevertheless better to define a \COUNTER\ explicitly. One reason could be that
-%D the \COUNTER\ can be part of a test with \type {\ifnum} and this conditional does
-%D not accept undefined macro's. The \COUNTER\ in our example can for instance be
-%D defined with:
-%D
-%D \starttyping
-%D \newcounter\counter
-%D \stoptyping
-%D
-%D The command \type {\newcounter} must not be confused with \type {\newcount}! Of
-%D course this mechanism is much slower than using \TEX's \COUNTERS\ directly. In
-%D practice \COUNTERS\ (and therefore our pseudo counters too) are seldom the
-%D bottleneck in the processing of a text. Apart from some other incompatilities we
-%D want to mention a pitfal when using \type {\ifnum}.
-%D
-%D \starttyping
-%D \ifnum\normalcounter=\pseudocounter \doif \else \doelse \fi
-%D \ifnum\pseudocounter=\normalcounter \doif \else \doelse \fi
-%D \stoptyping
-%D
-%D In the first test, \TEX\ continues it's search for the second number after
-%D reading \type {\pseudocounter}, while in the second test, it stops reading after
-%D having encountered a real one. Tests like the first one therefore can give
-%D unexpected results, for instance execution of \type {\doif} even if both numbers
-%D are unequal.
-
-\def\zerocountervalue{0}
-
-\permanent\protected\def\newcounter#1%
- {\dodoglobal\let#1\zerocountervalue}
-
-%D Nowadays we don't mind a few more tokens if we can gain a bit of speed.
-
-\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\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\syst_helpers_do_do_increment(#1%
- {\def\m_syst_action_yes{\syst_helpers_do_do_do_increment#1}%
- \def\m_syst_action_nop{\syst_helpers_do_do_do_increment#1,\plusone}%
- \doifelsenextcharcs,\m_syst_action_yes\m_syst_action_nop}
-
-\def\syst_helpers_do_do_decrement(#1%
- {\def\m_syst_action_yes{\syst_helpers_do_do_do_decrement#1}%
- \def\m_syst_action_nop{\syst_helpers_do_do_do_decrement#1,\plusone}%
- \doifelsenextcharcs,\m_syst_action_yes\m_syst_action_nop}
-
-\permanent\protected\def\increment{\doifelsenextcharcs(\syst_helpers_do_do_increment\syst_helpers_do_increment}
-\permanent\protected\def\decrement{\doifelsenextcharcs(\syst_helpers_do_do_decrement\syst_helpers_do_decrement}
-
-\permanent\protected\def\fastincrement#1{\dodoglobal\edef#1{\the\numexpr#1+\plusone \relax}}
-\permanent\protected\def\fastdecrement#1{\dodoglobal\edef#1{\the\numexpr#1+\minusone\relax}}
-
-\permanent\protected\def\incrementvalue#1{\expandafter\increment\csname#1\endcsname}
-\permanent\protected\def\decrementvalue#1{\expandafter\decrement\csname#1\endcsname}
-
-%D \macros
-%D {newsignal}
-%D
-%D When writing advanced macros, we cannot do without signaling. A signal is a small
-%D (invisible) kern or penalty that signals the next macro that something just
-%D happened. This macro can take any action depending on the previous signal.
-%D Signals must be unique and the next macro takes care of that.
-%D
-%D \starttyping
-%D \newsignal\somesignal
-%D \stoptyping
-%D
-%D Signals old dimensions and can be used in skips, kerns and tests like \type
-%D {\ifdim}.
-
-\newdimen\d_syst_maximum_signal % step is about 0.00025pt
-
-\permanent\protected\def\newsignal#1%
- {\ifdefined#1\else
- \advance\d_syst_maximum_signal2\scaledpoint % to be save in rounding
- \immutable\dimensiondef#1\d_syst_maximum_signal
- \fi}
-
-%D \macros
-%D {strippedcsname}
-%D
-%D The next macro can be very useful when using \type {\csname} like in:
-%D
-%D \starttyping
-%D \csname if\strippedcsname\something\endcsname
-%D \stoptyping
-
-\aliased\let\checkedstrippedcsname\csstring
-
-%D \macros
-%D {savenormalmeaning}
-%D
-%D We will use this one in:
-
-\permanent\protected\def\savenormalmeaning#1%
- {\ifcsname normal\csstring#1\endcsname \else
- \letcsname normal\csstring#1\endcsname#1%
- \fi}
-
-%D \macros
-%D {dorecurse,recurselevel,recursedepth,
-%D dostepwiserecurse}
-%D
-%D \TEX\ does not offer us powerfull for||loop mechanisms. On the other hand its
-%D recursion engine is quite unique. We therefore identify the for||looping macros
-%D by this method. The most simple alternative is the one that only needs a number.
-%D
-%D \starttyping
-%D \dorecurse {n} {whatever we want}
-%D \stoptyping
-%D
-%D This macro can be nested without problems and therefore be used in situations
-%D where \PLAIN\ \TEX's \type {\loop} macro ungracefully fails. The current value of
-%D the counter is available in \type {\recurselevel}, before as well as after the
-%D \typ {whatever we wat} stuff.
-%D
-%D \starttyping
-%D \dorecurse % inner loop
-%D {10}
-%D {\recurselevel: % outer value
-%D \dorecurse % inner loop
-%D {\recurselevel} % outer value
-%D {\recurselevel} % inner value
-%D \dorecurse % inner loop
-%D {\recurselevel} % outer value
-%D {\recurselevel} % inner value
-%D \endgraf}
-%D \stoptyping
-%D
-%D In this example the first, second and fourth \type {\recurselevel} concern the
-%D outer loop, while the third and fifth one concern the inner loop. The depth of
-%D the nesting is available for inspection in \type {\recursedepth}.
-%D
-%D Both \type {\recurselevel} and \type {\recursedepth} are macros. The real
-%D \COUNTERS\ are hidden from the user because we don't want any interference.
-%D
-%D We now use the macro stack which is somewhat leaner and meaner and a little
-%D faster too.
-
-% left overs: too much \protected here
-
-\newcount\outerrecurse
-\newcount\innerrecurse
-
-\def\recursedepth{\the\outerrecurse}
-\def\recurselevel{0}
-
-\let\recurseaction\relax
-\let\recursestring\empty
-
-% \let\syst_helpers_stepwise_next\relax
-
-% \protected\def\syst_helpers_stepwise_recurse#1#2#3% from to step
-% {\ifnum#1>#2\relax
-% \expandafter\syst_helpers_stepwise_recurse_nop
-% \else
-% \def\recurselevel{#1}%
-% \doubleexpandafter\syst_helpers_stepwise_recurse_yes\expandafter
-% \fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}}
-
-\protected\def\syst_helpers_stepwise_recurse#1#2#3% from to step
- {\ifnum#1>#2\relax
- \expandafter\gobblefourarguments
- \else
- \def\recurselevel{#1}%
-% \doubleexpandafter\syst_helpers_stepwise_recurse_yes\expandafter
-% \fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}}
- \doubleexpandafter\syst_helpers_stepwise_recurse_yes
- \fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}}
-
-\protected\def\syst_helpers_stepwise_recurse_yes
- {\syst_helpers_recurse_content
- \syst_helpers_stepwise_recurse}
-
-\protected\def\syst_helpers_stepwise_reverse#1#2#3% from to step
- {\ifnum#1<#2\relax
-% \expandafter\syst_helpers_stepwise_recurse_nop
- \expandafter\gobblefourarguments
- \else
- \def\recurselevel{#1}%
- \innerrecurse#1\relax
- \advance\innerrecurse#3\relax
-% \doubleexpandafter\syst_helpers_stepwise_reverse_yes\expandafter
-% \fi\expandafter{\the\innerrecurse}{#2}{#3}}
- \doubleexpandafter\syst_helpers_stepwise_reverse_yes
- \fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}}
-
-\protected\def\syst_helpers_stepwise_reverse_yes
- {\syst_helpers_recurse_content
- \syst_helpers_stepwise_reverse}
-
-% \protected\def\syst_helpers_stepwise_exit
-% {\syst_helpers_stepwise_recurse_nop\relax}
-
-\permanent\def\doexpandedrecurse#1#2% user macro (also was \doxprecurse)
- {\ifnum#1>\zerocount
- #2\expandafter\doexpandedrecurse\expandafter{\the\numexpr#1-\plusone\relax}{#2}%
- \fi}
-
-%D As we can see here, the simple command \type{\dorecurse} is a special case of the
-%D more general:
-%D
-%D \starttyping
-%D \dostepwiserecurse {from} {to} {step} {action}
-%D \stoptyping
-%D
-%D This commands accepts positive and negative steps. Illegal values are handles as
-%D good as possible and the macro accepts numbers and \COUNTERS.
-%D
-%D \starttyping
-%D \dostepwiserecurse {1} {10} {2} {...}
-%D \dostepwiserecurse {10} {1} {-2} {...}
-%D \stoptyping
-%D
-%D Because the simple case (n=1) is used often, we implement it more efficiently:
-
-\permanent\protected\def\dorecurse#1%
- {\ifcase#1\relax
- \expandafter\gobbletwoarguments
- \or
- \expandafter\syst_helpers_recurse_y
- \else
- \expandafter\syst_helpers_recurse_x
- \fi{#1}}
-
-\protected\def\syst_helpers_recurse_indeed#1#2% from to
-% {\ifnum#1>#2 %
- {\ifnum#1>#2\relax
- \expandafter\syst_helpers_recurse_indeed_nop
- \else
- \def\recurselevel{#1}%
- \innerrecurse#1\advance\innerrecurse\plusone
- \doubleexpandafter\syst_helpers_recurse_indeed_yes
- \fi\expandafter{\the\innerrecurse}{#2}}
-
-\protected\def\syst_helpers_recurse_indeed_yes
- {\syst_helpers_recurse_content
- \syst_helpers_recurse_indeed}
-
-\protected\def\syst_helpers_recurse_indeed_nop#0#0#0%
- {}
-
-%D \macros
-%D {dowith}
-%D
-%D Here's a loop over whatever is in a list:
-%D
-%D \starttyping
-%D \dowith{a,b,c}{[#1]}
-%D \stoptyping
-
-\permanent\protected\def\dowith#1#2%
- {\def\syst_helpers_with##1{#2}%
- \normalexpanded{\processcommalist[#1]}\syst_helpers_with}
-
-%D \macros
-%D {doloop,exitloop}
-%D
-%D Sometimes loops are not determined by counters, but by (a combinations of)
-%D conditions. We therefore implement a straightforward loop, which can only be left
-%D when we explictly exit it. Nesting is supported. First we present a more
-%D extensive alternative.
-%D
-%D \starttyping
-%D \doloop
-%D {Some kind of typesetting punishment \par
-%D \ifnum\pageno>100 \exitloop \fi}
-%D \stoptyping
-%D
-%D When needed, one can call for \type {\looplevel} and \type {\loopdepth}.
-
-\aliased\let\endofloop\donothing % maybe \syst_helpers_loop_end
-
-\permanent\protected\def\doloop#1%
- {\global\advance\outerrecurse \plusone
- \globalpushmacro\recurseaction
- \globalpushmacro\recurselevel
- \protected\gdef\recurseaction##1##2{#1}%
- \enforced\let\endofloop\syst_helpers_loop
- \syst_helpers_loop1}% no \plusone else \recurselevel wrong
-
-\protected\def\syst_helpers_loop#1%
- {\def\recurselevel{#1}%
- \expandafter\syst_helpers_loop_yes\expandafter{\the\numexpr\recurselevel+\plusone\relax}}
-
-\protected\def\syst_helpers_loop_yes
- {\syst_helpers_recurse_content
- \endofloop}
-
-\protected\def\syst_helpers_loop_nop#0%
- {\enforced\let\endofloop\syst_helpers_loop
- \globalpopmacro\recurselevel
- \globalpopmacro\recurseaction
- \global\advance\outerrecurse\minusone}
-
-\permanent\protected\def\exitloop % \exitloop quits at end
- {\enforced\let\endofloop\syst_helpers_loop_nop}
-
-\permanent\protected\def\exitloopnow#0\endofloop % \exitloopnow quits directly
- {\syst_helpers_loop_nop}
-
-%D The loop is executed at least once, so beware of situations like:
-%D
-%D \starttyping
-%D \doloop {\exitloop some commands}
-%D \stoptyping
-%D
-%D It's just a matter of putting the text into the \type {\if} statement that should
-%D be there anyway, like in:
-%D
-%D \starttyping
-%D \doloop {\ifwhatever \exitloop \else some commands\fi}
-%D \stoptyping
-%D
-%D You can also quit a loop immediately, by using \type
-%D {\exitloopnow} instead. Beware, this is more sensitive
-%D for conditional errors.
-
-%D Krzysztof Leszczynski suggested to provide access to the level by means of a
-%D \type {#1}. I decided to pass the more frequently used level as \type {#1} and
-%D the less favoured depth as \type {#2}. The intended usage is:
-%D
-%D \starttyping
-%D \dorecurse{3}{\definesymbol[test-#1][xx-#1]}
-%D
-%D \def\test{\dorecurse{3}{\definesymbol[test-##1][xx-##1]}} \test
-%D
-%D \symbol[test-1]\quad\symbol[test-2]\quad\symbol[test-3]
-%D \stoptyping
-%D
-%D Since the hashed arguments are expanded, we don't need tricky expansion here.
-%D
-%D \starttyping
-%D \dorecurse{3}{\expanded{\definesymbol[test-\recurselevel][xx-\recurselevel]}}
-%D \stoptyping
-
-\def\syst_helpers_recurse_content
- {\normalexpanded{\recurseaction{\recurselevel}{\the\outerrecurse}}}
-
-\protected\def\syst_helpers_recurse_x#1#2%
- {\global\advance\outerrecurse\plusone
- \globalpushmacro\recurseaction
- \globalpushmacro\recurselevel
- \protected\gdef\recurseaction##1##2{#2}%
- \expandafter\syst_helpers_recurse_indeed\expandafter1\expandafter{\number#1}%
- \globalpopmacro\recurselevel
- \globalpopmacro\recurseaction
- \global\advance\outerrecurse\minusone}
-
-\protected\def\syst_helpers_recurse_y#1#2%
- {\global\advance\outerrecurse\plusone
- \globalpushmacro\recurseaction
- \globalpushmacro\recurselevel
- \let\recurselevel\!!plusone
- \protected\gdef\recurseaction##1##2{#2}%
- \syst_helpers_recurse_content
- \globalpopmacro\recurselevel
- \globalpopmacro\recurseaction
- \global\advance\outerrecurse\minusone}
-
-% \protected\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
-% {\global\advance\outerrecurse \plusone
-% \globalpushmacro\recurseaction
-% \globalpushmacro\recurselevel
-% \protected\gdef\recurseaction##1##2{#4}%
-% \normalexpanded{\ifcmpnum#3\zerocount
-% \ifnum#1<#2\relax\relax % so we catch \number\numexpr xx without \relax's
-% \syst_helpers_stepwise_exit
-% \else
-% \syst_helpers_stepwise_reverse
-% \fi
-% \or
-% \syst_helpers_stepwise_exit
-% \or
-% \ifnum#2<#1\relax\relax % so we catch \number\numexpr xx without \relax's
-% \syst_helpers_stepwise_exit
-% \else
-% \syst_helpers_stepwise_recurse
-% \fi
-% \fi{\number#1}{\number#2}{\number#3}}%
-% \globalpopmacro\recurselevel
-% \globalpopmacro\recurseaction
-% \global\advance\outerrecurse\minusone}
-
-\permanent\protected\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 ... todo: remove unused helpers
- {\global\advance\outerrecurse \plusone
- \globalpushmacro\recurseaction
- \globalpushmacro\recurselevel
- \protected\gdef\recurseaction##1##2{#4}%
- \normalexpanded{\ifcmpnum#3\zerocount
- \ifnum#1<#2\relax\relax % so we catch \number\numexpr xx without \relax's
- \doubleexpandafter\gobbletwoarguments
- \else
- \tripleexpandafter\syst_helpers_stepwise_reverse
- \fi
- \or
- \doubleexpandafter\gobbletwoarguments
- \orelse\ifnum#2<#1\relax\relax % so we catch \number\numexpr xx without \relax's
- \doubleexpandafter\gobbletwoarguments
- \else
- \doubleexpandafter\syst_helpers_stepwise_recurse
- \fi\normalexpanded{{\number#1}{\number#2}{\number#3}}}%
- \globalpopmacro\recurselevel
- \globalpopmacro\recurseaction
- \global\advance\outerrecurse\minusone}
-
-% \protected\def\syst_helpers_stepwise_recurse_nop#0#0#0#0%
-% {}
-
-\newcount\fastloopindex
-\newcount\fastloopfinal
-
-\let\m_syst_helpers_fast_loop_cs\relax
-
-\permanent\protected\def\dofastloopcs#1%
- {\fastloopfinal#1\relax
- \ifcase\fastloopfinal
- \expandafter\gobbleoneargument
- \else
- \expandafter\syst_helpers_fast_loop_cs
- \fi}
-
-\protected\def\syst_helpers_fast_loop_cs#1%
- {\let\m_syst_helpers_fast_loop_cs#1%
- \fastloopindex\plusone
- \syst_helpers_fast_loop_cs_step}
-
-\protected\def\syst_helpers_fast_loop_cs_step
- {\ifnum\fastloopindex>\fastloopfinal
- \let\m_syst_helpers_fast_loop_cs\relax
- \else
- \m_syst_helpers_fast_loop_cs
- \advance\fastloopindex\plusone
- \expandafter\syst_helpers_fast_loop_cs_step
- \fi}
-
-% Helper:
-
-\permanent\protected\def\resetrecurselevel{\let\recurselevel\!!zerocount}
-
-\let\recurselevel\!!zerocount
-
-% \appendtoks \resetrecurselevel \to \everydump
-
-%D \macros
-%D {doloopoverlist}
-%D
-%D \starttyping
-%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 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
-
-\permanent\protected\def\doloopoverlist#1#2%
- {\global\advance\outerrecurse\plusone
- \globalpushmacro\recurseaction
- \globalpushmacro\recursestring
- \protected\gdef\recurseaction##1{\edef\recursestring{##1}#2}%
- \processcommacommand[#1]\recurseaction
- \globalpopmacro\recursestring
- \globalpopmacro\recurseaction
- \global\advance\outerrecurse\minusone}
-
-%D This is some \LMTX\ experiment:
-%D
-%D Think of:
-%D
-%D \starttyping
-%D \domatch {(\letterpercent w+) *(\letterpercent w*)} {aa bb cc dd} {
-%D [
-%D \domatch{(\letterpercent w)(\letterpercent w)} {#1} {(##1 ##2)}
-%D \domatch{(\letterpercent w)(\letterpercent w)} {#2} {(##1 ##2)}
-%D ]
-%D }
-%D
-%D and:
-%D
-%D \stoptyping
-%D
-%D \starttyping
-%D \def\MyMacro#1{(#1)} \ctxluamatch \MyMacro {(.)} {abcd}
-%D \stoptyping
-
-\permanent\protected\def\doloopovermatch#1#2#3%
- {\pushmacro\matchloopcommand
- \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}%
- \ctxluamatch\matchloopcommand{#1}{#2}%
- \popmacro\matchloopcommand}
-
-\permanent\def\doloopovermatched#1#2#3%
- {\beginlocalcontrol
- \pushmacro\matchloopcommand
- \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}%
- \endlocalcontrol
- \the\ctxluamatch\matchloopcommand{#1}{#2}%
- \beginlocalcontrol
- \popmacro\matchloopcommand
- \endlocalcontrol}
-
-%D \macros
-%D {newevery,everyline,EveryLine,EveryPar}
-%D
-%D Lets skip to something quite different. It's common use to use \type {\everypar}
-%D for special purposes. In \CONTEXT\ we use this primitive for locating sidefloats.
-%D This means that when user assignments to \type {\everypar} can interfere with
-%D those of the package. We therefore introduce \type {\EveryPar}.
-%D
-%D The same goes for \type {\EveryLine}. Because \TEX\ offers no \type {\everyline}
-%D primitive, we have to call for \type {\everyline} when we are working on a line
-%D by line basis. Just by calling \type {\EveryPar{}} and \type {\EveryLine{}} we
-%D restore the old situation.
-
-% \dorecurse{2}{
-% \expanded{\everypar{before \recurselevel\space}}
-% \EveryPar{x } [before \recurselevel\space x] \par
-% \EveryPar{y } [before \recurselevel\space y] \par
-% \EveryPar{} [before \recurselevel] \par
-% \EveryPar{x } \EveryPar{y } \EveryPar{} [before \recurselevel] \par
-% \EveryPar{y } \everypar{before } [before] \par
-% }
-
-\installsystemnamespace{extraevery}
-
-\permanent\protected\def\newevery#1#2%
- {\ifx#1\everypar\else\newtoks#1\fi% we test for redefinition elsewhere
- \ifx#2\relax\orelse\ifdefined#2\else
- \expandafter\newtoks\csname\??extraevery\csstring#1\endcsname
- \frozen\protected\edef#2{\syst_helpers_every#1\csname\??extraevery\csstring#1\endcsname}%
- \fi}
-
-\protected\def\syst_helpers_every#1#2%
- {\removetoks\the#2\from#1%
- \appendtoks\the#2\to #1%
- #2}
-
-%D This one permits definitions like:
-
-\newevery \everypar \EveryPar % we get a warning which is ok
-\newevery \everyline \EveryLine
-
-%D and how about:
-
-\newtoks \neverypar
-
-\permanent\protected\def\forgeteverypar
- {\everypar{\the\neverypar}}
-
-%D Which we're going to use indeed! When the second argument equals \type {\relax},
-%D the first token list is created unless it is already defined.
-%D
-%D Technically spoken we could have used the method we are going to present in the
-%D visual debugger. First we save the primitive \type{\everypar}:
-%D
-%D \starttyping
-%D \let\normaleverypar=\everypar
-%D \stoptyping
-%D
-%D Next we allocate a \TOKENLIST\ named \type{\everypar}, which means that
-%D \type{\everypar} is no longer a primitive but something like \type{\toks44}.
-%D
-%D \starttyping
-%D \newtoks\everypar
-%D \stoptyping
-%D
-%D Because \TEX\ now executes \type{\normaleverypar} instead of \type{\everypar}, we
-%D are ready to assign some tokens to this internally known and used \TOKENLIST.
-%D
-%D \starttyping
-%D \normaleverypar={all the things the system wants to do \the\everypar}
-%D \stoptyping
-%D
-%D Where the user can provide his own tokens to be expanded every time he expects
-%D them to expand.
-%D
-%D \starttyping
-%D \everypar={something the user wants to do}
-%D \stoptyping
-%D
-%D We don't use this method because it undoubtly leads to confusing situations,
-%D especially when other packages are used, but it's this kind of tricks that make
-%D \TEX\ so powerful.
-
-%D \macros
-%D {convertargument,convertcommand,convertvalue}
-%D
-%D Some persistent experimenting led us to the next macro. This macro converts a
-%D parameter or an expanded macro to it's textual meaning.
-%D
-%D \starttyping
-%D \convertargument ... \to \command
-%D \stoptyping
-%D
-%D For example,
-%D
-%D \starttyping
-%D \convertargument{one \two \three{four}}\to\ascii
-%D \stoptyping
-%D
-%D The resulting macro \type{\ascii} can be written to a file or the terminal
-%D without problems. In \CONTEXT\ we use this macro for generating registers and
-%D tables of contents.
-%D
-%D The second conversion alternative accepts a command:
-%D
-%D \starttyping
-%D \convertcommand\command\to\ascii
-%D \stoptyping
-%D
-%D Both commands accept the prefix \type{\doglobal} for global assignments.
-
-\permanent\protected\def\convertvalue#1\to
- {\expandafter\convertcommand\csname#1\endcsname\to}
-
-\permanent\protected\def\defconvertedvalue#1#2% less sensitive for \to
- {\expandafter\defconvertedcommand\expandafter#1\csname#2\endcsname}
-
-%D \macros
-%D {doifassignmentelse}
-%D
-%D A lot of \CONTEXT\ commands take optional arguments, for instance:
-%D
-%D \starttyping
-%D \dothisorthat[alfa,beta]
-%D \dothisorthat[first=foo,second=bar]
-%D \dothisorthat[alfa,beta][first=foo,second=bar]
-%D \stoptyping
-%D
-%D Although a combined solution is possible, we prefer a seperation. The next
-%D command takes care of propper handling of such multi||faced commands.
-%D
-%D \starttyping
-%D \doifassignmentelse {...} {then ...} {else ...}
-%D \stoptyping
-%D
-%D So
-%D \startbuffer
-%D \doifelseassignment{a=b}{Y}{N}
-%D \doifelseassignment{a+b}{Y}{N}
-%D
-%D \ifcondition\validassignment {a=b}Y\else N\fi
-%D \ifcondition\novalidassignment{a=b}N\else Y\fi
-%D \ifcondition\novalidassignment {ab}Y\else N\fi
-%D \stopbuffer
-%D
-%D \typebuffer gives: \blank \getbuffer \blank
-
-\permanent\protected\def\doifelseassignment#1%
- {\ifhastok={#1}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\permanent\protected\def\doifelseassignmentcs#1#2#3%
- {\ifhastok={#1}%
- \expandafter#2%
- \else
- \expandafter#3%
- \fi}
-
-\aliased\let\doifassignmentelse \doifelseassignment
-\aliased\let\doifassignmentelsecs\doifelseassignmentcs
-
-\newif\ifassignment
-
-\permanent\protected\def\docheckassignment#1%
- {\ifhastok={#1}%
- \assignmenttrue
- \else
- \assignmentfalse
- \fi}
-
-\permanent\protected\def\validassignment #1{\ifhastok={#1}} % can become: {\ifhastok=} as we enforce {}
-\permanent\protected\def\novalidassignment#1{\ifnum\ifhastok={#1}\zerocount\else\plusone\fi=\plusone} % or use unless
-
-%D In \ETEX\ we can use \type {\detokenize} and gain some speed, but in general far
-%D less that 1\% for \type {\convertargument} and nil for \type {\convertcommand}.
-%D This macro is more robust than the pure \TEX\ one, something I found out when
-%D primitives like \type {\jobname} were fed (or something undefined).
-
-\permanent\protected\def\convertargument#1\to#2{\dodoglobal\edef#2{\detokenize{#1}}}
-\permanent\protected\def\convertcommand #1\to#2{\dodoglobal\edef#2{\expandafter\detokenize\expandafter{#1}}} % hm, only second is also ok
-
-\permanent\protected\def\defconvertedargument #1#2{\edef#1{\detokenize{#2}}}
-\permanent\protected\def\defconvertedcommand #1#2{\edef#1{\detokenize\expandafter{#2}}}
-\permanent\protected\def\edefconvertedargument#1#2{\edef#1{#2}%
- \edef#1{\detokenize\expandafter{#1}}}
-\permanent\protected\def\gdefconvertedargument#1#2{\xdef#1{\detokenize{#2}}}
-\permanent\protected\def\gdefconvertedcommand #1#2{\xdef#1{\detokenize\expandafter{#2}}}
-\permanent\protected\def\xdefconvertedargument#1#2{\xdef#1{#2}%
- \xdef#1{\detokenize\expandafter{#1}}}
-
-%D When you try to convert a primitive command, you'll find out that the \ETEX\
-%D method fails on for instance \type {\jobname} in the sense that it returns the
-%D filename instead of just \type {\jobname}. So far this does not give real
-%D problems.
-
-%D This is typically a macro that one comes to after reading the \TEX book
-%D carefully. Even then, the definite solution was found after rereading the \TEX
-%D book. The first implementation was:
-%D
-%D \starttyping
-%D \def\doconvertargument#1->#2\\\\{#2}
-%D \stoptyping
-%D
-%D The \type {-}, the delimiter \type {\\\\} and the the second argument are
-%D completely redundant.
-
-%D \macros
-%D {showvalue}
-%D
-%D Ahandy macro, for testing purposes only:
-
-\permanent\protected\def\showvalue#1%
- {\ifcsname#1\endcsname
- \expandafter\show\csname#1\endcsname
- \else
- \show\undefined
- \fi}
-
-%D \macros
-%D {doifmeaningelse}
-%D
-%D We can use both commands in testing, but alas, not all meanings expand to
-%D something \type {->}. This is no problem in the \ETEX\ implementation, but since
-%D we want compatibility, we need:
-%D
-%D \starttyping
-%D \doifmeaningelse {\next} {\something} {true} {false}
-%D \stoptyping
-%D
-%D Watch the one level expansion of the second argument.
-
-\permanent\protected\def\doifelsemeaning#1#2%
- {\edef\m_syst_string_one{\normalmeaning#1}%
- \def \m_syst_string_two{#2}%
- \edef\m_syst_string_two{\normalmeaning\m_syst_string_two}%
- \ifx\m_syst_string_one\m_syst_string_two
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifmeaningelse\doifelsemeaning
-
-%D \macros
-%D {doifsamestringselse,doifsamestring,doifnotsamestring}
-%D
-%D The next comparison macro converts the arguments into expanded strings. This
-%D command can be used to compare for instance \type {\jobname} with a name stored
-%D in a macro.
-%D
-%D \starttyping
-%D \doifelse {\jobname}{oeps}{YES}{NO}
-%D \doifsamestringelse{\jobname}{oeps}{YES}{NO}
-%D \stoptyping
-
-\def\syst_helpers_if_samestring_else#1#2#3#4%
- {\edef\m_syst_string_one{\detokenize\expandafter{\normalexpanded{#3}}}%
- \edef\m_syst_string_two{\detokenize\expandafter{\normalexpanded{#4}}}%
- \ifx\m_syst_string_one\m_syst_string_two\expandafter#1\else\expandafter#2\fi}
-
-\permanent\protected\def\doifelsesamestring{\syst_helpers_if_samestring_else\firstoftwoarguments\secondoftwoarguments}
-\permanent\protected\def\doifsamestring {\syst_helpers_if_samestring_else\firstofoneargument \gobbleoneargument }
-\permanent\protected\def\doifnotsamestring {\syst_helpers_if_samestring_else\gobbleoneargument \firstofoneargument }
-
-\aliased\let\doifsamestringelse\doifelsesamestring
-
-%D These are obsolete in MTX:
-%D
-%D \starttyping
-%D \ConvertToConstant #1#2#3
-%D \CheckConstantAfter #1#2
-%D \ConvertConstantAfter #1#2#3
-%D \stoptyping
-
-%D \macros
-%D {assignifempty}
-%D
-%D We can assign a default value to an empty macro using:
-%D
-%D \starttyping
-%D \assignifempty \macros {default value}
-%D \stoptyping
-%D
-%D We don't explicitly test if the macro is defined.
-
-\permanent\protected\def\assignifempty#1#2%
- {\iftok{#1}\emptytoks \def#1{#2}\fi}
-
-%D \macros
-%D {gobbleuntil,grabuntil,gobbleuntilrelax,
-%D processbetween,processuntil}
-%D
-%D In \TEX\ gobbling usually stand for skipping arguments, so here are our gobbling
-%D macros.
-%D
-%D In \CONTEXT\ we use a lot of \type {\start}||\type {\stop} like constructions.
-%D Sometimes, the \type {\stop} is used as a hard coded delimiter like in: %D
-%D \starttyping
-%D \protected\def\startcommand#1\stopcommand%
-%D {... #1 ...}
-%D \stoptyping
-%D
-%D In many cases the \type {\start}||\type {\stop} pair is defined at format
-%D generation time or during a job. This means that we cannot hardcode the \type
-%D {\stop} criterium. Only after completely understanding \type {\csname} and \type
-%D {\expandafter} I was able to to implement a solution, starting with:
-%D
-%D \starttyping
-%D \grabuntil{stop}\command
-%D \stoptyping
-%D
-%D This commands executes, after having encountered \type {\stop} the command \type
-%D {\command}. This command receives as argument the text preceding the \type
-%D {\stop}. This means that:
-%D
-%D \starttyping
-%D \protected\def\starthello%
-%D {\grabuntil{stophello}\message}
-%D
-%D \starthello Hello world!\stophello
-%D \stoptyping
-%D
-%D results in: \type{\message{Hello world!}}.
-
-\let\syst_helpers_grab_indeed\relax
-
-\protected\def\syst_helpers_grab#1#2%
- {\def\syst_helpers_grab_indeed##1#1{#2{##1}}\syst_helpers_grab_indeed}
-
-\permanent\protected\def\grabuntil#1%
- {\expandafter\syst_helpers_grab\expandafter{\csname#1\endcsname}}
-
-%D The next command build on this mechanism:
-%D
-%D \starttyping
-%D \processbetween{string}\command
-%D \stoptyping
-%D
-%D Here:
-%D
-%D \starttyping
-%D \processbetween{hello}\message
-%D \starthello Hello again!\stophello
-%D \stoptyping
-%D
-%D leads to: \type{\message{Hello again!}}. The command
-%D
-%D \starttyping
-%D \gobbleuntil{sequence}
-%D \stoptyping
-%D
-%D is related to these commands. This one simply throws away
-%D everything preceding \type{\command}.
-
-\let\syst_helpers_gobble_indeed\relax
-
-\permanent\protected\def\processbetween#1#2%
- {\setvalue{\s!start#1}{\grabuntil{\s!stop#1}{#2}}}
-
-% \protected\def\gobbleuntil#1%
-% {\def\syst_helpers_gobble_indeed##1#1{}\syst_helpers_gobble_indeed}
-%
-% \protected\def\gobbleuntilrelax#1\relax
-% {}
-
-\permanent\protected\def\gobbleuntil#1%
- {\def\syst_helpers_gobble_indeed##-#1{}\syst_helpers_gobble_indeed}
-
-\permanent\protected\def\gobbleuntilrelax#-\relax
- {}
-
-%D The next one simply expands the pickup up tokens.
-%D
-%D \starttyping
-%D \processuntil{sequence}
-%D \stoptyping
-
-\let\syst_helpers_until_indeed\relax
-
-\permanent\protected\def\processuntil#1%
- {\def\syst_helpers_until_indeed##1#1{##1}\syst_helpers_until_indeed}
-
-%D \macros
-%D {groupedcommand}
-%D
-%D Commands often manipulate argument as in:
-%D
-%D \starttyping
-%D \def\doezomaarwat#1{....#1....}
-%D \stoptyping
-%D
-%D A disadvantage of this approach is that the tokens that form \type{#1} are fixed
-%D the the moment the argument is read in. Normally this is no problem, but for
-%D instance verbatim environments adapt the \CATCODES\ of characters and therefore
-%D are not always happy with already fixed tokens.
-%D
-%D Another problem arises when the argument is grouped not by \type {{}} but by
-%D \type {\bgroup} and \type {\egroup}. Such an argument fails, because the \type
-%D {\bgroup} is een as the argument (which is quite normal).
-%D
-%D The next macro offers a solution for both unwanted situations:
-%D
-%D \starttyping
-%D \groupedcommand {before} {after}
-%D \stoptyping
-%D
-%D Which can be used like:
-%D
-%D \starttyping
-%D \def\cite%
-%D {\groupedcommand{\rightquote\rightquote}{\leftquote\leftquote}}
-%D \stoptyping
-%D
-%D This command is equivalent to, but more 'robust' than:
-%D
-%D \starttyping
-%D \def\cite#1%
-%D {\rightquote\rightquote#1\leftquote\leftquote}
-%D \stoptyping
-%D
-%D \starttyping
-%D \def\rightword%
-%D {\groupedcommand{\hfill\hbox}{\parfillskip\zeropoint}}
-%D
-%D .......... \rightword{the right way}
-%D \stoptyping
-%D
-%D Here \TEX\ typesets \type {\bf the right way} unbreakable at the end of the line.
-%D The solution mentioned before does not work here. We also handle
-%D
-%D \starttyping
-%D to be \bold{bold} or not, that's the question
-%D \stoptyping
-%D
-%D and
-%D
-%D \starttyping
-%D to be {\bold bold} or not, that's the question
-%D \stoptyping
-%D
-%D This alternative checks for a \type {\bgroup} token first. The internal
-%D alternative does not accept the box handling mentioned before, but further
-%D nesting works all right. The extra \type {\bgroup}||\type {\egroup} is needed to
-%D keep \type {\m_syst_helpers_handle_group_after} both into sight and local.
-
-\let\m_syst_helpers_handle_group_after \relax
-\let\m_syst_helpers_handle_group_before\relax
-
-\protected\def\syst_helpers_handle_group_nop
- {\ifnum\currentgrouptype=\semisimplegroupcode
- \expandafter\syst_helpers_handle_group_nop_a
- \else
- \expandafter\syst_helpers_handle_group_nop_b
- \fi}
-
-\def\syst_helpers_handle_group_nop_a
- {\begingroup
- \aftergroup\m_syst_helpers_handle_group_a
- \aftergroup\endgroup
- \m_syst_helpers_handle_group_b}
-
-\def\syst_helpers_handle_group_nop_b
- {\bgroup
- \aftergroup\m_syst_helpers_handle_group_a
- \aftergroup\egroup
- \m_syst_helpers_handle_group_b}
-
-\protected\def\syst_helpers_handle_group_normal
- {\bgroup
- \afterassignment\m_syst_helpers_handle_group_normal_before
- \let\next=}
-
-\def\m_syst_helpers_handle_group_normal_before
- {\bgroup
- \m_syst_helpers_handle_group_b
- \bgroup
- \aftergroup\m_syst_helpers_handle_group_a
- \aftergroup\egroup
- \aftergroup\egroup}
-
-\protected\def\syst_helpers_handle_group_simple% no inner group (so no kerning interference)
- {\bgroup
- \afterassignment\m_syst_helpers_handle_group_simple_before
- \let\next=}
-
-\def\m_syst_helpers_handle_group_simple_before
- {\bgroup
- \aftergroup\m_syst_helpers_handle_group_simple_after
- \m_syst_helpers_handle_group_b}
-
-\def\m_syst_helpers_handle_group_simple_after
- {\m_syst_helpers_handle_group_a
- \egroup}%
-
-\protected\def\syst_helpers_handle_group_pickup% no inner group (so no kerning interference)
- {\bgroup
- \afterassignment\m_syst_helpers_handle_group_pickup_before
- \let\next=}
-
-\def\m_syst_helpers_handle_group_pickup_before
- {\bgroup
- \aftergroup\m_syst_helpers_handle_group_a
- \aftergroup\egroup
- \aftergroup\m_syst_helpers_handle_group_p
- \m_syst_helpers_handle_group_b}
-
-\protected\def\syst_helpers_handle_group_nop_x
- {\ifnum\currentgrouptype=\semisimplegroupcode
- \begingroup
- \aftergroup\endgroup
- \else
- \bgroup
- \aftergroup\egroup
- \fi
- \m_syst_helpers_handle_group_b}
-
-\protected\def\syst_helpers_handle_group_normal_x
- {\bgroup
- \afterassignment\m_syst_helpers_handle_group_normal_before_x
- \let\next=}
-
-\def\m_syst_helpers_handle_group_normal_before_x
- {\bgroup
- \m_syst_helpers_handle_group_b
- \bgroup
- \aftergroup\egroup
- \aftergroup\egroup}
-
-%D I considered it a nuisance that
-%D
-%D \starttyping
-%D \color[green]
-%D {as grass}
-%D \stoptyping
-%D
-%D was not interpreted as one would expect. This is due to the fact that \type
-%D {\futurelet} obeys blank spaces, and a line||ending token is treated as a blank
-%D space. So the final implementation became:
-
-\permanent\protected\def\groupedcommand#1#2%
- {\def\m_syst_helpers_handle_group_b{#1}%
- \def\m_syst_helpers_handle_group_a{#2}%
- \futureexpandis\bgroup\syst_helpers_handle_group_normal\syst_helpers_handle_group_nop}
-
-\permanent\protected\def\groupedcommandcs#1#2%
- {\let\m_syst_helpers_handle_group_b#1%
- \let\m_syst_helpers_handle_group_a#2%
- \futureexpandis\bgroup\syst_helpers_handle_group_normal\syst_helpers_handle_group_nop}
-
-\permanent\protected\def\simplegroupedcommand#1#2%
- {\def\m_syst_helpers_handle_group_b{#1}%
- \def\m_syst_helpers_handle_group_a{#2}%
- \futureexpandis\bgroup\syst_helpers_handle_group_simple\syst_helpers_handle_group_nop}
-
-\permanent\protected\def\pickupgroupedcommand#1#2#3%
- {\def\m_syst_helpers_handle_group_b{#1}%
- \def\m_syst_helpers_handle_group_a{#2}%
- \def\m_syst_helpers_handle_group_p{#3}%
- \futureexpandis\bgroup\syst_helpers_handle_group_pickup\syst_helpers_handle_group_nop}
-
-\permanent\protected\def\triggergroupedcommand#1%
- {\def\m_syst_helpers_handle_group_b{#1}%
- \futureexpandis\bgroup\syst_helpers_handle_group_normal_x\syst_helpers_handle_group_nop_x}
-
-\permanent\protected\def\triggergroupedcommandcs#1%
- {\let\m_syst_helpers_handle_group_b#1%
- \futureexpandis\bgroup\syst_helpers_handle_group_normal_x\syst_helpers_handle_group_nop_x}
-
-%D Users should be aware of the fact that grouping can interfere with ones paragraph
-%D settings that are executed after the paragraph is closed. One should therefore
-%D explictly close the paragraph with \type {\par}, else the settings will be
-%D forgotten and not applied. So it's:
-%D
-%D \starttyping
-%D \def\BoldRaggedCenter%
-%D {\groupedcommand{\raggedcenter\bf}{\par}}
-%D \stoptyping
-
-%D \macros
-%D {checkdefined}
-%D
-%D The bigger the system, the greater the change that user defined commands collide
-%D with those that are part of the system. The next macro gives a warning when a
-%D command is already defined. We considered blocking the definition, but this is
-%D not always what we want.
-%D
-%D \starttyping
-%D \checkdefined {category} {class} {command}
-%D \stoptyping
-%D
-%D The user is warned with the suggestion to use \type {CAPITALS}. This suggestion
-%D is feasible, because \CONTEXT only defines lowcased macros.
-
-\protected\def\showdefinederror#1#2%
- {\writestatus\m!system{#1 #2 replaces a macro, use CAPITALS!}}
-
-\protected\def\checkdefined#1#2#3%
- {\doifdefined{#3}{\showdefinederror{#2}{#3}}}
-
-%D \macros
-%D {GotoPar,GetPar}
-%D
-%D Typesetting a paragraph in a special way can be done by first grabbing the
-%D contents of the paragraph and processing this contents grouped. The next macro
-%D for instance typesets a paragraph in boldface.
-%D
-%D \starttyping
-%D \def\remark#1\par%
-%D {\bgroup\bf#1\egroup}
-%D \stoptyping
-%D
-%D This macro has to be called like
-%D
-%D \starttyping
-%D \remark some text ... ending with \par
-%D \stoptyping
-%D
-%D Instead of \type {\par} we can of course use an empty line. When we started
-%D typesetting with \TEX, we already had produced lots of text in plain \ASCII. In
-%D producing such simple formatted texts, we adopted an open layout, and when
-%D switching to \TEX, we continued this open habit. Although \TEX\ permits a cramped
-%D and badly formatted source, it adds to confusion and sometimes introduces errors.
-%D So we prefer:
-%D
-%D \starttyping
-%D \remark
-%D
-%D some text ... ending with an empty line
-%D \stoptyping
-%D
-%D We are going to implement a mechanism that allows such open specifications. The
-%D definition of the macro handling \type {\remark} becomes:
-%D
-%D \starttyping
-%D \def\remark%
-%D {\BeforePar{\bgroup\bf}%
-%D \AfterPar{\egroup}%
-%D \GetPar}
-%D \stoptyping
-%D
-%D A macro like \type {\GetPar} can be defined in several ways. The recent version,
-%D the fourth one in a row, originally was far more complicated, but some
-%D functionality has been moved to other macros.
-%D
-%D We start with the more simple but in some cases more appropriate alternative is
-%D \type {\GotoPar}. This one leaves \type {\par} unchanged and is therefore more
-%D robust. On the other hand, \type {\AfterPar} is not supported.
-
-\let\syst_helpers_par_before\relax
-\let\syst_helpers_par_around\relax
-
-\permanent\protected\def\dowithpar#1#2%
- {\globalpushmacro\syst_helpers_par_around
- \def\syst_helpers_par_around##1\par{#1##1#2\globalpopmacro\syst_helpers_par_around}%
- \expandafter\syst_helpers_par_around\ignorepars}
-
-\permanent\protected\def\dogotopar#1%
- {\globalpushmacro\syst_helpers_par_before
- \def\syst_helpers_par_before{#1\globalpopmacro\syst_helpers_par_before}%
- \expandafter\syst_helpers_par_before\ignorepars}
-
-\aliased\let\dogotoparcs\dogotopar
-
-\permanent\protected\def\dogotoparstart
- {\ignorepars}
-
-%D This is old and kind of obsolete:
-
-\newtoks\BeforePar
-\newtoks\AfterPar
-
-\permanent\protected\def\GetPar
- {\expanded
- {\dowithpar
- {\the\BeforePar
- \BeforePar\emptytoks}
- {\the\AfterPar
- \BeforePar\emptytoks
- \AfterPar\emptytoks}}}
-
-\permanent\protected\def\GotoPar
- {\expanded
- {\dogotopar
- {\the\BeforePar
- \BeforePar\emptytoks}}}
-
-%D \macros
-%D {dowithpargument,dowithwargument}
-%D
-%D The next macros are a variation on \type {\GetPar}. When macros expect an
-%D argument, it interprets a grouped sequence of characters a one token. While this
-%D adds to robustness and less ambiguous situations, we sometimes want to be a bit
-%D more flexible, or at least want to be a bit more tolerant to user input.
-%D
-%D We start with a commands that acts on paragraphs. This
-%D command is called as:
-%D
-%D \starttyping
-%D \dowithpargument\command
-%D \dowithpargument{\command ... }
-%D \stoptyping
-%D
-%D In \CONTEXT\ we use this one to read in the titles of chapters, sections etc. The
-%D commands responsible for these activities accept several alternative ways of
-%D argument passing. In these examples, the \type {\par} can be omitted when an
-%D empty line is present.
-%D
-%D \starttyping
-%D \command{...}
-%D \command ... \par
-%D \command
-%D {...}
-%D \command
-%D ... \par
-%D \stoptyping
-
-\let\syst_helpers_next_par\relax
-\let\syst_helpers_next_arg\relax
-
-\permanent\protected\def\dowithpargument#1%
- {\def\syst_helpers_next_par##1 \par{#1{##1}}%
- \def\syst_helpers_next_arg##1{#1{##1}}%
- \doifelsenextbgroup\syst_helpers_next_arg{\doifelsenextchar\par{#1{}}\syst_helpers_next_par}}
-
-%D The \type {p} in the previous command stands for paragraph. When we want to act
-%D upon words we can use the \type{w} alternative.
-%D
-%D \starttyping
-%D \dowithwargument\command
-%D \dowithwargument{... \command ...}
-%D \stoptyping
-%D
-%D The main difference bwteen two alternatives is in the handling of \type {\par}'s.
-%D This time the space token acts as a delimiter.
-%D
-%D \starttyping
-%D \command{...}
-%D \command ...
-%D \command
-%D {...}
-%D \command
-%D ...
-%D \stoptyping
-
-\let\syst_helpers_next_war\relax
-\let\syst_helpers_next_arg\relax
-
-\permanent\protected\def\dowithwargument#1%
- {\def\syst_helpers_next_war##1 {#1{##1}}%
- \def\syst_helpers_next_arg##1{#1{##1}}%
- \doifelsenextbgroup\syst_helpers_next_arg\syst_helpers_next_war}
-
-%D \macros
-%D {dorepeat,dorepeatwithcommand}
-%D
-%D When doing repetitive tasks, we stromgly advice to use \type {\dorecurse}. The
-%D next alternative however, suits better some of the \CONTEXT\ interface commands.
-%D
-%D \starttyping
-%D \dorepeat[n*\command]
-%D \stoptyping
-%D
-%D The value of the used \COUNTER\ can be called within
-%D \type{\command} by \type{\repeater}.
-%D
-%D A slightly different alternative is:
-%D
-%D \starttyping
-%D \dorepeatwithcommand[n*{...}]\command
-%D \stoptyping
-%D
-%D When we call for something like:
-%D
-%D \starttyping
-%D \dorepeatwithcommand[3*{Hello}]\message
-%D \stoptyping
-%D
-%D we get ourselves three \type {\message{Hello}} messages in a row. In both
-%D commands, the \type {n*} is optional. When this specification is missing, the
-%D command executes once.
-
-\permanent\protected\def\dorepeatwithcommand[#1]%
- {\syst_helpers_repeat_with_command#1*\empty*\relax}
-
-\def\syst_helpers_repeat_with_command#1*#2#3*#4\relax#5%
- {\ifx#2\empty\syst_helpers_repeat_with_command_again[#1]#5\else\syst_helpers_repeat_with_command_indeed{#1}{#2}{#3}#5\fi}
-
-\def\syst_helpers_repeat_with_command_indeed#1#2#3#4%
- {\ifx#2\empty % redundant but gives cleaner extensions
- #4{#1}%
- \orelse\ifnum#1<\zerocount
- %\normalexpanded{\dorecurse{\number-\number#1}}{#4{-#2#3}}%
- \dorecurse{-#1}{#4{-#2#3}}%
- \orelse\ifx#2+%
- \dorecurse{#1}{#4{#3}}%
- \else
- \dorecurse{#1}{#4{#2#3}}%
- \fi}
-
-\def\syst_helpers_repeat_with_command_again[#1]#2%
- {#2{#1}}
-
-%D The extension hook permits something like:
-%D
-%D \starttyping
-%D \bgroup
-%D
-%D \catcode`\*=\superscriptcatcode
-%D
-%D \gdef\syst_helpers_repeat_with_command_again[#1]%
-%D {\redodorepeatwithcommand#1*\empty*\relax}
-%D
-%D \gdef\redodorepeatwithcommand#1*#2#3*#4\relax#5%
-%D {\syst_helpers_repeat_with_command_indeed{#1}{#2}{#3}#5}
-%D
-%D \egroup
-%D \stoptyping
-%D
-%D although one may wonder if changing the catcode of \type {*} is wise.
-
-%D \macros
-%D {doifstringinstringelse}
-%D
-%D The next macro is meant for situations where both strings are macros. This save
-%D some unneeded expansion. But now we just alias.
-
-\aliased\let\doifelsestringinstring\doifelseinstring
-\aliased\let\doifstringinstringelse\doifelseinstring
-
-%D \macros
-%D {appendtoks,prependtoks,appendtoksonce,prependtoksonce,
-%D doifintokselse,flushtoks,dotoks}
-%D
-%D We use tokenlists sparsely within \CONTEXT, because the comma separated lists are
-%D more suitable for the user interface. Nevertheless we have:
-%D
-%D \starttyping
-%D (\doglobal) \appendtoks ... \to\tokenlist
-%D (\doglobal) \prependtoks ... \to\tokenlist
-%D (\doglobal) \flushtoks\tokenlist
-%D \dotoks\tokenlist
-%D \stoptyping
-%D
-%D These macros are clones of the ones implemented in page~378 of Knuth's \TEX book.
-
-\newtoks\t_syst_helpers_scratch
-\let \m_syst_helpers_scratch\empty
-
-\permanent\protected\def\appendtoks#1\to#2%
- {\ifx\dodoglobal\relax
- \expandafter\toksapp
- \else
- \resetglobal
- \expandafter\gtoksapp
- \fi#2{#1}}
-
-\permanent\protected\def\prependtoks#1\to#2%
- {\ifx\dodoglobal\relax
- \expandafter\tokspre
- \else
- \resetglobal
- \expandafter\gtokspre
- \fi#2{#1}}
-
-% \def\syst_helpers_append_toks_indeed
-% {\ifx\dodoglobal\relax
-% \expandafter\toksapp
-% \else
-% \resetglobal
-% \expandafter\gtoksapp
-% \fi\m_syst_helpers_scratch\t_syst_helpers_scratch}
-%
-% \def\syst_helpers_prepend_toks_indeed
-% {\ifx\dodoglobal\relax
-% \expandafter\tokspre
-% \else
-% \resetglobal
-% \expandafter\gtokspre
-% \fi\m_syst_helpers_scratch\t_syst_helpers_scratch}
-%
-% \protected\def\appendtoksonce#1\to#2%
-% {\let\m_syst_helpers_scratch#2%
-% \t_syst_helpers_scratch{#1}%
-% \ifhasxtoks\t_syst_helpers_scratch\m_syst_helpers_scratch\else
-% \syst_helpers_append_toks_indeed
-% \fi}
-%
-% \protected\def\prependtoksonce#1\to#2%
-% {\let\m_syst_helpers_scratch#2%
-% \t_syst_helpers_scratch{#1}%
-% \ifhasxtoks\t_syst_helpers_scratch\m_syst_helpers_scratch\else
-% \syst_helpers_prepend_toks_indeed
-% \fi}
-
-\permanent\protected\def\appendtoksonce#1\to#2%
- {\ifhasxtoks{#1}#2\else
- \appendtoks#1\to#2%
- \fi}
-
-\permanent\protected\def\prependtoksonce#1\to#2%
- {\ifhasxtoks{#1}{#2}\m_syst_helpers_scratch\else
- \prependtoks#1\to#2%
- \fi}
-
-%D The test macro:
-
-\permanent\protected\def\doifelseintoks#1#2% #1 en #2 zijn toks
- {\ifhasxtoks#1#2%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifintokselse\doifelseintoks
-
-%D Moved from \type {lxml-ini.tex} to here. This one is for generators that collect
-%D stuff piecewise, which is sometimes hard on mechanisms that grab content using
-%D delimiters:
-%D
-%D \starttyping
-%D \startcollecting
-%D \startcollect \bTABLE \stopcollect
-%D \startcollect \bTR \stopcollect
-%D \startcollect \bTD \stopcollect
-%D \startcollect foo\stopcollect
-%D \startcollect \eTD \stopcollect
-%D \startcollect \bTD \stopcollect
-%D \startcollect bar\stopcollect
-%D \startcollect \eTD \stopcollect
-%D \startcollect \eTR \stopcollect
-%D \startcollect \eTABLE \stopcollect
-%D \stopcollecting
-%D \stoptyping
-
-\newtoks \collectingtoks
-
-\permanent\protected\def\startcollect #1\stopcollect {\toksapp \collectingtoks{#1}}
-\permanent\protected\def\startexpandedcollect#1\stopexpandedcollect{\etoksapp\collectingtoks{#1}}
-
-\permanent\protected\def\startcollecting{\collectingtoks\emptytoks}
-\permanent\protected\def\stopcollecting {\the\collectingtoks}
-
-\permanent\protected\def\collect {\toksapp \collectingtoks}
-\permanent\protected\def\collectexpanded{\etoksapp\collectingtoks}
-
-%D A nice one too:
-
-% {\scratchtoks{abc} \removetoks b\from\scratchtoks [\the\scratchtoks]}
-% {\scratchtoks{abc} \removetoks x\from\scratchtoks [\the\scratchtoks]}
-% {\scratchtoks{} \removetoks x\from\scratchtoks [\the\scratchtoks]}
-% {\scratchtoks{xaa} \removetoks x\from\scratchtoks [\the\scratchtoks]}
-% {\scratchtoks{a\relax b} \removetoks \relax\from\scratchtoks [\showthe\scratchtoks]}
-
-\permanent\protected\def\removetoks#1\from#2%
- {\def\syst_helpers_remove_toks##1#1##2\empty\empty\empty##3^^^^0004%
- {\def\m_syst_string_one{##3}%
- \ifempty\m_syst_string_one#2{##1}\else#2{##1##2}\fi}%
- \expandafter\syst_helpers_remove_toks\the#2\empty\empty\empty#1\empty\empty\empty^^^^0004}
-
-%D Also:
-
-\permanent\protected\def\appendetoks#1\to#2%
- {\ifx\dodoglobal\relax
- \expandafter\etoksapp
- \else
- \resetglobal
- \expandafter\xtoksapp
- \fi#2{#1}}
-
-\permanent\protected\def\prependetoks#1\to#2%
- {\ifx\dodoglobal\relax
- \expandafter\etokspre
- \else
- \resetglobal
- \expandafter\xtokspre
- \fi#2{#1}}
-
-%D Hm.
-
-\permanent\protected\def\flushtoks#1% nb: can reassign to #1 again, hence the indirectness
- {\t_syst_helpers_scratch#1\relax
- \dodoglobal#1\emptytoks
- \the\t_syst_helpers_scratch\relax}
-
-\aliased\let\dotoks\the
-
-%D \macros
-%D {beforesplitstring,aftersplitstring}
-%D
-%D These both commands split a string at a given point in two
-%D parts, so \type{x.y} becomes \type{x} or \type{y}.
-%D
-%D \starttyping
-%D \beforesplitstring test.tex\at.\to\filename
-%D \aftersplitstring test.tex\at.\to\extension
-%D \stoptyping
-%D
-%D The first routine looks (and is indeed) a bit simpler than the second one. The
-%D alternative looking more or less like the first one did not always give the
-%D results we needed. Both implementations show some insight in the manipulation of
-%D arguments.
-
-\let\syst_helpers_split_string\relax
-
-\permanent\protected\def\beforesplitstring#1\at#2\to#3%
- {\def\syst_helpers_split_string##1#2##0^^^^0004% no #- as we need to count
- {\ifarguments
- \let#3\empty
- \or
- \let#3\empty
- \else
- \def#3{##1}%
- \fi}%
- \expandafter\syst_helpers_split_string#1^^^^0004\ignorearguments\ignorearguments}
-
-\permanent\protected\def\aftersplitstring#1\at#2\to#3%
- {\def\syst_helpers_split_string##0#2##2^^^^0004% no #- as we need to count
- {\ifarguments
- \let#3\empty
- \or
- \def#3{#1}%
- \else
- \def#3{##2}%
- \fi}%
- \expandafter\syst_helpers_split_string#1^^^^0004\ignorearguments\ignorearguments}
-
-%D \macros
-%D {splitstring,greedysplitstring}
-%D
-%D A bonus macro.
-
-\permanent\protected\def\splitstring#1\at#2\to#3\and#4%
- {\def\syst_helpers_split_string##1#2##2^^^^0004%
- {\ifarguments
- \let#3\empty
- \let#4\empty
- \or
- \def#3{#1}%
- \let#4\empty
- \else
- \def#3{##1}%
- \def#4{##2}%
- \fi}%
- \expandafter\syst_helpers_split_string#1^^^^0004\ignorearguments\ignorearguments}
-
-\permanent\protected\def\greedysplitstring#1\at#2\to#3\and#4%
- {\def\syst_helpers_split_string##1#2##2^^^^0004%
- {\ifarguments
- \let#3\empty
- \let#4\empty
- \or
- \def#3{#1}%
- \let#4\empty
- \else
- \def#3{##1}%
- \def#4{##2}%
- \def\syst_helpers_split_string####1#2####2^^^^0004%
- {\ifarguments
- \or
- \else
- \expandafter\def\expandafter#3\expandafter{#3####1}%
- \def#4{####2}%
- \syst_helpers_split_string####2^^^^0004\ignorearguments\ignorearguments
- \fi}%
- \syst_helpers_split_string##2^^^^0004\ignorearguments\ignorearguments
- \fi}%
- \expandafter\syst_helpers_split_string#1^^^^0004\ignorearguments\ignorearguments}
-
-%D \macros
-%D {beforetestandsplitstring,
-%D aftertestandsplitstring,
-%D testandsplitstring}
-
-\aliased\let\beforetestandsplitstring\beforesplitstring
-
-\permanent\protected\def\aftertestandsplitstring#1\at#2\to#3%
- {\def\syst_helpers_split_string##0#2##2^^^^0004% no #- as we need to count
- {\ifarguments
- \let#3\empty
- \or
- \let#3\empty
- \else
- \def#3{##2}%
- \fi}%
- \expandafter\syst_helpers_split_string#1^^^^0004\ignorearguments\ignorearguments}
-
-\permanent\protected\def\testandsplitstring#1\at#2\to#3\and#4%
- {\def\syst_helpers_split_string##1#2##2^^^^0004%
- {\ifarguments
- \let#3\empty
- \let#4\empty
- \or
- \let#3\empty
- \let#4\empty
- \else
- \def#3{##1}%
- \def#4{##2}%
- \fi}%
- \expandafter\syst_helpers_split_string#1^^^^0004\ignorearguments\ignorearguments}
-
-%D \macros
-%D {splitatperiod, splitatcomma, splitatasterisk, splitatcolon, splitatcolons}
-
-\protected\def\syst_helpers_splitatperiod #1.#2.#-^^^^0004#3#4{\def #3{#1}\def #4{#2}}
-\protected\def\syst_helpers_splitatcomma #1,#2,#-^^^^0004#3#4{\def #3{#1}\def #4{#2}}
-\protected\def\syst_helpers_splitatasterisk #1*#2*#-^^^^0004#3#4{\def #3{#1}\def #4{#2}}
-\protected\def\syst_helpers_splitatcolon #1:#2:#-^^^^0004#3#4{\def #3{#1}\def #4{#2}}
-\protected\def\syst_helpers_splitatcolons #1::#2::#-^^^^0004#3#4{\edef#3{#1}\edef#4{#2}}
-
-\permanent\protected\def\splitatperiod #1{\normalexpanded{\syst_helpers_splitatperiod #1}..^^^^0004}
-\permanent\protected\def\splitatcomma #1{\normalexpanded{\syst_helpers_splitatcomma #1},,^^^^0004} % not at ", "
-\permanent\protected\def\splitatasterisk#1{\normalexpanded{\syst_helpers_splitatasterisk#1}**^^^^0004}
-\permanent\protected\def\splitatcolon #1{\normalexpanded{\syst_helpers_splitatcolon #1}::^^^^0004}
-\permanent\protected\def\splitatcolons #1{\normalexpanded{\syst_helpers_splitatcolons #1}::::^^^^0004}
-
-%D \macros
-%D {removesubstring}
-%D
-%D A first application of the two routines defined above is:
-%D
-%D \starttyping
-%D \removesubstring-\from first-last\to\nothyphenated
-%D \stoptyping
-%D
-%D Which in terms of \TEX\ looks like:
-
-\permanent\protected\def\removesubstring#1\from#2\to#3%
- {\splitstring#2\to\m_syst_string_one\and\m_syst_string_two
- \dodoglobal#3{\m_syst_string_one\m_syst_string_two}}
-
-%D \macros
-%D {appendtocommalist,prependtocommalist,
-%D addtocommalist,removefromcommalist}
-%D
-%D When working with comma separated lists, one sooner or later want the tools to
-%D append or remove items from such a list. When we add an item, we first check if
-%D it's already there. This means that every item in the list is unique.
-%D
-%D \starttyping
-%D \addtocommalist {alfa} \name
-%D \addtocommalist {beta} \name
-%D \addtocommalist {gamma} \name
-%D \removefromcommalist {beta} \name
-%D \stoptyping
-%D
-%D These commands can be prefixed with \type {\doglobal}. The implementation of the
-%D second command is more complecated, because we have to take leading spaces into
-%D account. Keep in mind that users may provide lists with spaces after the commas.
-%D When one item is left, we also have to get rid of trailing spaces.
-%D
-%D \starttyping
-%D \def\words{alfa, beta, gamma, delta}
-%D \def\words{alfa,beta,gamma,delta}
-%D \stoptyping
-%D
-%D Removing an item takes more time than adding one. A fast appending alternative,
-%D without any testing, is also provided:
-%D
-%D \starttyping
-%D \appendtocommalist {something} \name
-%D \prependtocommalist {something} \name
-%D \stoptyping
-%D
-%D This can be implemented as follows:
-%D
-%D \starttyping
-%D \def\appendtocommalist#1#2%
-%D {\ifx#2\empty
-%D \dodoglobal\edef#2{#1}%
-%D \else % no test on empty
-%D \dodoglobal\edef#2{#2,#1}%
-%D \fi}
-%D
-%D \def\prependtocommalist#1#2%
-%D {\ifx#2\empty
-%D \dodoglobal\edef#2{#1}%
-%D \else % no test on empty
-%D \dodoglobal\edef#2{#1,#2}%
-%D \fi}
-%D \stoptyping
-%D
-%D The faster alternatives are:
-
-\permanent\protected\def\appendtocommalist#1#2%
- {\dodoglobal\edef#2{\ifempty#2\else#2,\fi#1}}
-
-\permanent\protected\def\prependtocommalist#1#2%
- {\dodoglobal\edef#2{#1\ifempty#2\else,#2\fi}}
-
-\permanent\protected\def\addtocommalist#1#2% {item} \cs
- {\rawdoifelseinset{#1}#2\resetglobal
- {\dodoglobal\edef#2{\ifempty#2\else#2,\fi#1}}}
-
-\permanent\protected\def\pretocommalist#1#2% {item} \cs
- {\rawdoifelseinset{#1}#2\resetglobal
- {\dodoglobal\edef#2{#1\ifempty#2\else,#2\fi}}}
-
-\permanent\protected\def\robustdoifelseinset#1#2%
- {\edef\m_syst_string_one{\detokenize\expandafter{\normalexpanded{#1}}}%
- \edef\m_syst_string_two{\detokenize\expandafter{\normalexpanded{#2}}}%
- \rawdoifelseinset\m_syst_string_one\m_syst_string_two}
-
-\aliased\let\robustdoifinsetelse\robustdoifelseinset
-
-\permanent\protected\def\robustaddtocommalist#1#2% {item} \cs
- {\robustdoifelseinset{#1}#2\resetglobal
- {\dodoglobal\edef#2{\ifempty#2\else#2,\fi#1}}}
-
-\permanent\protected\def\robustpretocommalist#1#2% {item} \cs
- {\robustdoifelseinset{#1}#2\resetglobal
- {\dodoglobal\edef#2{#1\ifempty#2\else,#2\fi}}}
-
-\permanent\protected\def\xsplitstring#1#2% \cs {str}
- %{\def\syst_helpers_split_string##1,#2,##2,#2,##3\\%
- {\def\syst_helpers_split_string##1,#2,##2,#2,##-\\%
- {\edef\m_syst_string_one{\bcleanedupcommalist##1\empty\empty\relax}%
- \edef\m_syst_string_two{\acleanedupcommalist##2,,\relax}}%
- \expandafter\syst_helpers_split_string\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\acleanedupcommalist#1,,#-\relax{#1}
-
-\permanent\protected\def\removefromcommalist#1#2% to be sped up
- {\rawdoifelseinset{#1}#2%
- {\normalexpanded{\xsplitstring\noexpand#2{#1}}%
- \dodoglobal\edef#2%
- {\ifempty\m_syst_string_one
- \m_syst_string_two
- \else
- \m_syst_string_one\ifempty\m_syst_string_two\else,\m_syst_string_two\fi
- \fi}}
- \resetglobal}
-
-%D \macros
-%D {substituteincommalist}
-%D
-%D Slow but seldom used, so for the moment we stick to this implementation.
-%D
-%D \starttyping
-%D \substituteincommalist{old}{new}{list}
-%D \stoptyping
-
-\def\syst_helpers_substitute_in_comma_list_step#1%
- {\edef\m_syst_string_three{#1}%
- \ifx\m_syst_string_one\m_syst_string_three
- \ifempty\m_syst_string_two \else
- \edef\m_syst_string_four{\ifempty\m_syst_string_four\else\m_syst_string_four,\fi\m_syst_string_two}%
- \fi
- \else
- \edef\m_syst_string_four{\ifempty\m_syst_string_four\else\m_syst_string_four,\fi#1}%
- \fi}
-
-\permanent\protected\def\substituteincommalist#1#2#3% old, new, list (slooow)
- {\edef\m_syst_string_one{#1}%
- \edef\m_syst_string_two{#2}%
- \let\m_syst_string_four\empty
- \normalexpanded{\rawprocesscommacommand[#3]}\syst_helpers_substitute_in_comma_list_step
- \let#3\m_syst_string_four}
-
-%D \macros
-%D {replaceincommalist}
-%D
-%D The next macro can be used to replace an indexed element in a commalist:
-%D
-%D \starttyping
-%D \replaceincommalist\MyList{2}
-%D \stoptyping
-%D
-%D Element~2 will be replaced by the current meaning of the macro \type
-%D {\newcommalistelement}. The old meaning is saved in \type {\commalistelement}.
-%D The replacement honors grouped items, like in:
-%D
-%D \starttyping
-%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3}
-%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3}
-%D \def\MyList{a,{b,c},d,e,f} \replaceincommalist\MyList{3}
-%D \def\MyList{a,b,c,{d,e,f}} \replaceincommalist\MyList{3}
-%D \stoptyping
-%D
-%D This macro was used in the bibtex code (and is probably no longer needed).
-
-\newcount\c_syst_helpers_comma_list_index
-\let \m_syst_helpers_comma_list_target\empty
-
-\let\newcommalistelement\empty
-
-\def\syst_helpers_replace_in_comma_list_step#1% we can use #+ here too
- {\ifnum\commalistcounter=\c_syst_helpers_comma_list_index\relax
- \ifempty\newcommalistelement\else
- \ifempty\m_syst_helpers_comma_list_target
- \let\m_syst_helpers_comma_list_target\newcommalistelement
- \else
- \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
- \m_syst_helpers_comma_list_target\expandafter\expandafter\expandafter
- {\expandafter\m_syst_helpers_comma_list_target\expandafter,\newcommalistelement}%
- \fi
- \fi
- \def\commalistelement{#1}%
- \else
- \ifempty\m_syst_helpers_comma_list_target
- \ifx\nexttoken\bgroup % is known -)
- \def\m_syst_helpers_comma_list_target{{#1}}%
- \else
- \def\m_syst_helpers_comma_list_target{#1}%
- \fi
- \else
- \ifx\nexttoken\bgroup % is known -)
- \expandafter\def\expandafter\m_syst_helpers_comma_list_target\expandafter{\m_syst_helpers_comma_list_target,{#1}}%
- \else
- \expandafter\def\expandafter\m_syst_helpers_comma_list_target\expandafter{\m_syst_helpers_comma_list_target,#1}%
- \fi
- \fi
- \fi
- \advance\commalistcounter\plusone}
-
-\permanent\protected\def\replaceincommalist#1#2% #1 = commalistelement #2 = position starts at 1
- {\c_syst_helpers_comma_list_index#2\relax
- \let\m_syst_helpers_comma_list_target\empty
- \let\commalistelement\empty
- \commalistcounter\plusone
- \expandafter\processcommalist\expandafter[#1]\syst_helpers_replace_in_comma_list_step
- \dodoglobal\let#1\m_syst_helpers_comma_list_target}
-
-%D \macros
-%D {globalprocesscommalist}
-%D
-%D The commalist processing commands are characterized by the fact that the way they
-%D handle expansion as well as the fact that they can be nested. This makes them
-%D kind of useless for handling comma lists in alignments. In these situations the
-%D next macro can be of use.
-
-\let\m_syst_helpers_comma_list_command_global\empty
-
-\def\syst_helpers_comma_list_command_global_step#1,%
- {\if]#1\else
- \m_syst_helpers_comma_list_command_global{#1}%
- \expandafter\syst_helpers_comma_list_command_global_step
- \fi}
-
-\permanent\protected\def\globalprocesscommalist[#1]#2%
- {\glet\m_syst_helpers_comma_list_command_global#2%
- \expandafter\syst_helpers_comma_list_command_global_step#1,],}
-
-%D \macros
-%D {withoutpt,PtToCm,
-%D numberofpoints,dimensiontocount}
-%D
-%D We can convert point into centimeters with:
-%D
-%D \starttyping
-%D \PtToCm{dimension}
-%D \stoptyping
-
-% {\catcode`\.=\othercatcode
-% \catcode`\p=\othercatcode
-% \catcode`\t=\othercatcode
-% \gdef\WITHOUTPT#1pt{#1}}
-%
-% \def\withoutpt#1%
-% {\expandafter\WITHOUTPT#1}
-%
-% Okay, not really an impressive extension to the engine, but better than some macro
-% that is demonstrating deeper understanding of \TEX. It's anyway a trivial extension
-% anyway. There are actually many examples of very advanced macros and exposure of
-% how clever one is that could be done cheap in the engine. It's just that at the time
-% that \TEX\ was written, it made no sense to add a lot of that. After decades we know
-% what extras we need.
-
-\permanent\def\withoutpt#1{\thewithoutunit\dimexpr#1} % best use the primitive directly
-
-%D The capitals are needed because \type {p} and \type {t} have catcode~12, while
-%D macronames only permit tokens with the catcode~11. As a result we cannot use the
-%D \type {.group} primitives. Those who want to know more about this kind of
-%D manipulations, we advice to study the \TEX book in detail. Because this macro
-%D does not do any assignment, we can use it in the following way too.
-
-% \def\PtToCm#1%
-% {\withoutpt\the\dimexpr0.0351459804\dimexpr#1\relax\relax cm}
-
-\permanent\def\PtToCm#1{\thewithoutunit\dimexpr0.0351459804\dimexpr#1\relax\relax cm}
-
-%D We also support:
-%D
-%D \starttyping
-%D \numberofpoints {dimension}
-%D \dimensiontocount {dimension} {\count}
-%D \stoptyping
-%D
-%D Both macros return a rounded number.
-
-% \dimensiontocount{10.49pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.49pt}
-% \dimensiontocount{10.51pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.51pt}
-
-\permanent\def\dimensiontocount#1#2{#2\numexpr\dimexpr#1\relax/\maxcard\relax}
-\permanent\def\numberofpoints #1{\the\numexpr\dimexpr#1\relax/\maxcard\relax}
-
-%D \macros
-%D {swapdimens,swapskips,swapcounts,swapmacros,
-%D globalswapdimens,globalswapcounts,globalswapmacros}
-%D
-%D Simple but effective are the next two macros. There name exactly states their
-%D purpose.
-
-\newdimen\d_syst_helpers_swapped
-\newskip \s_syst_helpers_swapped
-\newcount\c_syst_helpers_swapped
-\let \m_syst_helpers_swapped\relax
-
-% \protected\def\swapdimens#1#2{\d_syst_helpers_swapped#1#1#2#2\d_syst_helpers_swapped}
-% \protected\def\swapskips #1#2{\s_syst_helpers_swapped#1#1#2#2\s_syst_helpers_swapped}
-% \protected\def\swapcounts#1#2{\c_syst_helpers_swapped#1#1#2#2\c_syst_helpers_swapped}
-% \protected\def\swapmacros#1#2{\let\m_syst_helpers_swapped#1\let#1#2\let#2\m_syst_helpers_swapped}
-
-\aliased\let\swapdimens\swapcsvalues
-\aliased\let\swapskips \swapcsvalues
-\aliased\let\swapcounts\swapcsvalues
-\aliased\let\swapmacros\swapcsvalues
-
-% \protected\def\globalswapdimens#1#2{\d_syst_helpers_swapped#1\global#1#2\global#2\d_syst_helpers_swapped}
-% \protected\def\globalswapskips #1#2{\s_syst_helpers_swapped#1\global#1#2\global#2\s_syst_helpers_swapped}
-% \protected\def\globalswapcounts#1#2{\c_syst_helpers_swapped#1\global#1#2\global#2\c_syst_helpers_swapped}
-% \protected\def\globalswapmacros#1#2{\let\m_syst_helpers_swapped#1\glet#1#2\glet#2\m_syst_helpers_swapped}
-
-\permanent\protected\def\globalswapdimens{\global\swapcsvalues}
-\permanent\protected\def\globalswapskips {\global\swapcsvalues}
-\permanent\protected\def\globalswapcounts{\global\swapcsvalues}
-\permanent\protected\def\globalswapmacros{\global\swapcsvalues}
-
-%D \macros
-%D {pushmacro,popmacro}
-%D
-%D Premature and a bit of beta, we offer:
-%D
-%D \starttyping
-%D \pushmacro\macro
-%D \popmacro\macro
-%D \stoptyping
-
-\permanent\let\pushmacro\localpushmacro
-\permanent\let\popmacro \localpopmacro
-
-%D \macros
-%D {setlocalhsize,distributedhsize}
-%D
-%D Sometimes we need to work with the \type{ \hsize} that is corrected for
-%D indentation and left and right skips. The corrected value is available in \type
-%D {\localhsize}, which needs to be calculated with \type {\setlocalhsize} first. %D
-%D
-%D \starttyping
-%D \setlocalhsize \hbox to \localhsize{...}
-%D \setlocalhsize[-1em] \hbox to \localhsize{...}
-%D \setlocalhsize[.5ex] \hbox to \localhsize{...}
-%D \stoptyping
-%D
-%D These examples show us that an optional can be used. The value provided is added
-%D to \type {\localhsize}.
-
-\newdimen\localhsize
-
-\protected\def\setlocalhsize % don't change !
- {\doifelsenextoptional
- \syst_helpers_set_local_hsize_yes
- \syst_helpers_set_local_hsize_nop}
-
-\def\syst_helpers_set_local_hsize_nop
- {\localhsize\availablehsize}
-
-\def\syst_helpers_set_local_hsize_yes[#1]%
- {\syst_helpers_set_local_hsize_nop
- \advance\localhsize#1\relax}
-
-\permanent\def\availablehsize
- {\dimexpr
- \hsize-\leftskip-\rightskip
- \ifnum\hangafter<\zerocount
- \ifdim\hangindent>\zeropoint-\else+\fi\hangindent
- \fi
- \relax}
-
-\permanent\def\distributedhsize#1#2#3%
- {\dimexpr(#1-\numexpr#3-1\relax\dimexpr#2\relax)/#3\relax}
-
-\permanent\def\hsizefraction#1#2%
- {\dimexpr#1/#2\relax}
-
-%D \macros
-%D {doifvalue,doifnotvalue,doifelsevalue,
-%D doifnothing,doifsomething,doifelsenothing,
-%D doifvaluenothing,doifvaluesomething,doifelsevaluenothing}
-%D
-%D These \type {\if} commands can be used to access macros (or variables) that are
-%D normally accessed by using \type {\getvalue}. Using these alternatives safes us
-%D three tokens per call. Anyone familiar with the not||values ones, can derive
-%D their meaning from the definitions.
-
-\permanent\protected\def\doifvalue#1#2%
- {\iftok{\csname#1\endcsname}{#2}%
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\doifnotvalue#1#2%
- {\iftok{\csname#1\endcsname}{#2}%
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\permanent\protected\def\doifelsevalue#1#2%
- {\iftok{\csname#1\endcsname}{#2}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\permanent\protected\def\doifnothing#1%
- {\iftok{#1}\emptytoks
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\doifsomething#1%
- {\iftok{#1}\emptytoks
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\permanent\protected\def\doifelsenothing#1%
- {\iftok{#1}\emptytoks
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\permanent\protected\def\doifelsesomething#1%
- {\iftok{#1}\emptytoks
- \expandafter\secondoftwoarguments
- \else
- \expandafter\firstoftwoarguments
- \fi}
-
-\permanent\protected\def\doifvaluenothing#1%
- {\iftok{\csname#1\endcsname}\emptytoks
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\protected\def\doifvaluesomething#1%
- {\iftok{\csname#1\endcsname}\emptytoks
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\permanent\protected\def\doifelsevaluenothing#1%
- {\iftok{\csname#1\endcsname}\emptytoks
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifvalueelse \doifelsevalue
-\aliased\let\doifnothingelse \doifelsenothing
-\aliased\let\doifsomethingelse \doifelsesomething
-\aliased\let\doifvaluenothingelse\doifelsevaluenothing
-
-%D \macros
-%D {doifemptyelsevalue, doifemptyvalue, doifnotemptyvalue}
-%D
-%D Also handy:
-
-\permanent\def\doifelseemptyvalue#1%
- {\expandafter\ifempty\csname#1\endcsname
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifemptyvalueelse\doifelseemptyvalue
-
-\permanent\def\doifemptyvalue#1%
- {\expandafter\ifempty\csname#1\endcsname
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\permanent\def\doifnotemptyvalue#1%
- {\expandafter\ifempty\csname#1\endcsname
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-%D \macros
-%D {doifallcommonelse}
-%D
-%D A complete match of two sets can be tested with \type {\doifallcommonelse}, where
-%D the first two arguments are sets.
-
-\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]\syst_helpers_do_common_check_all
- \ifdone\expandafter#1\else\expandafter#2\fi}
-
-\permanent\protected\def\doifelseallcommon{\syst_helpers_do_if_all_common_else\firstoftwoarguments\secondoftwoarguments}
-\permanent\protected\def\doifallcommon {\syst_helpers_do_if_all_common_else\firstofonearguments\gobbleoneargument }
-\permanent\protected\def\doifnotallcommon {\syst_helpers_do_if_all_common_else\gobbleoneargument \firstofonearguments }
-
-\aliased\let\doifallcommonelse\doifelseallcommon
-
-%D \macros
-%D {DOIF,DOIFELSE,DOIFNOT}
-%D
-%D \TEX\ is case sensitive. When comparing arguments, this feature sometimes is less
-%D desirable, for instance when we compare filenames. The next three alternatives
-%D upcase their arguments before comparing them.
-%D
-%D \starttyping
-%D \DOIF {string1} {string2} {...}
-%D \DOIFNOT {string1} {string2} {...}
-%D \DOIFELSE {string1} {string2} {then ...}{else ...}
-%D \stoptyping
-%D
-%D We have to use a two||step implementation, because the
-%D expansion has to take place outside \type{\uppercase}.
-%D
-%D These might end up as \LUA based helpers (i.e. consider these
-%D obsolete:
-
-\protected\def\syst_helpers_do_IF#1#2%
- {\uppercase{\iftok{#1}{#2}}%
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\protected\def\syst_helpers_do_IF_NOT#1#2%
- {\uppercase{\iftok{#1}{#2}}%
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\protected\def\syst_helpers_do_IF_ELSE#1#2%
- {\uppercase{\iftok{#1}{#2}}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\protected\def\syst_helpers_do_IF_INSTRING_ELSE#1#2%
- {\uppercase{\doifelseinstring{#1}{#2}}}
-
-\permanent\protected\def\DOIF #1#2{\normalexpanded{\syst_helpers_do_IF {#1}{#2}}}% will become obsolete
-\permanent\protected\def\DOIFNOT #1#2{\normalexpanded{\syst_helpers_do_IF_NOT {#1}{#2}}}% will become obsolete
-\permanent\protected\def\DOIFELSE #1#2{\normalexpanded{\syst_helpers_do_IF_ELSE {#1}{#2}}}% will become obsolete
-\permanent\protected\def\DOIFINSTRINGELSE #1#2{\normalexpanded{\syst_helpers_do_IF_INSTRING_ELSE{#1}{#2}}}% will become obsolete
-
-%D \macros
-%D {dosingleargumentwithset,
-%D dodoubleargumentwithset,dodoubleemptywithset,
-%D dotripleargumentwithset,dotripleemptywithset}
-%D
-%D These maybe too mysterious macros enable us to handle more than one setup at once.
-%D
-%D \starttyping
-%D \dosingleargumentwithset \command[#1]
-%D \dodoubleargumentwithset \command[#1][#2]
-%D \dotripleargumentwithset \command[#1][#2][#3]
-%D \dodoubleemptywithset \command[#1][#2]
-%D \dotripleemptywithset \command[#1][#2][#3]
-%D \stoptyping
-%D
-%D The first macro calls \type {\command[##1]} for each string in the set~\type
-%D {#1}. The second one calls for \typ {\command [##1][#2]} and the third, well one
-%D may guess. These commands support constructions like:
-%D
-%D \starttyping
-%D \def\dodefinesomething[#1][#2]%
-%D {\getparameters[\??xx#1][#2]}
-%D
-%D \protected\def\definesomething%
-%D {\dodoubleargumentwithset\dodefinesomething}
-%D \stoptyping
-%D
-%D Which accepts calls like:
-%D
-%D \starttyping
-%D \definesomething[alfa,beta,...][variable=...,...]
-%D \stoptyping
-
-%% \let\syst_helpers_with_set_step\relax
-%% \let\m_syst_helpers_with_set_command\empty
-%%
-%% \def\syst_helpers_with_set_double[#1][#2]%
-%% {\doifsomething{#1}%
-%% {\def\syst_helpers_with_set_step##1{\m_syst_helpers_with_set_command[##1][#2]}%
-%% \processcommalist[#1]\syst_helpers_with_set_step}}
-%%
-%% \def\syst_helpers_with_set_triple[#1][#2][#3]%
-%% {\doifsomething{#1}%
-%% {\def\syst_helpers_with_set_step##1{\m_syst_helpers_with_set_command[##1][#2][#3]}%
-%% \processcommalist[#1]\syst_helpers_with_set_step}}
-%%
-%% \def\dodoubleemptywithset #1{\let\m_syst_helpers_with_set_command#1\dodoubleempty \syst_helpers_with_set_double} % \command
-%% \def\dodoubleargumentwithset#1{\let\m_syst_helpers_with_set_command#1\dodoubleargument\syst_helpers_with_set_double} % \command
-%%
-%% \def\dotripleemptywithset #1{\let\m_syst_helpers_with_set_command#1\dotripleempty \syst_helpers_with_set_triple} % \command
-%% \def\dotripleargumentwithset#1{\let\m_syst_helpers_with_set_command#1\dotripleargument\syst_helpers_with_set_triple} % \command
-
-\let\syst_helpers_with_set_step\relax % maybe push pop
-
-\permanent\tolerant\protected\def\dodoubleemptywithset#1#*[#2]#*[#3]%
- {\doifsomething{#2}%
- {\def\syst_helpers_with_set_step##1{#1[##1][#3]}%
- \processcommalist[#1]\syst_helpers_with_set_step}}
-
-\permanent\tolerant\protected\def\dotripleemptywithset#1#*[#2]#*[#3]#*[#4]%
- {\doifsomething{#2}%
- {\def\syst_helpers_with_set_step##1{#1[##1][#3][#4]}%
- \processcommalist[#1]\syst_helpers_with_set_step}}
-
-\aliased\let\dodoubleargumentwithset\dodoubleemptywithset
-\aliased\let\dotripleargumentwithset\dotripleemptywithset
-
-%D \macros
-%D {stripcharacters,stripspaces}
-%D
-%D The next command was needed first when we implemented the \CONTEXT\ interactivity
-%D macros. When we use labeled destinations, we often cannot use all the characters
-%D we want. We therefore strip some of the troublemakers, like spaces, from the
-%D labels before we write them to the \DVI||file, which passes them to for instance
-%D a \POSTSCRIPT\ file.
-%D
-%D \starttyping
-%D \stripspaces\from\one\to\two
-%D \stoptyping
-%D
-%D Both the old string \type{\one} and the new one \type{\two}
-%D are expanded. This command is a special case of:
-%D
-%D \starttyping
-%D \stripcharacter\char\from\one\to\two
-%D \stoptyping
-%D
-%D As we can see below, spaces following a control sequence are to enclosed in \type
-%D {{}}.
-
-\let\m_syst_helpers_strip_character\empty
-
-\permanent\protected\def\stripcharacter#1\from#2\to#3%
- {\def\syst_helpers_strip_character##1#1##2\end
- {\edef\m_syst_helpers_strip_character{\m_syst_helpers_strip_character##1}%
- \doifnotempty{##2}{\syst_helpers_strip_character##2\end}}%
- \let\m_syst_helpers_strip_character\empty
- \edef\m_syst_string_one{#2}%
- \expandafter\syst_helpers_strip_character\m_syst_string_one#1\end
- \dodoglobal\let#3\m_syst_helpers_strip_character}
-
-\permanent\protected\def\stripspaces\from#1\to#2% will become \unspacestring#1\from#2
- {\stripcharacter{ }\from#1\to#2}
-
-%D \macros
-%D {unspacestring}
-%D
-%D The next macro does the same but is more compatible with other macros, like \type
-%D {\convert...}.
-
-\permanent\protected\def\unspacestring#1\to#2%
- {\stripcharacter{ }\from#1\to#2}
-
-%D \macros
-%D {executeifdefined}
-%D
-%D \CONTEXT\ uses one auxiliary file for all data concerning tables of contents,
-%D references, two||pass optimizations, sorted lists etc. This file is loaded as
-%D many times as needed. During such a pass we skip the commands thate are of no use
-%D at that moment. Because we don't want to come into trouble with undefined
-%D auxiliary commands, we call the macros in a way similar to \type {\getvalue}. The
-%D next macro take care of such executions and when not defined, gobbles the
-%D unwanted arguments.
-%D
-%D \starttyping
-%D \executeifdefined{name}\gobbleoneargument
-%D \stoptyping
-%D
-%D We can of course gobble more arguments using the appropriate gobbling command.
-
-\permanent\def\executeifdefined#1% #2 / never change this one again
- {\ifcsname#1\endcsname
- \expandafter\expandafter\expandafter\lastnamedcs\expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-%D This one also has the advantage that it is fully expandable and that it can be
-%D used after an assignment.
-
-%D \macros
-%D {doifsomespaceelse}
-%D
-%D The next command checks a string on the presence of a space and executed a
-%D command accordingly.
-%D
-%D \starttyping
-%D \doifsomespaceelse {tekst} {then ...} {else ...}
-%D \stoptyping
-%D
-%D We use this command in \CONTEXT\ for determing if an argument must be broken into
-%D words when made interactive. Watch the use of \type {\noexpand}.
-
-%D Is this one still needed?
-
-% \def\syst_helpers_if_some_space_else#1 #2#3^^^^0004{\if\noexpand#2@}
-%
-% \def\doifelsesomespace#1% % #2#3%
-% {\syst_helpers_if_some_space_else#1 @ @^^^^0004% #3\else#2\fi}
-% \expandafter\secondoftwoarguments
-% \else
-% \expandafter\firstoftwoarguments
-% \fi}
-
-\permanent\edef\doifelsesomespace#1%
- {\noexpand\ifhastok\space{#1}%
- \noexpand\expandafter\noexpand\firstoftwoarguments
- \noexpand\else
- \noexpand\expandafter\noexpand\secondoftwoarguments
- \noexpand\fi}
-
-\aliased\let\doifsomespaceelse\doifelsesomespace
-
-%D \macros
-%D {processseparatedlist}
-%D
-%D Maybe a bit late, but here is a more general version of the \type
-%D {\processcommalist} command. This time we don't handle nesting but accept
-%D arbitrary seperators.
-%D
-%D \starttyping
-%D \processseparatedlist[list][separator]\command
-%D \stoptyping
-%D
-%D One can think of things like:
-%D
-%D \starttyping
-%D \processseparatedlist[alfa+beta+gamma][+]\message
-%D \stoptyping
-%D
-%D We want to handle all situations, like:
-%D
-%D \startbuffer
-%D \processseparatedlist[{aap noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
-%D \processseparatedlist[{aap} {noot}][ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
-%D \processseparatedlist[aap {noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
-%D \processseparatedlist[aap noot] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
-%D \stopbuffer
-%D
-%D \typebuffer \getbuffer
-%D
-%D Therefore we smuggle a \type {\relax} in front of the argument, which we remove
-%D afterwards.
-
-\let\syst_helpers_process_separated_list_step\relax
-
-% \def\syst_helpers_process_separated_list#1]#*[#2]#3%
-% {\def\syst_helpers_process_separated_list_step##1##2#2%
-% {\def\m_syst_string_one{##2}% suggested by VZ
-% \if]##1%
-% \let\syst_helpers_process_separated_list_step\relax
-% \orelse\ifx\blankspace\m_syst_string_one
-% #3{##1}%
-% \orelse\if]##2%
-% \let\syst_helpers_process_separated_list_step\relax
-% \else
-% #3{##1##2}%
-% \fi
-% \syst_helpers_process_separated_list_step}%
-% \expandafter\syst_helpers_process_separated_list_step\gobbleoneargument#1#2]#2}
-
-% \def\syst_helpers_process_separated_list#1]#*[#2]#3%
-% {\def\syst_helpers_process_separated_list_step##1##2#2%
-% {\def\m_syst_string_one{##2}% suggested by VZ
-% \if]##1%
-% \orelse\ifx\blankspace\m_syst_string_one
-% #3{##1}%
-% \expandafter\syst_helpers_process_separated_list_step
-% \orelse\if]##2%
-% \else
-% #3{##1##2}%
-% \expandafter\syst_helpers_process_separated_list_step
-% \fi
-% }%
-% \expandafter\syst_helpers_process_separated_list_step\gobbleoneargument#1#2]#2}
-
-% \permanent\protected\def\processseparatedlist[%
-% {\syst_helpers_process_separated_list\relax}
-
-\permanent\protected\def\processseparatedlist[#+]#*[#2]#3%
- {\tolerant\def\syst_helpers_process_separated_list_step##1#2%
- {\ifarguments\or
- #3{##1}%
- \expandafter\syst_helpers_process_separated_list_step
- \fi}%
- \syst_helpers_process_separated_list_step#1\ignorearguments\ignorearguments}
-
-%D \macros
-%D {processlist}
-%D
-%D An even more general list processing macro is the following one:
-%D
-%D \starttyping
-%D \processlist{beginsym}{endsym}{separator}\docommand list
-%D \stoptyping
-%D
-%D This one supports arbitrary open and close symbols as well as user defined
-%D separators.
-%D
-%D \starttyping
-%D \processlist(){=>}\docommand(a=>b=>c=>d)
-%D \stoptyping
-
-\let\syst_helpers_process_any_list \relax
-\let\syst_helpers_process_any_list_indeed\relax
-\let\syst_helpers_process_any_list_step \relax
-
-\permanent\protected\def\processlist#1#2#3#4% no blank skipping !
- {\def\syst_helpers_process_any_list_indeed##1#2%
- {\def\syst_helpers_process_any_list_step####1####2#3%
- {\ifx#2####1%
- \let\syst_helpers_process_any_list_step\relax
- \orelse\ifx#2####2%
- \let\syst_helpers_process_any_list_step\relax
- \else
- #4{####1####2}%
- \fi
- \syst_helpers_process_any_list_step}%
- \expandafter\syst_helpers_process_any_list_step\gobbleoneargument##1#3#2#3}%
- \def\syst_helpers_process_any_list#1%
- {\syst_helpers_process_any_list_indeed\relax}%
- \syst_helpers_process_any_list}
-
-%D \macros
-%D {processassignlist}
-%D
-%D Is possible to combine an assignment list with one containing keywords.
-%D Assignments are treated accordingly, keywords are treated by \type {\command}.
-%D
-%D \starttyping
-%D \processassignlist[...=...,...=...,...]\commando
-%D \stoptyping
-%D
-%D This command can be integrated in \type {\getparameters}, but we decided best not
-%D to do so.
-
-% \protected\def\processassignlist#1[#2]#3%
-% {\def\syst_helpers_process_assign_list_assign[##1=##2=##3]%
-% {\doif{##3}\relax{#3{##1}}}%
-% \def\syst_helpers_process_assign_list_step##1%
-% {\syst_helpers_process_assign_list_assign[##1==\relax]}%
-% \processcommalist[#2]\syst_helpers_process_assign_list_step}
-
-\permanent\protected\def\processassignlist#1[#2]#3%
- {\def\syst_helpers_process_assign_list_assign[##1=##-=##2]%
- {\doif{##2}\relax{#3{##1}}}%
- \def\syst_helpers_process_assign_list_step##1%
- {\syst_helpers_process_assign_list_assign[##1==\relax]}%
- \processcommalist[#2]\syst_helpers_process_assign_list_step}
-
-%D \macros
-%D {untextargument
-%D untexcommand}
-%D
-%D When manipulating data(bases) and for instance generating index entries, the next
-%D three macros can be of help:
-%D
-%D \starttyping
-%D \untextargument{...}\to\name
-%D \untexcommand {...}\to\name
-%D \stoptyping
-%D
-%D They remove braces and backslashes and give us something to sort.
-
-\let\m_syst_helpers_untexed\empty
-
-\permanent\protected\def\untexsomething
- {\begingroup
- \catcode\leftbraceasciicode \ignorecatcode
- \catcode\rightbraceasciicode\ignorecatcode
- \escapechar\minusone
- \syst_helpers_untex_something}
-
-\def\syst_helpers_untex_something#1#2\to#3%
- {\doglobal#1#2\to\m_syst_helpers_untexed
- \endgroup
- \let#3\m_syst_helpers_untexed}
-
-\permanent\protected\def\untexargument{\untexsomething\convertargument}
-\permanent\protected\def\untexcommand {\untexsomething\convertcommand}
-
-%D \macros
-%D {ScaledPointsToBigPoints,ScaledPointsToWholeBigPoints}
-%D
-%D One characteristic of \POSTSCRIPT\ and \PDF\ is that both used big points (\TEX's
-%D bp). The next macros convert points and scaled points into big points. The magic
-%D factor $72/72.27$ can be found in most \TEX\ related books.
-%D
-%D \starttyping
-%D \ScaledPointsToBigPoints {number} \target
-%D \ScaledPointsToWholeBigPoints {number} \target
-%D \stoptyping
-
-\aliased\let\tobigpoints \clf_tobigpoints % todo: permanent at lua end
-\aliased\let\towholebigpoints\clf_towholebigpoints % todo: permanent at lua end
-
-\permanent\protected\def\PointsToBigPoints #1#2{\edef#2{\tobigpoints #1}} % can be avoided
-\permanent\protected\def\PointsToWholeBigPoints #1#2{\edef#2{\towholebigpoints#1}} % can be avoided
-\permanent\protected\def\ScaledPointsToBigPoints #1#2{\edef#2{\tobigpoints #1\scaledpoint}} % obsolete
-\permanent\protected\def\ScaledPointsToWholeBigPoints#1#2{\edef#2{\towholebigpoints#1\scaledpoint}} % obsolete
-
-%D \macros
-%D {PointsToReal}
-%D
-%D Points can be stripped from their suffix by using \type {\withoutpt}. The next
-%D macro enveloppes this macro.
-%D
-%D \starttyping
-%D \PointsToReal {dimension} \target
-%D \stoptyping
-
-% \protected\def\PointsToReal#1#2%
-% {\edef#2{\withoutpt\the\dimexpr#1}}
-
-\permanent\protected\def\PointsToReal#1#2%
- {\edef#2{\thewithoutunit\dimexpr#1}}
-
-%D \macros
-%D {dontleavehmode}
-%D
-%D Sometimes when we enter a paragraph with some command, the first token gets the
-%D whole first line. We can prevent this by saying:
-%D
-%D \starttyping
-%D \dontleavehmode
-%D \stoptyping
-%D
-%D This command is used in for instance the language module \type {lang-ini}. The
-%D first version was:
-%D
-%D \starttyping
-%D \def\dontleavehmode{\ifhmode\orelse\ifmmode\else$ $\fi}
-%D \stoptyping
-%D
-%D Next, Taco came with a better alternative (using mathsurround):
-%D
-%D \starttyping
-%D \def\dontleavehmode
-%D {\ifhmode\else \ifmmode\else
-%D {\mathsurround\zeropoint\everymath\emptytoks$ $}%
-%D \fi \fi}
-%D \stoptyping
-%D
-%D And finaly we got the following alternative, one that avoids interfering grouping
-%D at the cost of a box.
-%D
-%D \starttyping
-%D \newbox\b_syst_helpers_dlh
-%D
-%D \protected\def\dontleavehmode
-%D {\ifhmode\else \ifmmode\else
-%D \setbox\b_syst_helpers_dlh\hbox{\mathsurround\zeropoint\everymath\emptytoks$ $}\unhbox\b_syst_helpers_dlh
-%D \fi \fi}
-%D \stoptyping
-%D
-%D But, as we run a recent version of \TEX, we can use the new primitive:
-
-\ifdefined\normalquitvmode \let\dontleavehmode\normalquitvmode \fi
-
-%D \macros
-%D {utfupper, utflower, uppercasestring, lowercasestring}
-%D
-%D The names tell what they do:
-%D
-%D \starttyping
-%D \uppercasestring somestring\to\somestring
-%D \lowercasestring somestring\to\somestring
-%D \stoptyping
-%D
-%D The first argument may be a \type{\macro}.
-%D
-%D These macros are sort of obsolete as we never use uppercase this way. But
-%D nevertheless we provide them:
-
-\permanent\def\utfupper#1{\clf_upper{#1}} % expandable
-\permanent\def\utflower#1{\clf_lower{#1}} % expandable
-
-\permanent\protected\def\uppercasestring#1\to#2{\dodoglobal\edef#2{\clf_upper{#1}}}
-\permanent\protected\def\lowercasestring#1\to#2{\dodoglobal\edef#2{\clf_lower{#1}}}
-
-%D \macros
-%D {handletokens}
-%D
-%D With the next macro we enter a critical area of macro expansion. What we want is
-%D a macro that looks like:
-%D
-%D \starttyping
-%D \handletokens some tokens\with \somemacro
-%D \stoptyping
-%D
-%D A bonus example:
-%D
-%D \starttyping
-%D \hbox{\handletokens tekst en meer tekst\with\ruledhbox}
-%D
-%D \def\weetikveel#1{\if#1\blankspace\space\else\ruledhbox{#1}\fi}
-%D
-%D \hbox{\handletokens tekst en meer tekst\with\weetikveel}
-%D \stoptyping
-
-%D \macros
-%D {counttoken,counttokens}
-%D
-%D For the few occasions that we want to know the number of specific tokens in a
-%D string, we can use:
-%D
-%D \starttyping
-%D \counttoken token\in string\to \somecount
-%D \counttokens string\to \somecount
-%D \stoptyping
-%D
-%D This macro, that for instance is used in \type {cont-tab}, takes a real counter.
-%D The macro can be preceded by \type {\doglobal}.
-
-\def\syst_helpers_count_token#1% obeys {}
- {\def\m_syst_string_three{#1}%
- \ifx\m_syst_string_two\m_syst_string_three \else
- \ifx\m_syst_string_one\m_syst_string_three
- \advance\privatescratchcounter\plusone
- \fi
- \expandafter\syst_helpers_count_token
- \fi}
-
-\permanent\protected\def\counttoken#1\in#2\to#3%
- {\privatescratchcounter\zerocount
- \def\m_syst_string_one{#1}%
- \def\m_syst_string_two{\end}%
- \syst_helpers_count_token#2\end
- \dodoglobal#3\privatescratchcounter}
-
-\permanent\protected\def\counttokens#1\to#2%
- {\privatescratchcounter\zerocount
- \def\syst_helpers_count_token##1{\advance\privatescratchcounter\plusone}%
- \handletokens#1\with\syst_helpers_count_token
- \dodoglobal#2\privatescratchcounter}
-
-%D \macros
-%D {splitofftokens}
-%D
-%D Running this one not always gives the expected results. Consider for instance the
-%D macro for which I originally wrote this token handler.
-
-\permanent\protected\def\splitofftokens#1\from#2\to#3% slow but hardly used
- {\ifnum#1>\zerocount
- \privatescratchcounter#1\relax
- \def\syst_helpers_split_off_tokens##1%
- {\ifnum\privatescratchcounter>\zerocount
- \advance\privatescratchcounter \minusone
- \edef#3{#3##1}%
- \fi}%
- % \let#3\empty % #3 can be #2, so:
- \expandafter\let\expandafter#3\expandafter\empty
- \expandafter\handletokens#2\with\syst_helpers_split_off_tokens
- \else
- \edef#3{#2}%
- \fi}
-
-%D This macro can be called like:
-%D
-%D \startbuffer[example]
-%D \splitofftokens10\from01234567 890123456789\to\test [\test]
-%D \stopbuffer
-%D
-%D up there. The reason for this is not that logical but follows from \TEX's
-%D However, the characters that we expect to find in \type {\test} just don't show
-%D sometimes 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 \expandafter\edef\expandafter\test\expandafter{\test\next} [\test]
-%D \stopbuffer
-%D
-%D \typebuffer[next]
-%D
-%D Careful reading shows that inside an \type {\edef} macro's that are \type {\let}
-%D are not expanded!
-%D
-%D \unprotect\getbuffer[next]\protect
-%D
-%D That's why we finally end up with a macro that looks ahead by using an
-%D assignment, this time by using \type {\futurelet}, and grabbing an argument as
-%D well. That way we can handle the sentinal, a blank space and grouped tokens.
-
-\protected\def\syst_helpers_handle_tokens % \nexthandledtoken is part of interface
- {\futurelet\nexthandledtoken\syst_helpers_handle_tokens_indeed}
-
-\permanent\protected\def\handletokens#1\with#2%
- {\gdef\syst_helpers_handle_tokens_command{#2}% permits more complex #2's
- \syst_helpers_handle_tokens#1\end}
-
-\def\syst_helpers_handle_tokens_indeed
- {\ifx\nexthandledtoken\blankspace
- \expandafter\syst_helpers_handle_tokens_indeed_one
- \orelse\ifx\nexthandledtoken\end
- \expandafter\gobbletwoarguments % also gobble the \end
- \else
- \expandafter\syst_helpers_handle_tokens_indeed_two
- \fi *}
-
-\def\syst_helpers_handle_tokens_indeed_one * %
- {\syst_helpers_handle_tokens_command{ }\syst_helpers_handle_tokens}
-
-\def\syst_helpers_handle_tokens_indeed_two *#1%
- {\syst_helpers_handle_tokens_command{#1}\syst_helpers_handle_tokens}
-
-%D This macro is tested on:
-%D
-%D \def\xxx#1{[#1]}
-%D
-%D \startlines
-%D \handletokens abc\with\xxx
-%D \handletokens a b c\with\xxx
-%D \handletokens a b c\with\xxx
-%D \handletokens a{bc}d\with\xxx
-%D \handletokens a\space bc \with\xxx
-%D \stoplines
-%D
-%D And our previous example shows up as:
-%D
-%D \getbuffer[example]
-
-%D \macros
-%D {iftrialtypesetting, ifvisible}
-%D
-%D The next boolean is at first sight a strange one. Sometimes one does a trial
-%D typesetting run, for instance to determine dimensions. Some mechanisms, like
-%D object inclusion, can fail on such trials. Temporary setting the next boolean to
-%D true, helps a lot. The second boolena can be used to inhibit processing
-%D completely.
-
-\newif\ifvisible \visibletrue
-
-\newtoks\everysettrialtypesetting
-\newtoks\everyresettrialtypesetting
-
-\permanent\protected\def\settrialtypesetting {\the\everysettrialtypesetting } % obeys grouping so
-\permanent\protected\def\resettrialtypesetting{\the\everyresettrialtypesetting} % this one is seldom needed
-
-\let\iftrialtypesetting\iffalse % so we have no \trialtypesettingtrue|false in mkiv !
-
-\appendtoks \let\iftrialtypesetting\iftrue \to \everysettrialtypesetting
-\appendtoks \let\iftrialtypesetting\iffalse \to \everyresettrialtypesetting
-
-%D \macros
-%D {twodigitrounding}
-%D
-%D When using \type {\special}s or \type {\pdfliteral}s, it sometimes makes sense to
-%D limit the precission. The next macro rounds a real number to two digits. It takes
-%D one argument and only works in \ETEX.
-
-\permanent\def\integerrounding #1{\clf_rounded\zerocount\numexpr#1\relax}
-\permanent\def\onedigitrounding #1{\clf_rounded\plusone \numexpr#1\relax}
-\permanent\def\twodigitrounding #1{\clf_rounded\plustwo \numexpr#1\relax}
-\permanent\def\threedigitrounding#1{\clf_rounded\plusthree\numexpr#1\relax}
-
-%D \macros
-%D {processcontent}
-%D
-%D This macro is first used in the tabulation macros.
-%D
-%D \starttyping
-%D \protected\def\starthans%
-%D {\processcontent{stophans}\test{\message{\test}\wait}}
-%D \stoptyping
-
-\permanent\protected\def\processcontent#1%
- {\begingroup\expandafter\syst_helpers_process_content\csname#1\endcsname}
-
-\protected\def\syst_helpers_process_content#1#2#3%
- {\protected\def\syst_helpers_process_content##1#1%
- {\endgroup\def#2{##1}#3}%
- \syst_helpers_process_content}
-
-%D \macros
-%D {dogobblesingleempty, dogobbledoubleempty}
-%D
-%D These two macros savely grab and dispose two arguments.
-
-\permanent\tolerant\protected\def\dogobblesingleempty [#-]{}
-\permanent\tolerant\protected\def\dogobbledoubleempty[#-]#*[#-]{}
-
-\aliased\let\gobblesingleempty\dogobblesingleempty % also used
-\aliased\let\gobbledoubleempty\dogobbledoubleempty % also used
-
-%D \macros
-%D {setdimensionwithunit, freezedimensionwithunit}
-%D
-%D The next assignments are all valid:
-%D
-%D \starttyping
-%D \setdimensionwithunit\scratchdimen{10} {cm}
-%D \setdimensionwithunit\scratchdimen{10cm}{cm}
-%D \setdimensionwithunit\scratchdimen{10cm}{}
-%D \freezedimensionwithunit\SomeWidth{\textwidth}
-%D \freezedimensionwithunit\SomeDepth{\dp\strutbox}
-%D \stoptyping
-%D
-%D As an alternative for the next macro we can use a global assignment inside a box.
-%D The \type {\empty}'s permits gobbling while preventing spurious \type {\relax}'s.
-
-\permanent\protected\def\setdimensionwithunit#1#2#3% number unit dimension / nice trick
- {\afterassignment\gobblefourarguments#1=#2#3pt\relax\empty\empty\empty\empty}
-
-\permanent\protected\def\freezedimensionwithunit#1#2%
- {\setdimensionwithunit\privatescratchdimen#1{#2}\edef#1{\the\privatescratchdimen}}
-
-%D \macros
-%D {doifsometokselse, doifsometoks}
-%D
-%D Not that fast I guess, but here's a way to test for token registers being empty.
-
-\permanent\protected\def\doifelsesometoks#1%
- {\iftok#1\emptytoks
- \expandafter\secondoftwoarguments
- \else
- \expandafter\firstoftwoarguments
- \fi}
-
-\permanent\protected\def\doifsometoks#1%
- {\iftok#1\emptytoks
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\permanent\protected\def\doifemptytoks#1%
- {\iftok#1\emptytoks
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\aliased\let\doifsometokselse\doifelsesometoks
-
-%D \macros
-%D {startstrictinspectnextcharacter}
-%D
-%D This one is for the bibliography module (still?):
-
-\let\syst_helpers_strict_inspect_next_character[
-
-\def\syst_helpers_strict_inspect_next_character% no user macro !
- {\ifx\nexttoken[%
- \expandafter\m_syst_action_yes
- \else
- \expandafter\m_syst_action_nop
- \fi}
-
-\permanent\protected\def\strictdoifelsenextoptional#1#2%
- {\def\m_syst_action_yes{#1}%
- \def\m_syst_action_nop{#2}%
- \futurelet\nexttoken\syst_helpers_strict_inspect_next_character}
-
-\aliased\let\strictdoifnextoptionalelse\strictdoifelsenextoptional
-
-%D \macros
-%D {gobblespacetokens}
-%D
-%D This macro needs a speed-up!
-
-%\def\gobblespacetokens
-% {\doifnextcharelse\empty\donothing\donothing} % no {}\do\do !
-
-\permanent\def\gobblespacetokens
- {\afterassignment\nexttoken\let\nexttoken=}
-
-%D \macros
-%D {verbatimargument}
-%D
-%D As the name says, this macro converts its argument to a (rather safe) string.
-
-\aliased\let\verbatimstring\detokenize
-
-%D These are needed in ordinal number conversions:
-
-\permanent\def\lastdigit#1%
- {\expandafter\thelastdigit\number#1\relax}
-
-\permanent\def\thelastdigit#1#2%
- {\ifx#2\relax#1\else\expandafter\thelastdigit\expandafter#2\fi}
-
-\permanent\def\lasttwodigits#1%
- {\expandafter\thelasttwodigits\expandafter0\number#1\relax}
-
-\permanent\def\thelasttwodigits#1#2#3% 0 dig ... \relax
- {\ifx#3\relax#1#2\else\expandafter\thelasttwodigits\expandafter#2\expandafter#3\fi}
-
-%D \macros
-%D {serializecommalist}
-%D
-%D Concatenate commalists:
-
-\let\syst_helpers_serialize_comma_list_step\relax
-
-\def\syst_helpers_serialize_comma_list_step#1%
- {\edef\serializedcommalist{\serializedcommalist#1}}
-
-\permanent\protected\def\serializecommalist[#1]%
- {\let\serializedcommalist\empty
- \processcommacommand[#1]\syst_helpers_serialize_comma_list_step}
-
-%D \macros
-%D {purenumber}
-%D
-%D Sometimes we need control over when \TEX\ stops reading a number, especially in
-%D full expandable macros where using \type {\relax} would lead to disasters.
-%D
-%D \starttyping
-%D \ifodd\purenumber{...}\space ... \else ... \fi
-%D \stoptyping
-%D
-%D Here we use a space as number delimiter in combination with a space- and
-%D relax-less \type {\purenumber}. This macro works ok with \type {\the}, \type
-%D {\number} as well as \ETEX's \type {\numexpr}.
-
-\permanent\def\purenumber#1{\expandafter\firstofoneargument\expandafter{\number#1}}
-
-%D \macros
-%D {filterfromvalue}
-%D
-%D \starttyping
-%D \setvalue{xx}{{A}{B}{C}}
-%D
-%D \filterfromvalue{xx}{3}{3}
-%D \filterfromvalue{xx}{3}{2}
-%D \filterfromvalue{xx}{3}{1}
-%D \stoptyping
-%D
-%D An alternative is to store 'max' in the list, say:
-%D
-%D \starttyping
-%D \setvalue{xx}{3{A}{B}{C}}
-%D
-%D \filterfromvalues{3}{xx}{3}
-%D \filterfromvalues{3}{xx}{2}
-%D \filterfromvalues{3}{xx}{1}
-%D \stoptyping
-%D
-%D I'll implement this when I'm in \quotation {writing dirty macros mood}.
-
-\permanent\def\dofilterfromstr#1#2% max n % no need to be fast
- {\expandafter \expandafter \expandafter \csstring
- \ifcase#1\or \ifcase#2\or
- \firstofoneargument \else
- \gobbleoneargument \fi
- \or \ifcase#2\or
- \firstoftwoarguments \or
- \secondoftwoarguments \else
- \gobbletwoarguments \fi
- \or \ifcase#2\or
- \firstofthreearguments \or
- \secondofthreearguments \or
- \thirdofthreearguments \else
- \gobblethreearguments \fi
- \or \ifcase#2\or
- \firstoffourarguments \or
- \secondoffourarguments \or
- \thirdoffourarguments \or
- \fourthoffourarguments \else
- \gobblefourarguments \fi
- \or \ifcase#2\or
- \firstoffivearguments \or
- \secondoffivearguments \or
- \thirdoffivearguments \or
- \fourthoffivearguments \or
- \fifthoffivearguments \else
- \gobblefivearguments \fi
- \fi}
-
-\permanent\def\filterfromvalue#1#2#3% value max n
- {\expandafter\doubleexpandafter\csname % we use the fact that an
- \expandafter\ifx\csname#1\endcsname\relax % undefined cs has become \relax
- \csstring\gobbleoneargument % which we then gobble here
- \else
- \dofilterfromstr{#2}{#3}%
- \fi
- \endcsname\csname#1\endcsname}
-
-\permanent\def\filterfromnext#1#2% max n {..}{..}{..}{..}
- {\csname\dofilterfromstr{#1}{#2}\endcsname}
-
-%D \macros
-%D {definemeasure}
-%D
-%D \starttyping
-%D \definemeasure[mywidth][\dimexpr(\textwidth-1cm)]
-%D
-%D ... \measure{mywidth} ...
-%D \stoptyping
-
-\installsystemnamespace{measure}
-
-\permanent\tolerant\protected\def\definemeasure[#1]#*[#2]{\defcsname \??measure#1\endcsname{#2}}
-\permanent\tolerant\protected\def\freezemeasure[#1]#*[#2]{\edefcsname\??measure#1\endcsname{\the\dimexpr#2}}
-
-\permanent\protected\def\setmeasure #1#2{\defcsname \??measure#1\endcsname{#2}} % quick way
-\permanent\protected\def\setgmeasure#1#2{\global\defcsname \??measure#1\endcsname{#2}} % quick way
-\permanent\protected\def\setemeasure#1#2{\edefcsname \??measure#1\endcsname{\the\dimexpr#2}} % quick way
-\permanent\protected\def\setxmeasure#1#2{\global\edefcsname\??measure#1\endcsname{\the\dimexpr#2}} % quick way
-
-\permanent\def\measure {\the\measured}
-\permanent\def\measured#1{\dimexpr\ifcsname\??measure#1\endcsname\lastnamedcs\else\zeropoint\fi\relax}
-
-% #2 could be omitted, but we want to support spaces
-%
-% \setmeasure {x} {1cm}
-% \setmeasure {xx} {1cm}
-% \setmeasure {xxx}{1cm}
-
-%D \macros
-%D {definequantity}
-%D
-%D These do the same but for numbers.
-
-\installsystemnamespace{quantity}
-
-\permanent\tolerant\protected\def\definequantity[#1]#*[#2]{\defcsname \??quantity#1\endcsname{#2}}
-\permanent\tolerant\protected\def\freezequantity[#1]#*[#2]{\edefcsname\??quantity#1\endcsname{\the\numexpr#2}}
-
-\permanent\protected\def\setquantity #1#2{\defcsname \??quantity#1\endcsname{#2}} % quick way
-\permanent\protected\def\setgquantity#1#2{\global\defcsname \??quantity#1\endcsname{#2}} % quick way
-\permanent\protected\def\setequantity#1#2{\edefcsname \??quantity#1\endcsname{\the\numexpr#2}} % quick way
-\permanent\protected\def\setxquantity#1#2{\global\edefcsname\??quantity#1\endcsname{\the\numexpr#2}} % quick way
-
-\permanent\def\quantity {\the\quantitied}
-\permanent\def\quantitied #1{\numexpr\ifcsname\??quantity#1\endcsname\lastnamedcs\else\zeropoint\fi\relax}
-\permanent\def\directquantity#1{\the\numexpr#1\relax}
-
-% let\quantified\quantitied
-
-%D \macros
-%D {dividedsize}
-%D
-%D This one can be used inside a measure (used in m4all):
-%D
-%D \starttyping
-%D \definemeasure[columnwidth][\dividedsize\textwidth{1em}{3}]
-%D \stoptyping
-
-\permanent\def\dividedsize#1#2#3% size gap n
- {\dimexpr
- \ifnum\dimexpr#1\relax>\plusone
- (\dimexpr#1\relax-\numexpr#3-\plusone\relax\dimexpr#2\relax)/#3\else#1%
- \fi
- \relax}
-
-%D \macros
-%D {doifdimensionelse}
-%D
-%D This is a dirty one: we simply append a unit and discard it when needed.
-
-\permanent\def\doifelsedimension#1%
- {\ifchkdim#1\or
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifdimensionelse\doifelsedimension
-
-%D Ok, here's another one, slower but seldom used. This one scans the text.
-%D
-%D \starttabulate[|Tc|Tc|]
-%D \NC pt \NC \doifdimenstringelse {pt}{yes}{no} \NC \NR
-%D \NC 12pt \NC \doifdimenstringelse {-12pt}{yes}{no} \NC \NR
-%D \NC 1pt \NC \doifdimenstringelse {1pt}{yes}{no} \NC \NR
-%D \NC 12pt \NC \doifdimenstringelse {12pt}{yes}{no} \NC \NR
-%D \NC 12.0pt \NC \doifdimenstringelse {12.0pt}{yes}{no} \NC \NR
-%D \NC -.12pt \NC \doifdimenstringelse {-.12pt}{yes}{no} \NC \NR
-%D \NC .12pt \NC \doifdimenstringelse {.12pt}{yes}{no} \NC \NR
-%D \NC -12pt \NC \doifdimenstringelse {-12pt}{yes}{no} \NC \NR
-%D \NC -12.0pt \NC \doifdimenstringelse{-12.0pt}{yes}{no} \NC \NR
-%D \NC big \NC \doifdimenstringelse {big}{yes}{no} \NC \NR
-%D \NC 10 \NC \doifdimenstringelse {10}{yes}{no} \NC \NR
-%D \NC 1 \NC \doifdimenstringelse {1}{yes}{no} \NC \NR
-%D \stoptabulate
-
-\aliased\let\doifelsedimenstring\doifelsedimension
-\aliased\let\doifdimenstringelse\doifelsedimenstring
-
-%D \macros
-%D {comparedimension,comparedimensioneps}
-%D
-%D We no longer use the \MKIV\ dirty trick. These are obsolete anyway.
-
-\newdimen \roundingeps \roundingeps=10sp
-\newconstant\compresult
-
-\permanent\def\comparedimension#1#2%
- {\compresult
- \ifdim#1<#2%
- \zerocount
- \orelse\ifdim#1<#2%
- \plusone
- \else
- \plustwo
- \fi}
-
-\permanent\def\comparedimensioneps#1#2% todo: use eps feature
- {\compresult
- \ifdim\dimexpr#1-#2\relax<\roudingeps
- \zerocount
- \orelse\ifdim\dimexpr#2-#1\relax<\roudingeps
- \zerocount
- \orelse\ifdim#1<#2%
- \plusone
- \else
- \plustwo
- \fi}
-
-% pretty ugly but fast
-
-% \copycsname xxx\endcsname\csname ..\endcsname
-
-\permanent\protected\def\copycsname{\expandafter\expandafter\expandafter\let\expandafter\expandafter\csname}
-
-% \letcscsname \crap \csname ..\endcsname
-% \letcsnamecs \csname ..\endcsname\crap
-% \letcsnamecsname\csname ..\endcsname\csname ..\endcsname
-
-\permanent\protected\def\letcscsname {\expandafter\let\expandafter}
-\permanent\protected\def\letcsnamecs {\expandafter\let}
-\permanent\protected\def\letcsnamecsname{\expandafter\expandafter\expandafter\let\expandafter\expandafter}
-
-% another one, add an item to a commalist
-
-\permanent\protected\def\addvalue#1#2% cs item
- {\ifcsname#1\endcsname\else\letcsname#1\endcsname\empty\fi
- \normalexpanded{\addtocommalist{#2}\expandafter\noexpand\csname#1\endcsname}}
-
-%D Are these ever used? Anyway, these variants are somewhat more efficient than
-%D the \MKIV variants for larger strings.
-
-% A variant:
-%
-% \permanent\def\unspaced#1%
-% {\localcontrolled{\begingroup\catcode\spaceasciicode\ignorecatcode}%
-% \tokenized{#1}%
-% \localcontrolled{\endgroup}}
-%
-% but we can also do this:
-
-\permanent\def\unspaced#1%
- {\tokenized \s!catcodetable \ctdcatcodes {#1}}
-
-\permanent\protected\def\unspaceargument#1\to#2%
- {\edef#2{\tokenized \s!catcodetable \ctdcatcodes {#1}}}
-
-\protected\def\unspaceafter#1#2%
- {\expandafter#1\expandafter{\tokenized \s!catcodetable \ctdcatcodes {#2}}}
-
-\permanent\protected\def\doifelsehasspace#1%
- {\expandafter\ifhastok\space{#1}%
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifhasspaceelse\doifelsehasspace
-
-% this will replace loadfile once and alike !!! todo
-
-\installsystemnamespace{flag}
-
-\protected\def\setflag #1{\dodoglobal\letcsname\??flag#1\endcsname\zerocount}
-\protected\def\resetflag#1{\dodoglobal\letcsname\??flag#1\endcsname\plusone}
-
-\permanent\def\flag#1{\csname\??flag#1\endcsname}
-
-\permanent\def\doifelseflagged#1%
- {\expandafter\ifx\csname\??flag#1\endcsname\relax
- \expandafter\secondoftwoarguments
- \orelse\ifcase\csname\??flag#1\endcsname
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\aliased\let\doifflaggedelse\doifelseflagged
-
-\permanent\def\doifnotflagged#1%
- {\expandafter\ifx\csname\??flag#1\endcsname\relax
- \expandafter\firstofoneargument
- \orelse\ifcase\csname\??flag#1\endcsname
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
-
-\permanent\protected\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey
- {\defcsname#1#3\expandafter\endcsname\expandafter{\csname#1#5\endcsname}}
-
-\def\syst_helpers_if_non_zero_positive_else#1#2\end % #3#4%
- {\ifx#1\relax
- \ifcase\privatescratchcounter
- \endgroup
- \doubleexpandafter\secondoftwoarguments
- \else
- \endgroup
- \doubleexpandafter\firstoftwoarguments
- \fi
- \else
- \endgroup
- \expandafter\secondoftwoarguments
- \fi}
-
-% used ?
-
-\permanent\def\doifelsenonzeropositive#1%
- {\begingroup\afterassignment\syst_helpers_if_non_zero_positive_else\privatescratchcounter=0#1\relax\empty\end}
-
-\aliased\let\doifnonzeropositiveelse\doifelsenonzeropositive
-
-% here ?
-
-\protected\def\dosetrawvalue #1#2#3{\defcsname #1#2\endcsname{#3}}
-\protected\def\dosetrawevalue#1#2#3{\edefcsname #1#2\endcsname{#3}}
-\protected\def\dosetrawgvalue#1#2#3{\global\defcsname #1#2\endcsname{#3}}
-\protected\def\dosetrawxvalue#1#2#3{\global\edefcsname#1#2\endcsname{#3}}
-
-\permanent\protected\def\getrawparameters {\dogetparameters\dosetrawvalue }
-\permanent\protected\def\getraweparameters {\dogetparameters\dosetrawevalue}
-\permanent\protected\def\getrawgparameters {\dogetparameters\dosetrawgvalue}
-\permanent\protected\def\getrawxparameters {\dogetparameters\dosetrawxvalue}
-
-\permanent\protected\def\globalgetrawparameters{\dogetparameters\dosetrawgvalue} % obsolete
-
-%D Sort of obsolete:
-
-\newcount\c_syst_helpers_mod
-
-\permanent\protected\def\dosetmodulo#1#2#3%
- {\c_syst_helpers_mod#1\divide\c_syst_helpers_mod#2\multiply\c_syst_helpers_mod#2%
- #3#1\advance#3-\c_syst_helpers_mod}
-
-\permanent\protected\def\dosetdivision#1#2#3%
- {#3#1\divide#3 #2\relax}
-
-\permanent\protected\def\DoMod#1by#2to#3{\dosetmodulo {#1}{#2}{#3}}
-\permanent\protected\def\DoDiv#1by#2to#3{\dosetdivision{#1}{#2}{#3}}
-
-\def\syst_helpers_unprotected#1\par
- {#1\protect}
-
-\protected\def\unprotected
- {\unprotect
- \syst_helpers_unprotected}
-
-\aliased\let\resettimer \clf_resettimer % todo: at lua end
-\aliased\let\elapsedtime \clf_elapsedtime % todo: at lua end
-\aliased\let\elapsedseconds\elapsedtime
-
-\let\elapsedsteps\!!zerocount
-
-\permanent\protected\def\elapsedsteptime % unexpanded ! a bit useless but who knows ...
- {\clf_elapsedsteptime\elapsedsteps\relax}
-
-\newcount\c_syst_helpers_test_feature_n
-\newcount\c_syst_helpers_test_feature_m
-
-\def\currentfeaturetest{\number\c_syst_helpers_test_feature_n}
-
-\permanent\protected\def\testfeature#1#2%
- {\c_syst_helpers_test_feature_m#1\relax
- \xdef\elapsedsteps{\number\c_syst_helpers_test_feature_m}%
- \def\syst_helpers_test_feature_yes
- {\advance\c_syst_helpers_test_feature_n\plusone
- \ifnum\c_syst_helpers_test_feature_n>\c_syst_helpers_test_feature_m\else
- #2\expandafter\syst_helpers_test_feature_yes
- \fi}%
- \def\syst_helpers_test_feature_nop
- {\advance\c_syst_helpers_test_feature_n\plusone
- \ifnum\c_syst_helpers_test_feature_n>\c_syst_helpers_test_feature_m\else
- \expandafter\syst_helpers_test_feature_nop
- \fi}%
- \retestfeature}
-
-\permanent\protected\def\retestfeature % timer support is new per 10/5/2005
- {\bgroup
- \ifcase\interactionmode\let\wait\relax\fi
- \clf_resettimer
- \c_syst_helpers_test_feature_n\zerocount
- \syst_helpers_test_feature_nop
- \clf_benchmarktimer
- \writestatus\m!system
- {starting feature test: %
- \number\c_syst_helpers_test_feature_m\space steps}%
- \c_syst_helpers_test_feature_n\zerocount
- \syst_helpers_test_feature_yes
- \writestatus\m!system
- {feature test done: %
- \number\c_syst_helpers_test_feature_m\space steps, %
- \clf_elapsedtime\space seconds, %
- \clf_elapsedsteptime\elapsedsteps\space\space per step}%
- \egroup}
-
-\permanent\protected\def\showtimer#1%
- {\writestatus{runtime}{\elapsedseconds\space s / #1}}
-
-\permanent\protected\def\testfeatureonce#1#2%
- {\begingroup
- \let\wait\relax
- \testfeature{#1}{#2}%
- \endgroup}
-
-%D \macros
-%D {freezedimenmacro}
-%D
-%D This macro is use as:
-%D
-%D \starttyping
-%D \freezedimenmacro\leftmargindistance
-%D \stoptyping
-
-\permanent\protected\def\freezedimenmacro#1%
- {\edef#1{\the\dimexpr#1}}
-
-%D The next macro negates a macro (dimension or number, or actually, whatever. It's
-%D a typical example of \type {\if} usage:
-%D
-%D \starttyping
-%D \if-\whatever \else-\whatever\fi => else => -whatever
-%D \if--\whatever\else-\whatever\fi => then => whatever
-%D \stoptyping
-
-\permanent\def\negated#1{\if-#1\else-#1\fi} % does only work in macros or text
-
-\def\gobbleassigndimen#1\\{}
-
-\permanent\def\assigndimen#1#2%
- {\afterassignment\gobbleassigndimen#1=#2\zeropoint\\}
-
-\permanent\protected\def\appended#1#2#3{\expandafter#1\expandafter#2\expandafter{#2#3}}
-\permanent\protected\def\appendvalue #1{\expandafter\appended\expandafter \def\csname#1\endcsname}
-\permanent\protected\def\appendgvalue#1{\expandafter\appended\expandafter\gdef\csname#1\endcsname}
-
-\protected\def\prepended#1#2#3%
- {\t_syst_helpers_scratch{#3}%
- \expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter#2\expandafter\expandafter\expandafter
- {\expandafter\the\expandafter\t_syst_helpers_scratch#2}}
-
-\permanent\protected\def\prependvalue #1{\expandafter\prepended\expandafter \def\csname#1\endcsname}
-\permanent\protected\def\prependgvalue#1{\expandafter\prepended\expandafter\gdef\csname#1\endcsname}
-
-%D \macros
-%D {dowithrange}
-%D
-%D This one is for Mojca Miklavec, who made me aware of the fact that \type
-%D {page-imp.tex} was not the best place to hide it.
-%D
-%D \startbuffer
-%D \def\DoSomething#1{ [item #1] }
-%D
-%D \processranges[1,4:5]\DoSomething \par
-%D \dowithrange {1,4:5}\DoSomething \par
-%D \stopbuffer
-%D
-%D \typebuffer \blank \getbuffer \blank
-
-\def\syst_helpers_with_range#1%
- {\splitstring#1\at:\to\m_syst_helpers_range_from\and\m_syst_helpers_range_to
- \ifempty\m_syst_helpers_range_to\let\m_syst_helpers_range_to\m_syst_helpers_range_from\fi
- \dostepwiserecurse\m_syst_helpers_range_from\m_syst_helpers_range_to\plusone{\m_helpers_range_action{##1}}}%
-
-\permanent\protected\def\processranges[#1]#2% #1= n:m,p,q:r
- {\def\m_helpers_range_action{#2}%
- \processcommacommand[#1]\syst_helpers_with_range}
-
-\permanent\protected\def\dowithrange#1#2%
- {\def\m_helpers_range_action{#2}%
- \processcommacommand[#1]\syst_helpers_with_range}
-
-% \def\DoSomething#1{ [item #1] }
-% \dowithrange[1,4:5]\DoSomething
-
-%D \macros
-%D {ignoreimplicitspaces}
-%D
-%D \startbuffer
-%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignorespaces}
-%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b}
-%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignoreimplicitspaces}
-%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b}
-%D \stopbuffer
-%D
-%D \typebuffer \getbuffer
-
-\permanent\protected\def\ignoreimplicitspaces
- {\doifelsenextchar\relax\relax\relax}
-
-%D \macros
-%D {processwords}
-%D
-%D Not that sophisticated but sometimes users (like in metafun).
-
-%D This will be overloaded.
-
-\def\syst_helpers_process_word#1 #2\_e_o_w_
- {\doifsomething{#1}{\processword{#1} \syst_helpers_process_word#2 \_e_o_w_}}
-
-\def\processwords#1%
- {\syst_helpers_process_word#1 \_e_o_w_}% no \unskip
-
-\let\processword\relax
-
-%D \macros
-%D {startnointerference}
-%D
-%D \starttyping
-%D \startnointerference
-%D all kind of code
-%D \stopnointerference
-%D \stoptyping
-
-\newbox\b_syst_helpers_no_interference
-
-\permanent\protected\def\startnointerference % not even grouped !
- {\setbox\b_syst_helpers_no_interference\vbox
- \bgroup}
-
-\permanent\protected\def\stopnointerference
- {\egroup
- \setbox\b_syst_helpers_no_interference\emptybox}
-
-%D A variant for \type {\executeifdefined}:
-
-\permanent\def\expandcheckedcsname#1#2% #2 is often a \xxxparameter so let's expand it once
- {\normalexpanded{\noexpand\syst_helpers_expand_checked_csname{#1}{#2}}}
-
-\def\syst_helpers_expand_checked_csname#1#2#3%
- {\csname#1\ifcsname#1#2\endcsname#2\else#3\fi\endcsname}
-
-%D Signal. Some fonts have a char0 rendering so we need to make sure that it is not
-%D set in the font! (This will be overloaded)
-
-\protected\def\signalcharacter{\char\zerocount} % \zwj
-
-%D A few secial variants of commands defined here. Some more will be moved here (e.g.
-%D from table modules.
-
-\permanent\def\dodirectdoubleempty#1#2% used in math (lookahead issues)
- {\ifx#2[%
- \expandafter\syst_helpers_direct_double_empty_one_yes
- \else
- \expandafter\syst_helpers_direct_double_empty_one_nop
- \fi#1#2}
-
-\def\syst_helpers_direct_double_empty_one_yes#1[#2]#3%
- {\ifx#3[\else\expandafter\syst_helpers_direct_double_empty_two_nop\fi#1[#2]#3}
-
-\def\syst_helpers_direct_double_empty_one_nop#1{#1[][]}
-\def\syst_helpers_direct_double_empty_two_nop#1[#2]{#1[#2][]}
-
-%D Used in math definitions (in an \type {\edef}):
-
-%D \startbuffer
-%D [\docheckedpair{}]
-%D [\docheckedpair{a}]
-%D [\docheckedpair{a,b}]
-%D [\docheckedpair{a,b,c}]
-%D \stopbuffer
-%D
-%D \typebuffer \startlines \getbuffer \stoplines
-
-\permanent\def\docheckedpair#1%
- {\syst_helpers_checked_pair#1,,\_o_e_p_}
-
-% \def\syst_helpers_checked_pair#1,#2,#0\_o_e_p_
-% {#1,#2}
-
-\def\syst_helpers_checked_pair#1,#2,#-\_o_e_p_
- {#1,#2}
-
-%D Here are some nasty helpers. They can be used to fill often expanded token
-%D lists efficiently (see tabulate for an example).
-
-\permanent\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}
-
-\permanent\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}
-
-\permanent\def\constantdimen#1%
- {\ifdim#1=\zeropoint
- \zeropoint
- \else
- \the#1\relax
- \fi}
-
-\permanent\def\constantdimenargument#1%
- {\ifdim#1=\zeropoint
- \zeropoint
- \else
- {\the#1}%
- \fi}
-
-\permanent\def\constantemptyargument#1%
- {\ifempty#1%
- \noexpand\empty
- \else
- {#1}%
- \fi}
-
-%D \macros
-%D {getsubstring}
-%D \startbuffer
-%D
-%D \getsubstring{4}{}{Who Wants This}
-%D \getsubstring{4}{9}{Who Wants This}
-%D \getsubstring{9}{-2}{Who Wants This}
-%D \getsubstring{1}{5}{Who Wants This}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlines
-%D \getbuffer
-%D \stoplines
-
-% expandable:
-
-\permanent\def\getsubstring#1#2#3{\clf_getsubstring{#3}{#1}{#2}}
-
-%D Other dimensions than pt (used in mb-mp)
-
-\permanent\def\converteddimen#1#2{\clf_converteddimen\dimexpr#1\relax{#2}}
-
-%D Maybe (looks ugly):
-%D
-%D \starttyping
-%D \doifcase {foo}
-%D {bar} {BAR}
-%D {foo} {FOO}
-%D {default} {DEFAULT}
-%D
-%D \doifcase {foo}
-%D {bar} {BAR}
-%D {foo} {\doifcase {bar}
-%D {bar} {BAR}
-%D {foo} {FOO}
-%D {default} {DEFAULT}
-%D }
-%D {default} {DEFAULT}
-%D \stoptyping
-
-% \doifcase {\btxfoundname{author}}
-% {author} {\btxflush{author}}
-% {editor} {\texdefinition{btx:apa:editor-or-editors}}
-% {title} {\texdefinition{btx:apa:title-subtitle-type}}
-% {default} {\btxflush{author}}
-
-% \protected\def\doifcase#1%
-% {\edef\m_case_asked{#1}%
-% \syst_aux_case}
-%
-% \def\syst_aux_case#1%
-% {\edef\m_case_temp{#1}%
-% \ifx\m_case_temp\m_case_asked
-% \expandafter\syst_aux_case_yes
-% \orelse\ifx\m_case_temp\s!default
-% \expandafter\firstofoneargument
-% \else
-% \expandafter\syst_aux_case_nop
-% \fi}
-%
-% \def\syst_aux_skip#1#2%
-% {\edef\m_case_temp{#1}%
-% \ifx\m_case_temp\s!default
-% \expandafter\syst_aux_done
-% \else
-% \expandafter\syst_aux_skip
-% \fi}
-%
-% \def\syst_aux_case_yes#1%
-% {\def\syst_aux_done{#1}%
-% \syst_aux_skip}
-%
-% \def\syst_aux_case_nop#1%
-% {\syst_aux_case}
-
-%D \macros
-%D {ntimes}
-%D
-%D some repetition:
-%D
-%D \startbuffer
-%D \ntimes{*}{20}
-%D \stopbuffer
-%D
-%D \typebuffer \blank gives: \getbuffer \blank
-%D
-%D This is not real fast but quite okay:
-
-%def\ntimes#1#2{\ifnum#2>\zerocount#1\ntimes{#1}{\numexpr#2-\plusone\relax}\fi} % 1.72
-\permanent\def\ntimes#1#2{\clf_ntimes{#1}\numexpr#2\relax} % 0.33
-
-%D Experiment (sometimes looks nicer in code):
-
-\permanent\protected\def\sameargumentscondition#1#2%
- {\edef\m_syst_string_one{#1}%
- \edef\m_syst_string_two{#2}%
- \ifx\m_syst_string_one\m_syst_string_two}
-
-\permanent\protected\def\emptyargumentcondition#1%
- {\edef\m_syst_string_one{#1}%
- \ifempty\m_syst_string_one}
-
-%D New (also serves as an example):
-%D
-%D \starttyping
-%D \commandflags\defineframed
-%D \stoptyping
-
-\permanent\def\commandflags#1%
- {\beginlocalcontrol\begingroup\scratchtoks\emptytoks\donefalse
- \ifflags#1= \frozenflagcode\etoksapp\scratchtoks{\ifdone \space\fi frozen}\donetrue\fi
- \ifflags#1=\permanentflagcode\etoksapp\scratchtoks{\ifdone \space\fi permanent}\donetrue\fi
- \ifflags#1=\immutableflagcode\etoksapp\scratchtoks{\ifdone \space\fi immutable}\donetrue\fi
- \ifflags#1=\primitiveflagcode\etoksapp\scratchtoks{\ifdone \space\fi primitive}\donetrue\fi
- \ifflags#1= \mutableflagcode\etoksapp\scratchtoks{\ifdone \space\fi mutable}\donetrue\fi
- \ifflags#1=\noalignedflagcode\etoksapp\scratchtoks{\ifdone \space\fi noaligned}\donetrue\fi
- \ifflags#1= \instanceflagcode\etoksapp\scratchtoks{\ifdone \space\fi instance}\donetrue\fi
- %\ifflags#1= \reservedflagcode\etoksapp\scratchtoks{\ifdone \space\fi reserved}\donetrue\fi
- \ifflags#1= \tolerantflagcode\etoksapp\scratchtoks{\ifdone \space\fi tolerant}\donetrue\fi
- \ifflags#1=\protectedflagcode\etoksapp\scratchtoks{\ifdone \space\fi protected}\donetrue\fi
- \expandafter\endgroup\expandafter\endlocalcontrol\the\scratchtoks}
-
-%D \macros
-%D {resetmacros}
-%D
-%D The next macro can be used to reset a macro:
-%D
-%D \starttyping
-%D \resetmacros[startfoo,\stopfoo]
-%D \stoptyping
-
-\permanent\protected\def\syst_reset_macro#1%
- {\overloaded\letcsname\csstring#1\endcsname\undefined} % so only frozen (instances(
-
-\permanent\protected\def\resetmacros[#1]%
- {\processcommalist[#1]\syst_reset_macro}
-
-\protect \endinput