%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 \starttabulatie[|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 \stoptabulatie

\writestatus{loading}{Context Multilingual Macros / Initialization}

\unprotect

%D \macros
%D   [constanten,variabelen,commandos]
%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 \startregelcorrectie
%D \starttabel[|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 \stoptabel
%D \stopregelcorrectie
%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!}

%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 \starttypen
%D \defineinterfaceconstant {name} {meaning}
%D \defineinterfacevariable {name} {meaning}
%D \defineinterfaceelement  {name} {meaning}
%D \stoptypen
%D
%D Which is the same as:
%D
%D \starttypen
%D \def\c!name{meaning}
%D \def\v!name{meaning}
%D \def\e!name{meaning}
%D \stoptypen

\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 \starttypen
%D \definereferenceconstant {name} {meaning}
%D \definefileconstant      {name} {meaning}
%D \stoptypen

\def\definereferenceconstant #1#2{\setvalue{\r!prefix!#1}{#2}}
\def\definefileconstant      #1#2{\setvalue{\f!prefix!#1}{#2}}

%D And finaly we have the one argument, space saving constants
%D
%D \starttypen
%D \definesystemconstant  {name}
%D \definemessageconstant {name}
%D \stoptypen

\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 \starttypen
%D \definesystemvariable {name}
%D \stoptypen

\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 \starttypen
%D \startinterface language
%D
%D language specific definitions & commands
%D
%D \stopinterface
%D \stoptypen

%\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 \starttypen
%D \getmessage  {library} {tag}
%D \showmessage {library} {tag} {data}
%D \makemessage {library} {tag} {data}
%D \stoptypen
%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 \starttypen
%D \startmessages  english  library: alfa
%D   title: something
%D       1: first message
%D       2: second (--) message --
%D \stopmessages
%D \stoptypen
%D
%D The first message is a simple one and can be shown with:
%D
%D \starttypen
%D \showmessage {alfa} {1} {}
%D \stoptypen
%D
%D The second message on the other hand needs some extra data:
%D
%D \starttypen
%D \showmessage {alfa} {2} {and last,to you}
%D \stoptypen
%D
%D This message is shown as:
%D
%D \starttypen
%D something : second (and last) message to you
%D \stoptypen
%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 \starttypen
%D \startmessages  english  library: alfa
%D      10: tenth message
%D \stopmessages
%D \stoptypen
%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\\%
  {\def\docomposemessagetext##1,##2,##3,##4,##5,##6\\%
     {\edef\currentmessagetext{#1##1#2##2#3##3#4##4#5##5}}%
   \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 \starttypen
%D \showwarningstrue
%D \showmessagestrue
%D \stoptypen
%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,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 \starttypen
%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 \stoptypen
%D
%D These macros are called upon quite often and so we optimized
%D them a bit.

\def\dosetvalue#1#2#3%
  {\let\c!internal!\c!internal!n
   \p!doifundefined{\k!prefix!#2}%
     \let\c!internal!\c!internal!y
     \let\donottest\doprocesstest
     \@EA\def\csname#1#2\endcsname{#3}%
   \else
     \let\c!internal!\c!internal!y
     \let\donottest\doprocesstest
     \@EA\def\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
   \fi}

\def\dosetevalue#1#2#3%
  {\let\c!internal!\c!internal!n
   \p!doifundefined{\k!prefix!#2}%
     \let\c!internal!\c!internal!y
     \let\donottest\doprocesstest
     \@EA\edef\csname#1#2\endcsname{#3}%
   \else
     \let\c!internal!\c!internal!y
     \let\donottest\doprocesstest
     \@EA\edef\csname#1\csname\k!prefix!#2\endcsname\endcsname{#3}%
   \fi}

\def\docopyvalue#1#2#3%
  {\let\c!internal!\c!internal!n
   \p!doifundefined{\k!prefix!#3}%
     \let\c!internal!\c!internal!y
     \let\donottest\doprocesstest
     \@EA\def\csname#1#3\endcsname%
       {\csname#2#3\endcsname}%
   \else
     \let\c!internal!\c!internal!y
     \let\donottest\doprocesstest
     \@EA\def\csname#1\csname\k!prefix!#3\endcsname\endcsname%
       {\csname#2\csname\k!prefix!#3\endcsname\endcsname}%
   \fi}

\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).

\def\docopyvalue#1#2#3%  c -> k
  {\p!doifundefined{\k!prefix!#3}%
     \let\donottest\doprocesstest
     \@EAEAEA\def\@EA
       \csname\@EA#1\@EA#3\@EA
       \endcsname\@EA{\csname#2#3\endcsname}%
   \else
     \let\donottest\doprocesstest
     \@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}

%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}

% 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}
% 
% 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\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}
% 
% sligntly 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\docopyvalue#1#2#3%
  {\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}%
   \else
     \let\c!internal!\c!internal!y
     \@EAEAEA\def\@EA\@EA\csname#1#3\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 \starttypen
%D \setupsomething[some variable=some value, another one=a keyword]
%D \stoptypen
%D
%D or by keyword only:
%D
%D \starttypen
%D \dosomething[this way, that way, no way]
%D \stoptypen
%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 \starttypen
%D \setupbox [width=12cm, height=3cm]
%D \stoptypen
%D
%D results in something like
%D
%D \starttypen
%D \<box><width>   {12cm}
%D \<box><height>  {3cm}
%D \stoptypen
%D
%D while a similar command for specifying the page dimensions
%D of an \kap{A4} page results in:
%D
%D \starttypen
%D \<page><width>  {21.0cm}
%D \<page><height> {27.9cm}
%D \stoptypen
%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 \starttypen
%D \<box><color>   {<blue>}
%D \<box><kleur>   {<blauw>}
%D \<box><couleur> {<blue>}
%D \stoptypen
%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 \starttypen
%D \<pagenumber><location> {<left>}
%D \<skip><left>           {12cm}
%D \stoptypen
%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 \starttypen
%D \<empty><figure>
%D \<empty><intermezzo>
%D \stoptypen
%D
%D But in dutch we have the following:
%D
%D \starttypen
%D \<lege><figuur>
%D \<leeg><intermezzo>
%D \stoptypen
%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 \starttypen
%D \<prefix><variable>
%D \stoptypen
%D
%D This means that for instance:
%D
%D \starttypen
%D \setupbox[width=12cm]
%D \stoptypen
%D
%D expands to something like:
%D
%D \starttypen
%D \def\boxwidth{12cm}
%D \stoptypen
%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 \starttypen
%D \stelblokin[breedte=12cm]
%D \stoptypen
%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 \starttypen
%D \def\boxwidth   {12cm}
%D \def\boxbreedte {12cm}
%D \stoptypen
%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 \starttypen
%D \valueof\box\width
%D \stoptypen
%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 \starttypen
%D \c!width
%D \stoptypen
%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 \starttypen
%D \c!breedte
%D \stoptypen
%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{\c!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 \starttypen
%D \def\setupbox[#1]%
%D   {\getparameters[\??bx][#1]}
%D \stoptypen
%D
%D This command can be used as:
%D
%D \starttypen
%D \setupbox [width=3cm, height=1cm]
%D \stoptypen
%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 \starttypen
%D \stelblokin [breedte=3cm, hoogte=1cm]
%D \stoptypen
%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 \starttypen
%D \v!left
%D \stoptypen
%D
%D Which can be used in macro's like:
%D
%D \starttypen
%D \processaction
%D   [\@@bxlocation]
%D   [  \v!left=>\dosomethingontheleft,
%D    \v!middle=>\dosomthinginthemiddle,
%D     \v!right=>\dosomethingontheright]
%D \stoptypen
%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 \startsmaller \em
%D user variables become system constants
%D \stopsmaller
%D
%D and
%D
%D \startsmaller \em
%D user constants (keywords) become system variables
%D \stopsmaller
%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 \starttypen
%D \startconstants  english    dutch
%D
%D          width:  width      breedte
%D         height:  height     hoogte
%D
%D \stopconstants
%D \stoptypen
%D
%D Keep in mind that what users see as variables, are constants
%D for the system.
%D
%D \starttypen
%D \startvariables  english    dutch
%D
%D       location:  left       links
%D           text:  text       tekst
%D
%D \stopvariables
%D \stoptypen
%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
         \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.

\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!#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}

%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 \starttypen
%D \def\setinterfacesetupconstant
%D   {\ifinterfacetranslation
%D      \expandafter\setinterfaceconstant
%D    \fi}
%D \stoptypen
%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}

%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 \starttypen
%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 \stoptypen
%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 \starttypen
%D \startelements  english     dutch
%D
%D        setupa:  setup       stel
%D        setupb:  -           in
%D
%D \stopelements
%D \stoptypen
%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}

%D \macros
%D   {startcommands}
%D
%D The last setup has to do with the commands themselve.
%D Commands are defined as:
%D
%D \starttypen
%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 \stoptypen
%D
%D Here we also have to take care of the optional translation
%D needed for reference cards.

\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}}%
      \setinterfacesetupvariable{#1}{#2}}}

\def\startcommands
  {\startinterfaceobjects\setinterfacecommand\stopcommands}

%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 \starttypen
%D \interfacetranslationtrue
%D \stoptypen
%D
%D Keep in mind that enabling interfacetranslation costs a
%D bit of hash space.

\newif\ifinterfacetranslation

\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}

%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 \starttypen
%D \interfacetranslationtrue
%D \input mult-con
%D \input mult-com
%D \stoptypen

%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 \starttypen
%D \interfaced {something}
%D \stoptypen
%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} \fi

\ifx\undefined\normaldump
  \newtoks\everydump
  \let\normaldump\dump
  \def\dump{\the\everydump\normaldump}
\fi

\appendtoks \showcontextbanner \to \everydump

\protect

\endinput
