diff options
Diffstat (limited to 'tex/context/base/mult-ini.tex')
| -rw-r--r-- | tex/context/base/mult-ini.tex | 2441 |
1 files changed, 1292 insertions, 1149 deletions
diff --git a/tex/context/base/mult-ini.tex b/tex/context/base/mult-ini.tex index 2519fb092..5bd104cde 100644 --- a/tex/context/base/mult-ini.tex +++ b/tex/context/base/mult-ini.tex @@ -1,1149 +1,1292 @@ -%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. Non||commercial use is
-%C granted.
-
-%D This module implements the multi||lingual interface to
-%D \CONTEXT. These capabilities concern messages, commands and
-%D parameters.
-
-\writestatus{loading}{Context Multilingual Macros / Initialization}
-
-\unprotect
-
-%D \macros
-%D [constanten,variabelen,commandos]
-%D {v!,c!,s!,e!,m!,l!,r!,f!,p!,x!,y!}
-%D {}
-%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{\v!prefix!} \NC v! \NC variable \NC\FR
-%D \NC \type{\c!prefix!} \NC c! \NC constant \NC\MR
-%D \NC \type{\s!prefix!} \NC s! \NC system \NC\MR
-%D \NC \type{\e!prefix!} \NC e! \NC element \NC\MR
-%D \NC \type{\m!prefix!} \NC m! \NC message \NC\MR
-%D \NC \type{\l!prefix!} \NC l! \NC language \NC\MR
-%D \NC \type{\r!prefix!} \NC r! \NC reference \NC\MR
-%D \NC \type{\f!prefix!} \NC f! \NC file \NC\MR
-%D \NC \type{\p!prefix!} \NC p! \NC procedure \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\v!prefix!{v!} \def\c!prefix!{c!} \def\s!prefix!{s!}
-\def\e!prefix!{e!} \def\m!prefix!{m!} \def\r!prefix!{r!}
-\def\f!prefix!{f!} \def\p!prefix!{p!} \def\x!prefix!{x!}
-\def\y!prefix!{y!} \def\l!prefix!{l!}
-
-%D \macros
-%D [constants,variables,commands]
-%D {@@,??}
-%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}
-
-%D \macros
-%D {defineinterfaceconstant,
-%D defineinterfacevariable,
-%D defineinterfaceelement,
-%D definesystemvariable,
-%D definesystemconstant,
-%D definemessageconstant,
-%D definereferenceconstant,
-%D definefileconstant}
-%D {}
-%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}}
-
-%D \macros
-%D {selectinterface,
-%D defaultinterface, currentinterface, currentresponses}
-%D {}
-%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\defaultinterface\undefined
-
- \def\defaultinterface{dutch}
-
- \def\selectinterface%
- {\def\docommando##1##2%
- {\bgroup
- \endlinechar=-1
- \global\read16 to ##1
- \egroup
- \doif{\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}
-
-\else
-
- \def\selectinterface%
- {\writestatus{interface}{defining \currentinterface\space interface}%
- \writeline
- \writestatus{interface}{using \currentresponses\space messages}%
- \writeline}
-
-\fi
-
-\ifx\currentinterface\undefined \let\currentinterface=\defaultinterface \fi
-\ifx\currentresponses\undefined \let\currentresponses=\defaultinterface \fi
-
-%D \macros
-%D {startinterface}
-%D {}
-%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
-
-%\long\def\startinterface #1 #2\stopinterface%
-% {\doifelse{#1}{\currentinterface}
-% {\long\def\next{#2}}
-% {\let\next=\relax}%
-% \next}
-
-\def\startinterface #1
- {\doifelse{#1}{\currentinterface}
- {\let\next\relax}
- {\long\def\next##1\stopinterface{}}%
- \next}
-
-\let\stopinterface=\relax
-
-%D \macros
-%D {startmessages,
-%D getmessage,
-%D showmessage,
-%D makemessage}
-%D {}
-%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.
-
-\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}
-
-\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
- \doifelse{\currentmessagetext}{}
- {\def\currentmessagetext{<unknown message #2>}}
- {\@EA\composemessagetext\currentmessagetext----------\\#3,,,,,\\}%
- \@EA\writestatus\@EA{\currentmessagetitle}{\currentmessagetext}}
-
-\def\doaddinterfacemessage#1#2%
- {\findinterfacemessage{#1}\currentmessagetext
- \doifelse{\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
- \def\next##1{\egroup}%
- \else
- \let\next\addinterfacemessage
- \fi
- \next}
-
-\gdef\startmessages #1 library: #2
- {\bgroup
- \obeylines
- \doifinsetelse{#1}{\currentresponses,all}
- {\def\next%
- {\def\currentmessagelibrary{#2}%
- \doifundefined{@@ms\currentmessagelibrary}
- {\setgvalue{@@ms\currentmessagelibrary}{}}%
- \futurelet\next\getinterfacemessage}}
- {\long\def\next##1\stopmessages{\egroup}}%
- \next}
-
-%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,docopyvalue,doresetvalue,
-%D dogetvalue}
-%D {}
-%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 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
-%D \def\dogetvalue#1#2%
-%D {\getvalue{#1\getvalue{\c!prefix!#2}}}
-%D \stoptypen
-%D
-%D These macros are called upon quite often and so we optimized
-%D them a bit.
-
-\def\dosetvalue#1#2#3%
- {\p!doifundefined{\c!prefix!#2}%
- \let\donottest\doprocesstest
- \@EA\def\csname#1#2\endcsname{#3}%
- \else
- \let\donottest\doprocesstest
- \@EA\def\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}%
- \fi}
-
-\def\dosetevalue#1#2#3%
- {\p!doifundefined{\c!prefix!#2}%
- \let\donottest\doprocesstest
- \@EA\edef\csname#1#2\endcsname{#3}%
- \else
- \let\donottest\doprocesstest
- \@EA\edef\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}%
- \fi}
-
-\def\docopyvalue#1#2#3%
- {\p!doifundefined{\c!prefix!#3}%
- \let\donottest\doprocesstest
- \@EA\def\csname#1#3\endcsname%
- {\csname#2#3\endcsname}%
- \else
- \let\donottest\doprocesstest
- \@EA\def\csname#1\csname\c!prefix!#3\endcsname\endcsname%
- {\csname#2\csname\c!prefix!#3\endcsname\endcsname}%
- \fi}
-
-\def\doresetvalue#1#2%
- {\dosetvalue{#1}{#2}{}}
-
-\def\dogetvalue#1#2%
- {\csname#1\csname\c!prefix!#2\endcsname\endcsname}
-
-%D Although maybe bot clearly visible, there is a
-%D considerable profit in further optimalization. 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%
- {\p!doifundefined{\c!prefix!#3}%
- \let\donottest\doprocesstest
- \@EA\@EA\@EA\def\@EA\csname\@EA#1\@EA#3\@EA\endcsname
- \@EA{\csname#2#3\endcsname}%
- \else
- \let\donottest\doprocesstest
- \@EA\@EA\@EA\def\@EA
- \csname
- \@EA#1\@EA\csname\@EA\c!prefix!\@EA#3\@EA\endcsname\@EA
- \endcsname
- \@EA{\csname#2\csname\c!prefix!#3\endcsname\endcsname}%
- \fi}
-
-%D We take this opportunity of redefining to adapt an
-%D assignment macro. The change has to do with the fact that the
-%D generated error message must be multi||lingual. We can not
-%D define the message yet, because we still have to select the
-%D interface language.
-
-%\def\p!doassign#1[#2][#3=#4=#5]%
-% {\let\donottest=\dontprocesstest
-% \edef\!!stringa{#5}%
-% \edef\!!stringb{\relax}%
-% \let\donottest=\doprocesstest
-% \ifx\!!stringa\!!stringb
-% \showmessage{check}{1}{#3,\the\inputlineno}%
-% \else
-% #1{#2}{#3}{#4}%
-% \fi}
-
-\def\p!doassign#1[#2][#3=#4=#5]%
- {\ifx\empty#3\else % and definitely not \ifx#3\empty
- \ifx\relax#5%
- \showmessage{check}{1}{#3,\the\inputlineno}%
- \else
- #1{#2}{#3}{#4}%
- \fi
- \fi}
-
-\def\dogetargument#1#2#3#4%
- {\doifnextcharelse{#1}
- {\let\expectedarguments\noexpectedarguments
- #3\dodogetargument}
- {\ifnum\expectedarguments>\noexpectedarguments
- \showmessage{check}{2}{\the\expectedarguments,\the\inputlineno}%
- \fi
- \let\expectedarguments\noexpectedarguments
- #4\dodogetargument#1#2}}
-
-\def\dogetgroupargument#1#2%
- {\def\nextnextargument%
- {\ifx\nextargument\bgroup
- \let\expectedarguments\noexpectedarguments
- \def\nextargument{#1\dodogetargument}%
- %\else\ifx\nextargument\lineending % this can be an option
- % \def\nextargument{\bgroup\def\\ {\egroup\dogetgroupargument#1#2}\\}%
- %\else\ifx\nextargument\blankspace % but may never be default
- % \def\nextargument{\bgroup\def\\ {\egroup\dogetgroupargument#1#2}\\}%
- \else
- \ifnum\expectedarguments>\noexpectedarguments
- \showmessage{check}{2}{\the\expectedarguments,\the\inputlineno}%
- \fi
- \let\expectedarguments\noexpectedarguments
- \def\nextargument{#2\dodogetargument{}}%
- \fi%\fi\fi % so let's get rid of it
- \nextargument}%
- \futurelet\nextargument\nextnextargument}
-
-\def\checkdefined#1#2#3%
- {\doifdefined{#3}
- {\showmessage{check}{3}{#2,#3}}}
-
-%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
-%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.
-
-\def\nointerfaceobject{-}
-
-\def\startinterfaceobjects#1#2%
- {\!!counta=1
- \let\dogetinterfaceobject\dogetinterfacetemplate
- \let\dowithinterfaceelement#1%
- \def\dodogetinterfaceobjects%
- {\ifx\next#2%
- \def\next####1%
- {}%
- \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]%
- {\doifinsetelse{#1}{\currentinterface,all}
- {\let\dogetinterfaceobject\doskipinterfaceobject}
- {\advance\!!counta by 1\relax}}
-
-\def\doskipinterfaceobject[#1:#2#3]%
- {\if#2:%
- \let\dogetinterfaceobject\dogetinterfaceelement
- \dogetinterfaceobject[#1:#2#3]%
- \fi}
-
-\def\dogetinterfaceelement[#1:#2#3]%
- {\ifx#2:%
- \!!countb=0
- \def\!!stringa{#1}%
- \else
- \advance\!!countb by 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.
-
-\def\setinterfaceconstant#1#2%
- {\setvalue{\c!prefix!#1}{#1}%
- \doifelse{#2}{\nointerfaceobject}
- {\debuggerinfo{constant}{#1 defined as #1 by default}}
- {\debuggerinfo{constant}{#1 defined as #2}%
- \ifinterfacetranslation
- \setvalue{\x!prefix!#1}{#2}%
- \fi
- \setvalue{\c!prefix!#2}{#1}}}
-
-\def\setinterfacevariable#1#2%
- {\doifelse{#2}{\nointerfaceobject}
- {\debuggerinfo{variable}{#1 defined as #1 by default}%
- \setvalue{\v!prefix!#1}{#1}}
- {\debuggerinfo{variable}{#1 defined as #2}%
- \setvalue{\v!prefix!#1}{#2}}}
-
-\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 thise 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
-%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
-%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}
- {\doifnot{\getvalue{\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
-%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}}%
- \@EA\@EA\@EA\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
-%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
-%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.
-
-\def\interfaced#1%
- {\expandafter\ifx\csname\c!prefix!#1\endcsname\relax
- #1%
- \else
- \csname\c!prefix!#1\endcsname
- \fi}
-
-%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.
-
-\protect
-
-\endinput
-
\ No newline at end of file +%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. Non||commercial use is +%C granted. + +%D This module implements the multi||lingual interface to +%D \CONTEXT. These capabilities concern messages, commands and +%D parameters. + +\writestatus{loading}{Context Multilingual Macros / Initialization} + +\unprotect + +%D \macros +%D [constanten,variabelen,commandos] +%D {v!,c!,s!,e!,m!,l!,r!,f!,p!,x!,y!} +%D {} +%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{\v!prefix!} \NC v! \NC variable \NC\FR +%D \NC \type{\c!prefix!} \NC c! \NC constant \NC\MR +%D \NC \type{\s!prefix!} \NC s! \NC system \NC\MR +%D \NC \type{\e!prefix!} \NC e! \NC element \NC\MR +%D \NC \type{\m!prefix!} \NC m! \NC message \NC\MR +%D \NC \type{\l!prefix!} \NC l! \NC language \NC\MR +%D \NC \type{\r!prefix!} \NC r! \NC reference \NC\MR +%D \NC \type{\f!prefix!} \NC f! \NC file \NC\MR +%D \NC \type{\p!prefix!} \NC p! \NC procedure \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\v!prefix!{v!} \def\c!prefix!{c!} \def\s!prefix!{s!} +\def\e!prefix!{e!} \def\m!prefix!{m!} \def\r!prefix!{r!} +\def\f!prefix!{f!} \def\p!prefix!{p!} \def\x!prefix!{x!} +\def\y!prefix!{y!} \def\l!prefix!{l!} + +%D \macros +%D [constants,variables,commands] +%D {@@,??} +%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 +%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}} + +%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\defaultinterface\undefined + + \def\defaultinterface{english} + + \def\selectinterface% + {\def\docommando##1##2% + {\bgroup + \endlinechar=-1 + \global\read16 to ##1 + \egroup + \doif{\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} + +\let\stopinterface=\relax + +%D \macros +%D {startmessages, +%D getmessage, +%D showmessage, +%D makemessage} +%D {} +%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. + +\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} + +\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 + \doifelse{\currentmessagetext}{} + {\def\currentmessagetext{<unknown message #2>}} + {\@EA\composemessagetext\currentmessagetext----------\\#3,,,,,\\}% + \@EA\writestatus\@EA{\currentmessagetitle}{\currentmessagetext}} + +\def\doaddinterfacemessage#1#2% + {\findinterfacemessage{#1}\currentmessagetext + \doifelse{\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 + \def\next##1{\egroup}% + \else + \let\next\addinterfacemessage + \fi + \next} + +\gdef\startmessages #1 library: #2 + {\definemessageconstant{#2}% handy for modules + \bgroup + \obeylines + \doifinsetelse{#1}{\currentresponses,all} + {\def\next% + {\def\currentmessagelibrary{#2}% + \doifundefined{@@ms\currentmessagelibrary} + {\setgvalue{@@ms\currentmessagelibrary}{}}% + \futurelet\next\getinterfacemessage}} + {\long\def\next##1\stopmessages{\egroup}}% + \next} + +%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,docopyvalue,doresetvalue, +%D dogetvalue} +%D {} +%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 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 +%D \def\dogetvalue#1#2% +%D {\getvalue{#1\getvalue{\c!prefix!#2}}} +%D \stoptypen +%D +%D These macros are called upon quite often and so we optimized +%D them a bit. + +\def\dosetvalue#1#2#3% + {\p!doifundefined{\c!prefix!#2}% + \let\donottest\doprocesstest + \@EA\def\csname#1#2\endcsname{#3}% + \else + \let\donottest\doprocesstest + \@EA\def\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}% + \fi} + +\def\dosetevalue#1#2#3% + {\p!doifundefined{\c!prefix!#2}% + \let\donottest\doprocesstest + \@EA\edef\csname#1#2\endcsname{#3}% + \else + \let\donottest\doprocesstest + \@EA\edef\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}% + \fi} + +\def\docopyvalue#1#2#3% + {\p!doifundefined{\c!prefix!#3}% + \let\donottest\doprocesstest + \@EA\def\csname#1#3\endcsname% + {\csname#2#3\endcsname}% + \else + \let\donottest\doprocesstest + \@EA\def\csname#1\csname\c!prefix!#3\endcsname\endcsname% + {\csname#2\csname\c!prefix!#3\endcsname\endcsname}% + \fi} + +\def\doresetvalue#1#2% + {\dosetvalue{#1}{#2}{}} + +\def\dogetvalue#1#2% + {\csname#1\csname\c!prefix!#2\endcsname\endcsname} + +%D Although maybe not clearly visible, there is a +%D considerable profit in further optimalization. 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% + {\p!doifundefined{\c!prefix!#3}% + \let\donottest\doprocesstest + \@EA\@EA\@EA\def\@EA + \csname\@EA#1\@EA#3\@EA + \endcsname\@EA{\csname#2#3\endcsname}% + \else + \let\donottest\doprocesstest + \@EA\@EA\@EA\def\@EA + \csname\@EA#1\@EA\csname\@EA\c!prefix!\@EA#3\@EA\endcsname\@EA + \endcsname\@EA{\csname#2\csname\c!prefix!#3\endcsname\endcsname}% + \fi} + +%D A slightly faster alternative: + +\beginTEX + +\def\dosetvalue#1#2#3% + {\@EA\ifx\csname\c!prefix!#2\endcsname\relax + \@EA\def\csname#1#2\endcsname{#3}% + \else + \@EA\def\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}% + \fi} + +\def\dosetevalue#1#2#3% + {\@EA\ifx\csname\c!prefix!#2\endcsname\relax + \@EA\edef\csname#1#2\endcsname{#3}% + \else + \@EA\edef\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}% + \fi} + +\def\docopyvalue#1#2#3% + {\@EA\ifx\csname\c!prefix!#3\endcsname\relax + \@EA\@EA\@EA\def\@EA + \csname\@EA#1\@EA#3\@EA + \endcsname\@EA{\csname#2#3\endcsname}% + \else + \@EA\@EA\@EA\def\@EA + \csname\@EA#1\@EA\csname\@EA\c!prefix!\@EA#3\@EA\endcsname\@EA + \endcsname\@EA{\csname#2\csname\c!prefix!#3\endcsname\endcsname}% + \fi} + +\endTEX + +\beginETEX \protected + +\def\dosetvalue#1#2#3% + {\ifcsname\c!prefix!#2\endcsname + \@EA\def\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}% + \else + \@EA\def\csname#1#2\endcsname{#3}% + \fi} + +\def\dosetevalue#1#2#3% + {\ifcsname\c!prefix!#2\endcsname + \@EA\edef\csname#1\csname\c!prefix!#2\endcsname\endcsname{#3}% + \else + \@EA\edef\csname#1#2\endcsname{#3}% + \fi} + +\def\docopyvalue#1#2#3% + {\ifcsname\c!prefix!#3\endcsname + \@EA\@EA\@EA\def\@EA + \csname\@EA#1\@EA\csname\@EA\c!prefix!\@EA#3\@EA\endcsname\@EA + \endcsname\@EA{\csname#2\csname\c!prefix!#3\endcsname\endcsname}% + \else + \@EA\@EA\@EA\def\@EA + \csname\@EA#1\@EA#3\@EA + \endcsname\@EA{\csname#2#3\endcsname}% + \fi} + +\endETEX + +%D We take this opportunity of redefining to adapt an +%D assignment macro. The change has to do with the fact that the +%D generated error message must be multi||lingual. We can not +%D define the message yet, because we still have to select the +%D interface language. + +%\def\p!doassign#1[#2][#3=#4=#5]% +% {\let\donottest=\dontprocesstest +% \edef\!!stringa{#5}% +% \edef\!!stringb{\relax}% +% \let\donottest=\doprocesstest +% \ifx\!!stringa\!!stringb +% \showmessage{check}{1}{#3,\the\inputlineno}% +% \else +% #1{#2}{#3}{#4}% +% \fi} + +\def\p!doassign#1[#2][#3=#4=#5]% + {\ifx\empty#3\else % and definitely not \ifx#3\empty + \ifx\relax#5% + \showmessage{check}{1}{#3,\the\inputlineno}% + \else + #1{#2}{#3}{#4}% + \fi + \fi} + +\def\dogetargument#1#2#3#4% + {\doifnextcharelse{#1} + {\let\expectedarguments\noexpectedarguments + #3\dodogetargument} + {\ifnum\expectedarguments>\noexpectedarguments + \showmessage{check}{2}{\the\expectedarguments,\the\inputlineno}% + \fi + \let\expectedarguments\noexpectedarguments + #4\dodogetargument#1#2}} + +\def\dogetgroupargument#1#2% + {\def\nextnextargument% + {\ifx\nextargument\bgroup + \let\expectedarguments\noexpectedarguments + \def\nextargument{#1\dodogetargument}% + %\else\ifx\nextargument\lineending % this can be an option + % \def\nextargument{\bgroup\def\\ {\egroup\dogetgroupargument#1#2}\\}% + %\else\ifx\nextargument\blankspace % but may never be default + % \def\nextargument{\bgroup\def\\ {\egroup\dogetgroupargument#1#2}\\}% + \else + \ifnum\expectedarguments>\noexpectedarguments + \showmessage{check}{2}{\the\expectedarguments,\the\inputlineno}% + \fi + \let\expectedarguments\noexpectedarguments + \def\nextargument{#2\dodogetargument{}}% + \fi%\fi\fi % so let's get rid of it + \nextargument}% + \futurelet\nextargument\nextnextargument} + +\def\checkdefined#1#2#3% + {\doifdefined{#3} + {\showmessage{check}{3}{#2,#3}}} + +%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 +%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: + +\ifx\undefined\scratchwrite \newwrite\scratchwrite \fi + +\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=1 + \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 by 1\relax}} + +\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=0 + \def\!!stringa{#1}% + \flushinterfaceelementline + \else + \advance\!!countb by 1 + \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. + +\def\setinterfaceconstant#1#2% + {\setvalue{\c!prefix!#1}{#1}% + \doifelse{#2}{\nointerfaceobject} + {\debuggerinfo{constant}{#1 defined as #1 by default}} + {\debuggerinfo{constant}{#1 defined as #2}% + \ifinterfacetranslation + \setvalue{\x!prefix!#1}{#2}% + \fi + \doifnot{#1}{#2} + {\checksetvalue{\c!prefix!#2}{#1}% + \setvalue{\c!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}}% + \wait}}}} + +\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 thise 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 +%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 +%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} + {\doifnot{\getvalue{\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 +%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}}% + \@EA\@EA\@EA\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 +%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 +%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. + +\beginTEX + +\def\interfaced#1% + {\expandafter\ifx\csname\c!prefix!#1\endcsname\relax + #1% + \else + \csname\c!prefix!#1\endcsname + \fi} + +\endTEX + +\beginETEX \ifcsname + +\def\interfaced#1% + {\ifcsname\c!prefix!#1\endcsname + \csname\c!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. + +\def\contextbanner% + {ConTeXt + ver: \contextversion \space + fmt: \formatversion \space + int: \currentinterface\space + mes: \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 + \let\normaldump\dump \def\dump{\showcontextbanner\normaldump} +\fi + +\protect + +\endinput |
