summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mult-ini.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mult-ini.tex')
-rw-r--r--Master/texmf-dist/tex/context/base/mult-ini.tex1556
1 files changed, 1556 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mult-ini.tex b/Master/texmf-dist/tex/context/base/mult-ini.tex
new file mode 100644
index 00000000000..abc01562a56
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mult-ini.tex
@@ -0,0 +1,1556 @@
+%D \module
+%D [ file=mult-ini,
+%D version=1996.06.01,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 This module implements the multi||lingual interface to
+%D \CONTEXT. These capabilities concern messages, commands and
+%D parameters. Currently the following interfaces are
+%D supported:
+%D
+%D \starttabulate[|l|l|c|c|]
+%D \NC\bf language\NC\bf translator \NC\bf messages\NC\bf interface\NC\NR
+%D \NC dutch \NC Hans Hagen \NC yes \NC yes \NC\NR
+%D \NC english \NC Hans Hagen \NC yes \NC yes \NC\NR
+%D \NC german \NC Tobias Burnus \NC yes \NC yes \NC\NR
+%D \NC czech \NC Tom Hudec \NC yes \NC yes \NC\NR
+%D \NC italian \NC Giuseppe Bilotta \NC yes \NC yes \NC\NR
+%D \NC norwegian \NC Hans Fredrik Nordhaug\NC yes \NC no \NC\NR
+%D \stoptabulate
+
+\writestatus{loading}{Context Multilingual Macros / Initialization}
+
+\unprotect
+
+%D \macros
+%D [constanten,variabelen,commands]
+%D {v!,c!,k!,s!,e!,m!,l!,r!,f!,p!,x!,y!}
+%D
+%D In the system modules we introduced some prefixed constants,
+%D variables (both macros) and registers. Apart from a
+%D tremendous saving in terms of memory and a gain in speed we
+%D use from now on prefixes when possible for just another
+%D reason: consistency and multi||linguality. Systematically
+%D using prefixed macros enables us to implement a
+%D multi||lingual user interface. Redefining these next set of
+%D prefixes therefore can have desastrous results.
+%D
+%D \startlinecorrection
+%D \starttable[|c|c|c|]
+%D \HL
+%D \NC \bf prefix \NC \bf meaning \NC \bf application \NC\SR
+%D \HL
+%D \NC \type{\c!prefix!} \NC c! \NC constant (direct) \NC\FR
+%D \NC \type{\e!prefix!} \NC e! \NC element \NC\MR
+%D \NC \type{\f!prefix!} \NC f! \NC file \NC\MR
+%D \NC \type{\k!prefix!} \NC k! \NC constant (indirect) \NC\MR
+%D \NC \type{\l!prefix!} \NC l! \NC language \NC\MR
+%D \NC \type{\m!prefix!} \NC m! \NC message \NC\MR
+%D \NC \type{\p!prefix!} \NC p! \NC procedure \NC\MR
+%D \NC \type{\r!prefix!} \NC r! \NC reference \NC\MR
+%D \NC \type{\s!prefix!} \NC s! \NC system \NC\MR
+%D \NC \type{\v!prefix!} \NC v! \NC variable \NC\MR
+%D \NC \type{\x!prefix!} \NC x! \NC setup constant \NC\MR
+%D \NC \type{\y!prefix!} \NC y! \NC setup variable \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D In the single||lingual version we used \type{!}, \type{!!},
+%D \type{!!!} and \type{!!!!}.
+
+\def\c!prefix!{c!} \def\e!prefix!{e!} \def\f!prefix!{f!}
+\def\k!prefix!{k!} \def\l!prefix!{l!} \def\m!prefix!{m!}
+\def\p!prefix!{p!} \def\r!prefix!{r!} \def\s!prefix!{s!}
+\def\v!prefix!{v!} \def\x!prefix!{x!} \def\y!prefix!{y!}
+\def\t!prefix!{t!}
+
+%D \macros
+%D [constants,variables,commands]
+%D {@@,??}
+%D
+%D Variables generated by the system can be recognized on their
+%D prefix \type{@@}. They are composed of a command (class)
+%D specific tag, which can be recognized on \type{??}, and a
+%D system constant, which has the prefix \type{c!}. We'll se
+%D some more of this.
+
+\def\??prefix {??}
+\def\@@prefix {@@}
+
+%D Just to be complete we repeat some of the already defined
+%D system constants here. Maybe their prefix \type{\s!} now
+%D falls into place.
+
+\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!start {start}
+\def\s!simple {simple} \def\s!stop {stop}
+
+\def\!!width {width} \def\!!plus {plus}
+\def\!!height {height} \def\!!minus {minus}
+\def\!!depth {depth} \def\!!to {to}
+
+%D \macros
+%D {defineinterfaceconstant,
+%D defineinterfacevariable,
+%D defineinterfaceelement,
+%D definesystemvariable,
+%D definesystemconstant,
+%D definemessageconstant,
+%D definereferenceconstant,
+%D definefileconstant}
+%D
+%D The first part of this module is dedicated to dealing with
+%D multi||lingual constants and variables. When \CONTEXT\ grew
+%D bigger and bigger in terms of bytes and used string space,
+%D we switched to predefined constants. At the cost of more
+%D hash table entries, the macros not only becase more compact,
+%D they became much faster too. Maybe an even bigger advantage
+%D was that mispelling could no longer lead to problems. Even a
+%D multi||lingual interface became possible.
+%D
+%D Constants --- we'll introduce the concept of variables later
+%D on --- are preceded by a type specific prefix, followed by a
+%D \type{!}. To force consistency, we provide a few commands
+%D for defining such constants.
+%D
+%D \starttyping
+%D \defineinterfaceconstant {name} {meaning}
+%D \defineinterfacevariable {name} {meaning}
+%D \defineinterfaceelement {name} {meaning}
+%D \stoptyping
+%D
+%D Which is the same as:
+%D
+%D \starttyping
+%D \def\c!name{meaning}
+%D \def\v!name{meaning}
+%D \def\e!name{meaning}
+%D \stoptyping
+
+\def\defineinterfaceconstant #1#2{\setvalue{\c!prefix!#1}{#2}}
+\def\defineinterfacevariable #1#2{\setvalue{\v!prefix!#1}{#2}}
+\def\defineinterfaceelement #1#2{\setvalue{\e!prefix!#1}{#2}}
+
+%D Next come some interface independant constants:
+%D
+%D \starttyping
+%D \definereferenceconstant {name} {meaning}
+%D \definefileconstant {name} {meaning}
+%D \stoptyping
+
+\def\definereferenceconstant #1#2{\setvalue{\r!prefix!#1}{#2}}
+\def\definefileconstant #1#2{\setvalue{\f!prefix!#1}{#2}}
+
+%D A new one:
+
+\def\definetypescriptconstant#1#2{\setvalue{\t!prefix!#1}{#2}}
+
+%D And finaly we have the one argument, space saving constants
+%D
+%D \starttyping
+%D \definesystemconstant {name}
+%D \definemessageconstant {name}
+%D \stoptyping
+
+\def\definesystemconstant #1{\setvalue{\s!prefix!#1}{#1}}
+\def\definemessageconstant #1{\setvalue{\m!prefix!#1}{#1}}
+
+%D In a parameter driven system, some parameters are shared
+%D by more system components. In \CONTEXT\ we can distinguish
+%D parameters by a unique prefix. Such a prefix is defined
+%D with:
+%D
+%D \starttyping
+%D \definesystemvariable {name}
+%D \stoptyping
+
+\def\definesystemvariable#1{\setevalue{\??prefix#1}{\@@prefix#1}}
+
+\definesystemvariable{ms}
+
+%D \macros
+%D {selectinterface,
+%D defaultinterface, currentinterface, currentresponses}
+%D
+%D With \type{\selectinterface} we specify the language we are
+%D going to use. The system asks for the language wanted, and
+%D defaults to \type{\currentinterface} when we just give
+%D \type{enter}. By default the message system uses the
+%D current interface language, but \type{\currentresponses}
+%D can specify another language too.
+%D
+%D Because we want to generate formats directly too, we do
+%D not ask for interface specifications when these are already
+%D defined (like in cont-nl.tex and alike).
+
+\ifx\undefined\scratchwrite \newwrite\scratchwrite \fi
+\ifx\undefined\scratchread \newwrite\scratchread \fi
+
+\immediate\openin\scratchread=mult-def.tex % may overload the defaults
+
+\ifeof\scratchread % no high level commands yet
+ \immediate\closein\scratchread
+\else
+ \immediate\closein\scratchread \input mult-def.tex
+\fi
+
+\ifx\defaultinterface\undefined
+
+ \def\defaultinterface{english}
+
+ \def\selectinterface
+ {\def\docommando##1##2%
+ {\bgroup
+ \endlinechar\minusone
+ \global\read16 to ##1
+ \egroup
+ \doifnothing\currentinterface{\let##1=##2}%
+ \doifundefined{\s!prefix!##1}{\let##1=##2}}%
+ \docommando\currentinterface\defaultinterface
+ \writestatus{interface}{defining \currentinterface\space interface}%
+ \writeline
+ \docommando\currentresponses\currentinterface
+ \writestatus{interface}{using \currentresponses\space messages}%
+ \writeline
+ \let\selectinterface\relax}
+
+\else
+
+ \def\selectinterface
+ {\writestatus{interface}{defining \currentinterface\space interface}%
+ \writeline
+ \writestatus{interface}{using \currentresponses\space messages}%
+ \writeline
+ \let\selectinterface\relax}
+
+\fi
+
+\ifx\currentinterface\undefined \let\currentinterface=\defaultinterface \fi
+\ifx\currentresponses\undefined \let\currentresponses=\defaultinterface \fi
+
+%D \macros
+%D {startinterface}
+%D
+%D Sometimes we want to define things only for specific
+%D interface languages. This can be done by means of the
+%D selector:
+%D
+%D \starttyping
+%D \startinterface language
+%D
+%D language specific definitions & commands
+%D
+%D \stopinterface
+%D \stoptyping
+
+%\def\startinterface #1
+% {\doifinsetelse{\currentinterface}{#1}
+% {\let\next\relax}
+% {\long\def\next##1\stopinterface{}}%
+% \next}
+
+\def\startinterface #1
+ {\doifnotinset\currentinterface{#1}{\gobbleuntil\stopinterface}}
+
+\let\stopinterface=\relax
+
+%D \macros
+%D {startmessages,
+%D getmessage,
+%D showmessage,
+%D makemessage}
+%D
+%D A package as large as \CONTEXT\ can hardly function without
+%D a decent message mechanism. Due to its multi||lingual
+%D interface, the message subsystem has to be multi||lingual
+%D too. A major drawback of this feature is that we have to
+%D code messages. As a result, the source becomes less self
+%D documented. On the other hand, consistency will improve.
+%D
+%D Because the overhead in terms of entries in the (already
+%D exhausted) hash table has to be minimal, messages are packed
+%D in libraries. We can extract a message from such a library
+%D in three ways:
+%D
+%D \starttyping
+%D \getmessage {library} {tag}
+%D \showmessage {library} {tag} {data}
+%D \makemessage {library} {tag} {data}
+%D \stoptyping
+%D
+%D The first command gets the message \type{tag} from the
+%D \type{library} specified. The other commands take an extra
+%D argument: a list of items to be inserted in the message
+%D text. While \type{\showmessage} shows the message at the
+%D terminal, the other commands generate the message as text.
+%D Before we explain the \type{data} argument, we give an
+%D example of a library.
+%D
+%D \starttyping
+%D \startmessages english library: alfa
+%D title: something
+%D 1: first message
+%D 2: second (--) message --
+%D \stopmessages
+%D \stoptyping
+%D
+%D The first message is a simple one and can be shown with:
+%D
+%D \starttyping
+%D \showmessage {alfa} {1} {}
+%D \stoptyping
+%D
+%D The second message on the other hand needs some extra data:
+%D
+%D \starttyping
+%D \showmessage {alfa} {2} {and last,to you}
+%D \stoptyping
+%D
+%D This message is shown as:
+%D
+%D \starttyping
+%D something : second (and last) message to you
+%D \stoptyping
+%D
+%D As we can see, the title entry is shown with the message.
+%D The data fields are comma separated and are specified in the
+%D message text by \type{--}.
+%D
+%D It is not required to define all messages in a library at
+%D once. We can add messages to a library in the following way:
+%D
+%D \starttyping
+%D \startmessages english library: alfa
+%D 10: tenth message
+%D \stopmessages
+%D \stoptyping
+%D
+%D Because such definitions can take place in different
+%D modules, the system gives a warning when a tag occurs more
+%D than once. The first occurrence takes preference over later
+%D ones, so we had better use a save offset, as shown in the
+%D example. As we can see, the title field is specified only
+%D the first time!
+%D
+%D Because we want to check for duplicate tags, the macros
+%D are a bit more complicated than neccessary. The \NEWLINE\
+%D token is used as message separator.
+%D
+%D For internal purposes one can use \type {\dogetmessage},
+%D which puts the message text asked for in \type
+%D {\currentmessagetext}.
+
+\def\findinterfacemessage#1#2%
+ {\let#2\empty
+ \def\dofindinterfacemessage##1 #1: ##2\relax##3\end{\def#2{##2}}%
+ \edef\!!stringa{\getvalue{\??ms\currentmessagelibrary} #1: \relax}%
+ \expandafter\dofindinterfacemessage\!!stringa\end}
+
+\def\composemessagetext#1--#2--#3--#4--#5--#6--#7--#8--#9\\%
+ {\def\docomposemessagetext##1,##2,##3,##4,##5,##6,##7,##8,##9\\%
+ {\edef\currentmessagetext{#1##1#2##2#3##3#4##4#5##5#6##6#7##7#8##8}}%
+ \docomposemessagetext}
+
+\def\dogetmessage#1#2%
+ {\def\currentmessagelibrary{#1}%
+ \findinterfacemessage{#2}\currentmessagetext}
+
+\unexpanded\def\getmessage#1#2%
+ {\def\currentmessagelibrary{#1}%
+ \findinterfacemessage{#2}\currentmessagetext
+ \currentmessagetext}
+
+\unexpanded\def\makemessage#1#2#3%
+ {\def\currentmessagelibrary{#1}%
+ \findinterfacemessage{#2}\currentmessagetext
+ \@EA\composemessagetext\currentmessagetext----------------\\#3,,,,,,,,\\%
+ \currentmessagetext}
+
+\def\showmessage#1#2#3%
+ {\def\currentmessagelibrary{#1}%
+ \findinterfacemessage{#2}\currentmessagetext
+ \findinterfacemessage{title}\currentmessagetitle
+ \ifx\currentmessagetext\empty
+ \def\currentmessagetext{<unknown message #2>}%
+ \else
+ \@EA\composemessagetext\currentmessagetext----------------\\#3,,,,,,,,\\%
+ \fi
+ \@EA\writestatus\@EA{\currentmessagetitle}{\currentmessagetext}}
+
+\def\doaddinterfacemessage#1#2%
+ {\findinterfacemessage{#1}\currentmessagetext
+ \doifelsenothing\currentmessagetext
+ {\setxvalue{\??ms\currentmessagelibrary}%
+ {\getvalue{\??ms\currentmessagelibrary} #1: #2\relax}}
+ {\debuggerinfotrue % we consider this an important error
+ \debuggerinfo
+ {message}
+ {duplicate tag #1
+ in library \currentmessagelibrary\space
+ of interface \currentresponses}}%
+ \futurelet\next\getinterfacemessage}
+
+\bgroup
+\obeylines
+\gdef\addinterfacemessage#1: #2
+ {\doaddinterfacemessage{#1}{#2}}%
+\egroup
+
+\def\getinterfacemessage
+ {\ifx\next\stopmessages
+ \egroup\expandafter\gobbleoneargument
+ \else
+ \expandafter\addinterfacemessage
+ \fi}
+
+\def\startmessages #1 library: #2
+ {\definemessageconstant{#2}% handy for modules
+ \bgroup
+ \obeylines
+ \doifinsetelse{#1}{\currentresponses,all}
+ {\def\next
+ {\def\currentmessagelibrary{#2}%
+ \doifundefined{\??ms\currentmessagelibrary}
+ {\letgvalueempty{\??ms\currentmessagelibrary}}%
+ \futurelet\next\getinterfacemessage}}
+ {\long\def\next##1\stopmessages{\egroup}}%
+ \next}
+
+%D Here, the messages are stored in a way that saves hash
+%D entries, i.e. they are packed in one macro per library.
+%D This was important in the days when we used \TEX's with
+%D hash tables of about 10.000. The next, less efficient way
+%D of storing the message, makes \CONTEXT\ run upto 5\%
+%D faster by storing each message in a macro. In July 2000,
+%D this costs some 185 additional hash entries, and since
+%D we run large \TEX's, let do it!
+
+\def\startmessages #1 library: #2
+ {\definemessageconstant{#2}% handy for modules
+ \bgroup
+ \obeylines
+ \doifinsetelse{#1}{\currentresponses,all}
+ {\def\next
+ {\def\currentmessagelibrary{#2}%
+ \futurelet\next\getinterfacemessage}}
+ {\long\def\next##1\stopmessages{\egroup}}%
+ \next}
+
+\def\findinterfacemessage#1#2%
+ {\edef#2{\getvalue{\??ms\currentmessagelibrary#1}}}
+
+\def\doaddinterfacemessage#1#2%
+ {\doifdefined{\??ms\currentmessagelibrary#1}
+ {\debuggerinfotrue % we consider this an important error
+ \debuggerinfo
+ {message}
+ {duplicate tag #1
+ in library \currentmessagelibrary\space
+ of interface \currentresponses}}%
+ \setxvalue{\??ms\currentmessagelibrary#1}{#2}%
+ \futurelet\next\getinterfacemessage}
+
+%D \macros
+%D {ifshowwarnings, ifshowmessages}
+%D
+%D Sometimes displaying message can slow down processing
+%D considerably. We therefore introduce warnings. Users can
+%D turn of warnings and messages by saying:
+%D
+%D \starttyping
+%D \showwarningstrue
+%D \showmessagestrue
+%D \stoptyping
+%D
+%D Turning off messages also turns off warnings, which is
+%D quote logical because they are less important.
+
+\newif\ifshowwarnings \showwarningstrue
+\newif\ifshowmessages \showmessagestrue
+
+\let\normalshowmessage=\showmessage
+
+\def\showwarning
+ {\ifshowwarnings
+ \expandafter\showmessage
+ \else
+ \expandafter\gobblethreearguments
+ \fi}
+
+\def\showmessage
+ {\ifshowmessages
+ \expandafter\normalshowmessage
+ \else
+ \expandafter\gobblethreearguments
+ \fi}
+
+%D \macros
+%D {dosetvalue,dosetevalue,dosetgvalue,dosetxvalue,docopyvalue,doresetvalue} % dogetvalue
+%D
+%D We already defined these auxiliary macros in the system
+%D modules. Starting with this module however, we have to take
+%D multi||linguality a bit more serious.
+%D
+%D First we show a well||defined (simplified) alternative:
+%D
+%D \starttyping
+%D \def\dosetvalue#1#2#3%
+%D {\doifdefinedelse{\c!prefix!#2}
+%D {\setvalue{#1\getvalue{\c!prefix!#2}}{#3}}
+%D {\setvalue{#1#2}{#3}}}
+%D
+%D \def\docopyvalue#1#2#3%
+%D {\doifdefinedelse{\c!prefix!#3}
+%D {\setvalue{#1\getvalue{\c!prefix!#3}}%
+%D {\getvalue{#2\getvalue{\c!prefix!#3}}}}
+%D {\setvalue{#1#3}%
+%D {\getvalue{#2#3}}}}
+%D \stoptyping
+%D
+%D These macros are called upon quite often and so we optimized
+%D them a bit.
+%D
+%D \starttyping
+%D \def\dosetvalue#1#2#3%
+%D {\let\c!internal!\c!internal!n
+%D \p!doifundefined{\k!prefix!#2}%
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest
+%D \@EA\def\csname#1#2\endcsname{#3}%
+%D \else
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest
+%D \@EA\def\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+%D \fi}
+%D
+%D \def\dosetevalue#1#2#3%
+%D {\let\c!internal!\c!internal!n
+%D \p!doifundefined{\k!prefix!#2}%
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest
+%D \@EA\edef\csname#1#2\endcsname{#3}%
+%D \else
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest
+%D \@EA\edef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+%D \fi}
+%D
+%D \def\dosetgvalue#1#2#3%
+%D {\let\c!internal!\c!internal!n
+%D \p!doifundefined{\k!prefix!#2}%
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest
+%D \@EA\gdef\csname#1#2\endcsname{#3}%
+%D \else
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest
+%D \@EA\gdef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+%D \fi}
+%D
+%D \def\docopyvalue#1#2#3%
+%D {\let\c!internal!\c!internal!n
+%D \p!doifundefined{\k!prefix!#3}%
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest % still needed ?
+%D \@EA\def\csname#1#3\endcsname%
+%D {\csname#2#3\endcsname}%
+%D \else
+%D \let\c!internal!\c!internal!y
+%D \let\donottest\doprocesstest % still needed ?
+%D \@EA\def\csname#1\csname\k!prefix!#3\endcsname\endcsname%
+%D {\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
+%D \fi}
+%D \stoptyping
+
+\def\doresetvalue#1#2%
+ {\dosetvalue{#1}{#2}{}}
+
+\def\doignorevalue#1#2#3%
+ {\dosetvalue{#1}{#2}{}}
+
+% \def\dogetvalue#1#2%
+% {\csname#1\csname\k!prefix!#2\endcsname\endcsname}
+
+%D Although maybe not clearly visible, there is a
+%D considerable profit in further optimization. By expanding
+%D the embedded \type {\csname} we can reduce the format file
+%D by about 5\% (60~KB out of 1.9~MB).
+%D
+%D \starttyping
+%D \def\docopyvalue#1#2#3% c -> k
+%D {\p!doifundefined{\k!prefix!#3}%
+%D \let\donottest\doprocesstest
+%D \@EAEAEA\def\@EA
+%D \csname\@EA#1\@EA#3\@EA
+%D \endcsname\@EA{\csname#2#3\endcsname}%
+%D \else
+%D \let\donottest\doprocesstest
+%D \@EAEAEA\def\@EA
+%D \csname\@EA#1\@EA\csname\@EA\k!prefix!\@EA#3\@EA\endcsname\@EA
+%D \endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
+%D \fi}
+%D \stoptyping
+%D
+%D The next alternatives are slightly faster.
+
+\beginTEX
+
+% \def\dosetvalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+% \let\c!internal!\c!internal!y
+% \@EA\def\csname#1#2\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\def\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \fi}
+%
+% \def\dosetevalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+% \let\c!internal!\c!internal!y
+% \@EA\edef\csname#1#2\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\edef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \fi}
+%
+% \def\dosetgvalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+% \let\c!internal!\c!internal!y
+% \@EA\gdef\csname#1#2\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\gdef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \fi}
+%
+% cleaner (not that much faster) don't pass #3 yet:
+
+\def\dosetvalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\def\@EA\@EA\csname#1#2\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\def\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+ \fi}
+
+\def\dosetevalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\edef\@EA\@EA\csname#1#2\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\edef\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+ \fi}
+
+\def\dosetgvalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\gdef\@EA\@EA\csname#1#2\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\gdef\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+ \fi}
+
+\def\dosetxvalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \@EA\ifx\csname\k!prefix!#2\endcsname\relax
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\xdef\@EA\@EA\csname#1#2\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\xdef\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+ \fi}
+
+% so far
+
+\def\docopyvalue#1#2#3%
+ {\let\c!internal!\c!internal!n
+ \@EA\ifx\csname\k!prefix!#3\endcsname\relax
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\def\@EA
+ \csname\@EA#1\@EA#3\@EA
+ \endcsname\@EA{\csname#2#3\endcsname}%
+ \else
+ \let\c!internal!\c!internal!y
+ \@EAEAEA\def\@EA
+ \csname\@EA#1\@EA\csname\@EA\k!prefix!\@EA#3\@EA\endcsname\@EA
+ \endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
+ \fi}
+
+\endTEX
+
+\beginETEX \protected
+
+% \def\dosetvalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EA\def\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\def\csname#1#2\endcsname{#3}%
+% \fi}
+%
+% \def\dosetevalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EA\edef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\edef\csname#1#2\endcsname{#3}%
+% \fi}
+%
+% \def\dosetgvalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EA\gdef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\gdef\csname#1#2\endcsname{#3}%
+% \fi}
+%
+% \def\dosetxvalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EA\xdef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EA\xdef\csname#1#2\endcsname{#3}%
+% \fi}
+%
+% cleaner (not that much faster) don't pass #3 yet:
+%
+% \def\dosetvalue#1#2%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\def\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+% \else
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\def\@EA\@EA\csname#1#2\endcsname
+% \fi}
+%
+% \def\dosetevalue#1#2%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\edef\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+% \else
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\edef\@EA\@EA\csname#1#2\endcsname
+% \fi}
+%
+% \def\dosetgvalue#1#2%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\gdef\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+% \else
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\gdef\@EA\@EA\csname#1#2\endcsname
+% \fi}
+%
+% \def\dosetxvalue#1#2%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#2\endcsname
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\xdef\@EA\@EA\csname#1\csname\k!prefix!#2\endcsname\endcsname
+% \else
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\xdef\@EA\@EA\csname#1#2\endcsname
+% \fi}
+%
+% \def\docopyvalue#1#2#3%
+% {\let\c!internal!\c!internal!n
+% \ifcsname\k!prefix!#3\endcsname
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\def\@EA
+% \csname\@EA#1\@EA\csname\@EA\k!prefix!\@EA#3\@EA\endcsname\@EA
+% \endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
+% \else
+% \let\c!internal!\c!internal!y
+% \@EAEAEA\def\@EA
+% \csname\@EA#1\@EA#3\@EA
+% \endcsname\@EA{\csname#2#3\endcsname}%
+% \fi}
+%
+% slightly more efficient (but not faster in day to day runs)
+
+\def\dosetvalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \ifcsname\k!prefix!#2\endcsname
+ \let\c!internal!\c!internal!y
+ \@EA\def\csname#1\csname\k!prefix!#2\endcsname%\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EA\def\csname#1#2%\endcsname
+ \fi\endcsname}
+
+\def\dosetevalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \ifcsname\k!prefix!#2\endcsname
+ \let\c!internal!\c!internal!y
+ \@EA\edef\csname#1\csname\k!prefix!#2\endcsname%\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EA\edef\csname#1#2%\endcsname
+ \fi\endcsname}
+
+\def\dosetgvalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \ifcsname\k!prefix!#2\endcsname
+ \let\c!internal!\c!internal!y
+ \@EA\gdef\csname#1\csname\k!prefix!#2\endcsname%\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EA\gdef\csname#1#2%\endcsname
+ \fi\endcsname}
+
+\def\dosetxvalue#1#2%
+ {\let\c!internal!\c!internal!n
+ \ifcsname\k!prefix!#2\endcsname
+ \let\c!internal!\c!internal!y
+ \@EA\xdef\csname#1\csname\k!prefix!#2\endcsname%\endcsname
+ \else
+ \let\c!internal!\c!internal!y
+ \@EA\xdef\csname#1#2%\endcsname
+ \fi\endcsname}
+
+\def\docopyvalue#1#2#3% real tricky expansion, quite unreadable
+ {\let\c!internal!\c!internal!n
+ \ifcsname\k!prefix!#3\endcsname
+ \let\c!internal!\c!internal!y
+ % \@EAEAEA\def\@EA\@EA
+ % \csname#1\csname\k!prefix!#3\endcsname
+ % \endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
+ \@EA\def\csname#1\csname\k!prefix!#3\endcsname
+ \@EA\endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
+ \else
+ \let\c!internal!\c!internal!y
+ %\@EAEAEA\def\@EA\@EA\csname#1#3\endcsname\@EA{\csname#2#3\endcsname}%
+ \@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}%
+ \fi}
+
+\endETEX
+
+%D We can now redefine some messages that will be
+%D introduced in the multi||lingual system module.
+
+\def\showassignerror #1#2{\showmessage\m!check1{#1,#2}\waitonfatalerror}
+\def\showargumenterror#1#2{\showmessage\m!check2{#1,#2}\waitonfatalerror}
+\def\showdefinederror #1#2{\showmessage\m!check3{#1,#2}\waitonfatalerror}
+
+%D \CONTEXT\ is a parameter driven package. This means that
+%D users instruct the system by means of variables, values and
+%D keywords. These instructions take the form:
+%D
+%D \starttyping
+%D \setupsomething[some variable=some value, another one=a keyword]
+%D \stoptyping
+%D
+%D or by keyword only:
+%D
+%D \starttyping
+%D \dosomething[this way,that way,no way]
+%D \stoptyping
+%D
+%D Because the same variables can occur in more than one setup
+%D command, we have to be able to distinguish them. This is
+%D achieved by assigning them a unique prefix.
+%D
+%D Imagine a setup command for boxed text, that enables us to
+%D specify the height and width of the box. Behide the scenes
+%D the command
+%D
+%D \starttyping
+%D \setupbox [width=12cm, height=3cm]
+%D \stoptyping
+%D
+%D results in something like
+%D
+%D \starttyping
+%D \<box><width> {12cm}
+%D \<box><height> {3cm}
+%D \stoptyping
+%D
+%D while a similar command for specifying the page dimensions
+%D of an \cap{A4} page results in:
+%D
+%D \starttyping
+%D \<page><width> {21.0cm}
+%D \<page><height> {27.9cm}
+%D \stoptyping
+%D
+%D The prefixes \type{<box>} and \type{<page>} are hidden from
+%D users and can therefore be language independant. Variables
+%D on the other hand, differ for each language:
+%D
+%D \starttyping
+%D \<box><color> {<blue>}
+%D \<box><kleur> {<blauw>}
+%D \<box><couleur> {<blue>}
+%D \stoptyping
+%D
+%D In this example we can see that the assigned values or
+%D keywords are language dependant too. This will be a
+%D complication when defining multi||lingual setup files.
+%D
+%D A third phenomena is that variables and values can have a
+%D similar meaning.
+%D
+%D \starttyping
+%D \<pagenumber><location> {<left>}
+%D \<skip><left> {12cm}
+%D \stoptyping
+%D
+%D A (minor) complication is that where in english we use
+%D \type{<left>}, in dutch we find both \type{<links>} and
+%D \type{<linker>}. This means that when we use some sort of
+%D translation table, we have to distinguish between the
+%D variables at the left side and the fixed values at the
+%D right.
+%D
+%D The same goes for commands that are composed of different
+%D user supplied and/or language specific elements. In english
+%D we can use:
+%D
+%D \starttyping
+%D \<empty><figure>
+%D \<empty><intermezzo>
+%D \stoptyping
+%D
+%D But in dutch we have the following:
+%D
+%D \starttyping
+%D \<lege><figuur>
+%D \<leeg><intermezzo>
+%D \stoptyping
+%D
+%D These subtle differences automatically lead to a solution
+%D where variables, values, elements and other components have
+%D a similar logical name (used in macro's) but a different
+%D meaning (supplied by the user).
+%D
+%D Our solution is one in which the whole system is programmed
+%D in terms of identifiers with language specific meanings. In
+%D such an implementation, each fixed variable is available as:
+%D
+%D \starttyping
+%D \<prefix><variable>
+%D \stoptyping
+%D
+%D This means that for instance:
+%D
+%D \starttyping
+%D \setupbox[width=12cm]
+%D \stoptyping
+%D
+%D expands to something like:
+%D
+%D \starttyping
+%D \def\boxwidth{12cm}
+%D \stoptyping
+%D
+%D because we don't want to recode the source, a setup command
+%D in another language has to expand to this variable, so:
+%D
+%D \starttyping
+%D \setupblock[width=12cm]
+%D \stoptyping
+%D
+%D has to result in the definition of \type{\boxwidth} too.
+%D This method enables us to build compact, fast and readable
+%D code.
+%D
+%D An alternative method, which we considered using, uses a
+%D more indirect way. In this case, both calls generate a
+%D different variable:
+%D
+%D \starttyping
+%D \def\boxwidth {12cm}
+%D \def\boxbreedte {12cm}
+%D \stoptyping
+%D
+%D And because we don't want to recode those megabytes of
+%D already developed code, this variable has to be called with
+%D something like:
+%D
+%D \starttyping
+%D \valueof\box\width
+%D \stoptyping
+%D
+%D where \type{\valueof} takes care of the translation of
+%D \type{width} or \type{breedte} to \type{width} and
+%D combining this with \type{box} to \type{\boxwidth}.
+%D
+%D One advantage of this other scheme is that, within certain
+%D limits, we can implement an interface that can be switched
+%D to another language at will, while the current approach
+%D fixes the interface at startup. There are, by the way,
+%D other reasons too for not choosing this scheme. Switching
+%D user generated commands is for instance impossible and a
+%D dual interface would therefore give a strange mix of
+%D languages.
+%D
+%D Now let's work out the first scheme. Although the left hand
+%D of the assignment is a variable from the users point of
+%D view, it is a constant in terms of the system. Both
+%D \type{width} and \type{breedte} expand to \type{width}
+%D because in the source we only encounter \type{width}. Such
+%D system constants are presented as
+%D
+%D \starttyping
+%D \c!width
+%D \stoptyping
+%D
+%D This constant is always equivalent to \type{width}. As we
+%D can see, we use \type{c!} to mark this one as constant. Its
+%D dutch counterpart is:
+%D
+%D \starttyping
+%D breedte
+%D \stoptyping
+%D
+%D When we interpret a setup command each variable is
+%D translated to it's \type{c!} counterpart. This means that
+%D \type{breedte} and \type{width} expand to \type{breedte}
+%D and \type{\c!width} which both expand to \type{width}. That
+%D way user variables become system constants.
+%D
+%D The interpretation is done by means of a general setup
+%D command \type{\getparameters} that we introduced in the
+%D system module. Let us define some simple setup command:
+%D
+%D \starttyping
+%D \def\setupbox[#1]%
+%D {\getparameters[\??bx][#1]}
+%D \stoptyping
+%D
+%D This command can be used as:
+%D
+%D \starttyping
+%D \setupbox [width=3cm, height=1cm]
+%D \stoptyping
+%D
+%D Afterwards we have two variables \type{\@@bxwidth} and
+%D \type{\@@bxheight} which have the values \type{3cm} and
+%D \type{1cm} assigned. These variables are a combinatiom of
+%D the setup prefix \type{\??bx}, which expands to \type{@@bx}
+%D and the translated user supplied variables \type{width} and
+%D \type{height} or \type{breedte} and \type{hoogte},
+%D depending on the actual language. In dutch we just say:
+%D
+%D \starttyping
+%D \setupblock [width=3cm, height=1cm]
+%D \stoptyping
+%D
+%D and get ourselves \type{\@@bxwidth} and \type{\@@bxheight}
+%D too. In the source of \CONTEXT, we can recognize constants
+%D and variables on their leading \type{c!}, \type{v!} etc.,
+%D prefixes on \type{??} and composed variables on \type{@@}.
+%D
+%D We already saw that user supplied keywords need some
+%D special treatment too. This time we don't translate the
+%D keyword, but instead use in the source a variable which
+%D meaning depends on the interface language.
+%D
+%D \starttyping
+%D \v!left
+%D \stoptyping
+%D
+%D Which can be used in macro's like:
+%D
+%D \starttyping
+%D \processaction
+%D [\@@bxlocation]
+%D [ \v!left=>\dosomethingontheleft,
+%D \v!middle=>\dosomthinginthemiddle,
+%D \v!right=>\dosomethingontheright]
+%D \stoptyping
+%D
+%D Because variables like \type{\@@bxlocation} can have a lot
+%D of meanings, including tricky expandable tokens, we cannot
+%D translate this meaning when we compare. This means that
+%D \type{\@@bxlocation} can be \type{left} of \type{links} of
+%D whatever meaning suits the language. But because
+%D \type{\v!left} also has a meaning that suits the language,
+%D we are able to compare.
+%D
+%D Although we know it sounds confusing we want to state two
+%D important characteristics of the interface as described:
+%D
+%D \startnarrower \em
+%D user variables become system constants
+%D \stopnarrower
+%D
+%D and
+%D
+%D \startnarrower \em
+%D user constants (keywords) become system variables
+%D \stopnarrower
+%D
+
+%D \macros
+%D {startconstants,startvariables}
+%D
+%D It's time to introduce the macro's that are responsible for
+%D this translations process, but first we show how constants
+%D and variables are defined. We only show two languages and
+%D a few words.
+%D
+%D \starttyping
+%D \startconstants english dutch
+%D
+%D width: width breedte
+%D height: height hoogte
+%D
+%D \stopconstants
+%D \stoptyping
+%D
+%D Keep in mind that what users see as variables, are constants
+%D for the system.
+%D
+%D \starttyping
+%D \startvariables english dutch
+%D
+%D location: left links
+%D text: text tekst
+%D
+%D \stopvariables
+%D \stoptyping
+%D
+%D The macro's responsible for interpreting these setups are
+%D shared. They take care of empty lines and permit a more or
+%D less free format. All setups accept the keyword \type{all}
+%D which equals every language.
+
+%D The next few macros come into action when we generate
+%D interface log files:
+
+\newif\iflogginginterface
+
+\def\flushinterfaceelementline
+ {\iflogginginterface
+ \immediate\write\scratchwrite{\interfaceelementline}%
+ \let\interfaceelementline\empty
+ \fi}
+
+\def\saveinterfaceelementline#1%
+ {\iflogginginterface
+ \edef\interfaceelementline{\interfaceelementline#1\space}%
+ \fi}
+
+\def\startlogginginterface #1 %
+ {\logginginterfacetrue
+ \let\interfaceelementline\empty
+ \immediate\openout\scratchwrite=./#1\relax}
+
+\def\stoplogginginterface
+ {\flushinterfaceelementline
+ \immediate\closeout\scratchwrite
+ \logginginterfacefalse}
+
+%D By default we don't log at all.
+
+\def\startlogginginterface #1 {}
+\def\stoplogginginterface {}
+
+%D These logging commands are used in the next macros.
+
+\def\nointerfaceobject{-}
+
+\def\startinterfaceobjects#1#2%
+ {\!!counta\plusone
+ \let\dogetinterfaceobject\dogetinterfacetemplate
+ \let\dowithinterfaceelement#1%
+ \def\dodogetinterfaceobjects
+ {\ifx\next#2%
+ \flushinterfaceelementline
+ \flushinterfaceelementline
+ \def\next####1{#2}% was: \let\next\gobbleoneargument
+ \else\ifx\next\par
+ \long\def\next####1{\dogetinterfaceobjects}%
+ \else\ifx\next\empty
+ \def\next####1{\dogetinterfaceobjects}%
+ \else
+ \def\next####1 {\dogetinterfaceobject[####1:\relax]\dogetinterfaceobjects}%
+ \fi\fi\fi
+ \next}%
+ \def\dogetinterfaceobjects{\futurelet\next\dodogetinterfaceobjects}%
+ \dogetinterfaceobjects}
+
+\def\dogetinterfacetemplate[#1:#2]%
+ {\saveinterfaceelementline{#1}%
+ \doifinsetelse{#1}{\currentinterface,all}
+ {\let\dogetinterfaceobject\doskipinterfaceobject}
+ {\advance\!!counta\plusone}}
+
+\def\doskipinterfaceobject[#1:#2#3]%
+ {\if#2:%
+ \let\dogetinterfaceobject\dogetinterfaceelement
+ \dogetinterfaceobject[#1:#2#3]%
+ \else
+ \saveinterfaceelementline{#1}%
+ \fi}
+
+\let\interfaceelementline\empty
+
+\def\dogetinterfaceelement[#1:#2#3]%
+ {\ifx#2:%
+ \!!countb\zerocount
+ \def\!!stringa{#1}%
+ \flushinterfaceelementline
+ \else
+ \advance\!!countb\plusone
+ \saveinterfaceelementline{#1}%
+ \ifnum\!!countb=\!!counta
+ \@EA\dowithinterfaceelement\@EA{\!!stringa}{#1}%
+ \let\dogetinterfaceobject\doskipinterfaceobject
+ \fi
+ \fi}
+
+%D The constants and variables are defined as described. When
+%D \type {\interfacetranslation} is \type{true}, we also
+%D generate a reverse translation. Because we don't want to put
+%D too big a burden on \TEX's hash table, this is no default
+%D behavior. Reverse translation is used in the commands that
+%D generate the quick reference cards. We are going to define
+%D the real \CONTEXT\ commands in an abstract way and generate
+%D those reference cards for each language without further
+%D interference.
+
+%D Anno 2003 I've forgotten why the \type {\c!internal} is
+%D still in there; it's probably a left over from an experiment.
+
+%D Once we're gone XML we can drop some of the extra mappings.
+
+\let\c!internal!y \string
+\def\c!internal!n {-}
+\let\c!internal! \c!internal!y
+
+\def\setinterfaceconstant#1#2%
+ {\setvalue{\c!prefix!#1}{\c!internal!#1}%
+ \doifelse{#2}\nointerfaceobject % ?
+ {\debuggerinfo{constant}{#1 defined as #1 by default}%
+ }% \setvalue{\k!prefix!#1}{#1}} % was #2 -> #1
+ {\debuggerinfo{constant}{#1 defined as #2}%
+ \ifinterfacetranslation
+ \setvalue{\x!prefix!#1}{#2}%
+ \fi
+ \checksetvalue{\k!prefix!#2}{#1}%
+ \setvalue{\k!prefix!#2}{#1}}}
+
+\def\setinterfacevariable#1#2%
+ {\doifelse{#2}\nointerfaceobject
+ {\debuggerinfo{variable}{#1 defined as #1 by default}%
+ \checksetvalue{\v!prefix!#1}{#1}%
+ \setvalue{\v!prefix!#1}{#1}}
+ {\debuggerinfo{variable}{#1 defined as #2}%
+ \checksetvalue{\v!prefix!#1}{#2}%
+ \setvalue{\v!prefix!#1}{#2}}}
+
+\def\checksetvalue#1#2%
+ {\doifdefined{#1}{\doifvaluesomething{#1}{\doifnotvalue{#1}{#2}
+ {\writestatus{problems}{set #1 to #2 overloads \getvalue{#1}}}}}}
+
+\def\startvariables{\startinterfaceobjects\setinterfacevariable\stopvariables}
+\def\startconstants{\startinterfaceobjects\setinterfaceconstant\stopconstants}
+
+\let\stopvariables\relax
+\let\stopconstants\relax
+
+%D \macros
+%D {defineinterfaceconstant}
+%D
+%D Next we redefine a previously defined macro to take care of
+%D interface translation too. It's a bit redundant, because
+%D in these situations we could use the c||version, but for
+%D documentation purposes the x||alternative comes in handy.
+
+\def\defineinterfaceconstant#1#2%
+ {\setvalue{\c!prefix!#1}{#2}%
+ \ifinterfacetranslation
+ \setvalue{\x!prefix!#1}{#2}%
+ \fi}
+
+%D \macros
+%D {startinterfacesetupconstant}
+%D
+%D The next command, \type{\startinterfacesetupconstant}, which
+%D behavior also depends on the boolean, is used for constants
+%D that are only needed in these quick reference macro's. The
+%D following, more efficient approach does not work here,
+%D because it sometimes generates spaces.
+%D
+%D \starttyping
+%D \def\setinterfacesetupconstant
+%D {\ifinterfacetranslation
+%D \expandafter\setinterfaceconstant
+%D \fi}
+%D \stoptyping
+%D
+%D We therefore use the more redundant but robust method:
+
+\def\setinterfacesetupvariable#1#2%
+ {\ifinterfacetranslation
+ \doifelse{#2}\nointerfaceobject
+ {\setvalue{\y!prefix!#1}{#1}}
+ {\setvalue{\y!prefix!#1}{#2}}%
+ \fi}
+
+\def\startsetupvariables{\startinterfaceobjects\setinterfacesetupvariable\stopsetupvariables}
+
+\let\stopsetupvariables\relax
+
+%D \macros
+%D {startelements}
+%D
+%D Due to the object oriented nature of \CONTEXT, we also need
+%D to define the elements that are used to build commands:
+%D
+%D \starttyping
+%D \startelements english dutch
+%D
+%D beginvan: begin beginvan
+%D eindvan: end eindvan
+%D start: start start
+%D stop: stop stop
+%D
+%D \stopelements
+%D \stoptyping
+%D
+%D Such elements sometimes are the same in diferent
+%D languages, but mostly they differ. Things can get even
+%D confusing when we look at for instance the setup commands.
+%D In english we say \type{\setup<something>}, but in dutch we
+%D have: \type{\stel<iets>in}. Such split elements are no
+%D problem, because we just define two elements. When no second
+%D part is needed, we use a \type{-}:
+%D
+%D \starttyping
+%D \startelements english dutch
+%D
+%D setupa: setup stel
+%D setupb: - in
+%D
+%D \stopelements
+%D \stoptyping
+%D
+%D Element translation is realized by means of:
+
+\def\setinterfaceelement#1#2%
+ {\doifelse{#2}\nointerfaceobject
+ {\debuggerinfo{element}{#1 defined as <empty>}%
+ \resetvalue{\e!prefix!#1}}
+ {\doifdefinedelse{\e!prefix!#1}
+ {\doifnotvalue{\e!prefix!#1}{#2}
+ {\debuggerinfo{element}{#1 redefined as #2}%
+ \setvalue{\e!prefix!#1}{#2}}}
+ {\debuggerinfo{element}{#1 defined as #2}%
+ \setvalue{\e!prefix!#1}{#2}}}}
+
+\def\startelements{\startinterfaceobjects\setinterfaceelement\stopelements}
+
+\let\stopelements\relax
+
+%D \macros
+%D {startcommands}
+%D
+%D The last setup has to do with the commands themselve.
+%D Commands are defined as:
+%D
+%D \starttyping
+%D \startcommands english dutch
+%D
+%D starttekst: starttext starttekst
+%D stoptekst: stoptext stoptekst
+%D omlijnd: framed omlijnd
+%D margewoord: marginword margewoord
+%D
+%D \stopcommands
+%D \stoptyping
+%D
+%D Here we also have to take care of the optional translation
+%D needed for reference cards.
+
+% \ifx\doifdefinedascommandelse\undefined
+% \let\doifdefinedascommandelse\thirdofthreearguments
+% \else
+% % this one will be defined in the encoding modules
+% \fi
+
+\def\setinterfacecommand#1#2%
+ {\doifelse{#2}\nointerfaceobject
+ {\debuggerinfo{command}{no link to #1}%
+ \setinterfacesetupvariable{#1}{#1}}
+ {\doifelse{#1}{#2}
+ {\debuggerinfo{command}{#1 remains #1}}
+ {\doifdefinedelse{#2}
+ {\debuggerinfo{command}{core command #2 redefined as #1}}%
+ {\debuggerinfo{command}{#2 defined as #1}}%
+ %\@EAEAEA\def\@EA\csname\@EA#2\@EA\endcsname\@EA{\csname#1\endcsname}}%
+ \@EA\def\csname#2\@EA\endcsname\@EA{\csname#1\endcsname}}% ugly but faster
+ \setinterfacesetupvariable{#1}{#2}}}
+
+\def\startcommands{\startinterfaceobjects\setinterfacecommand\stopcommands}
+
+\let\stopcommands\relax
+
+%D \macros
+%D {getinterfaceconstant, getinterfacevariable}
+%D
+%D Generating the interface translation macro's that are used
+%D in the reference lists, is enabled by setting the boolean:
+%D
+%D \starttyping
+%D \interfacetranslationtrue
+%D \stoptyping
+%D
+%D Keep in mind that enabling interfacetranslation costs a
+%D bit of hash space.
+
+\newif\ifinterfacetranslation
+
+% for a long time:
+%
+% \def\getinterfaceconstant#1%
+% {\ifinterfacetranslation
+% \doifdefinedelse{\x!prefix!#1}
+% {\getvalue{\x!prefix!#1}}
+% {#1}%
+% \else
+% #1%
+% \fi}
+%
+% \def\getinterfacevariable#1%
+% {\ifinterfacetranslation
+% \doifdefinedelse{\y!prefix!#1}
+% {\getvalue{\y!prefix!#1}}
+% {#1}%
+% \else
+% #1%
+% \fi}
+%
+% more compact
+
+\def\getinterfaceconstant#1%
+ {\ifinterfacetranslation
+ \executeifdefined{\x!prefix!#1}{#1}%
+ \else
+ #1%
+ \fi}
+
+\def\getinterfacevariable#1%
+ {\ifinterfacetranslation
+ \executeifdefined{\y!prefix!#1}{#1}%
+ \else
+ #1%
+ \fi}
+
+%D When a reference list is generated, one does not need to
+%D generate a new format. Just reloading the relevant
+%D definition files suits:
+%D
+%D \starttyping
+%D \interfacetranslationtrue
+%D \input mult-con
+%D \input mult-com
+%D \stoptyping
+
+%D \macros
+%D {interfaced}
+%D
+%D The setup commands translate the constants automatically.
+%D When we want to translate 'by hand' we can use the simple
+%D but effective command:
+%D
+%D \starttyping
+%D \interfaced {something}
+%D \stoptyping
+%D
+%D Giving \type{\interfaced{breedte}} results in \type{width}
+%D or, when not defined, in \type{breedte} itself. This
+%D macro is used in the font switching mechanism.
+
+\beginTEX
+
+\def\interfaced#1%
+ {\expandafter\ifx\csname\k!prefix!#1\endcsname\relax
+ #1%
+ \else
+ \csname\k!prefix!#1\endcsname
+ \fi}
+
+\endTEX
+
+\beginETEX \ifcsname
+
+\def\interfaced#1%
+ {\ifcsname\k!prefix!#1\endcsname
+ \csname\k!prefix!#1\endcsname
+ \else
+ #1%
+ \fi}
+
+\endETEX
+
+%D So much for the basic multi||lingual interface commands. The
+%D macro's can be enhanced with more testing facilities, but
+%D for the moment they suffice.
+
+%D Out of convenience we define the banners here.
+
+\edef\contextbanner
+ {ConTeXt \space
+ ver: \noexpand \contextversion \space \space
+ fmt: \noexpand \formatversion \space \space
+ int: \noexpand \currentinterface \space \space
+ mes: \noexpand \currentresponses}
+
+\def\showcontextbanner
+ {\writeline\writestring{\contextbanner}\writeline}
+
+\edef\formatversion
+ {\ifx\normalyear \undefined\the\year \else\the\normalyear \fi.%
+ \ifx\normalmonth\undefined\the\month\else\the\normalmonth\fi.%
+ \ifx\normalday \undefined\the\day \else\the\normalday \fi}
+
+\ifx\contextversion\undefined
+ \def\contextversion{unknown}
+ \def\contextversionnumber{0}
+\else
+ \def\contextversionnumber#1.#2.#3\relax{#1\ifnum#2<10 0\fi#2\ifnum#3<10 0\fi#3}
+ \edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax}
+\fi
+
+\ifx\undefined\normaldump
+ \newtoks\everydump
+ \let\normaldump\dump
+ \def\dump{\the\everydump\normaldump}
+\fi
+
+\appendtoks \showcontextbanner \to \everydump
+
+\protect \endinput