%D \module %D [ file=mult-ini, %D version=2008.10.22, % 1996.06.01, %D title=\CONTEXT\ Multilingual Macros, %D subtitle=Initialization, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D This module is a stripped down version of \type {mult-ini.tex}, which we keep %D around as \type {mult-kep.tex} for sentimental reasons. There you will find some %D more historic information. \writestatus{loading}{ConTeXt Multilingual Macros / Initialization} \unprotect \registerctxluafile{mult-ini}{} \registerctxluafile{mult-fmt}{initexonly} %D \macros %D [constanten,variabelen,commands] %D {v!,c!,k!,s!,e!,m!,l!,r!,f!,p!,x!,y!} %D %D In the system modules we introduced some prefixed constants, variables (both %D macros) and registers. Apart from a tremendous saving in terms of memory and a %D gain in speed we use from now on prefixes when possible for just another reason: %D consistency and multi||linguality. Systematically using prefixed macros enables %D us to implement a multi||lingual user interface. Redefining these next set of %D prefixes therefore can have desastrous results. %D %D \startlinecorrection %D \starttable[|c|c|c|] %D \HL %D \NC \bf prefix \NC \bf meaning \NC \bf application \NC\SR %D \HL %D \NC \type{\c!prefix!} \NC c! \NC constant (direct) \NC\FR %D \NC \type{\k!prefix!} \NC k! \NC constant (indirect) \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{\m!prefix!} \NC m! \NC age \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 \HL %D \stoptable %D \stoplinecorrection %D %D In the single||lingual version we used \type {!}, \type {!!}, \type {!!!} and %D \type {!!!!}. In the meantime some of these are obsolete (we had some 12 %D originally). \def\c!prefix!{c!} \def\k!prefix!{k!} \def\e!prefix!{e!} \def\f!prefix!{f!} % for the moment we keep this one \def\m!prefix!{m!} \def\s!prefix!{s!} \def\v!prefix!{v!} \def\t!prefix!{t!} %D \macros %D [constants,variables,commands] %D {@@,??} %D %D Variables generated by the system can be recognized on their prefix \type {@@}. %D They are composed of a command (class) specific tag, which can be recognized on %D \type {??}, and a system constant, which has the prefix \type {c!}. We'll se some %D more of this. \def\??prefix {??} \def\@@prefix {@@} %D Just to be complete we repeat some of the already defined system constants here. %D Maybe their prefix \type {\s!} now 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\s!true {true} \def\s!false {false} %D The word \type {height} takes 6~token memory cells. The control sequence \type %D {\height} on the other hand uses only one. Knowing this, we can improve the %D performance of \TEX, both is terms of speed and memory usage, by using control %D sequences instead of the words written in full. %D %D Where in the \ASCII\ file the second lines takes nine extra characters, \TEX\ %D saves us 13~tokens. %D %D \starttyping %D \hrule width 10pt height 2pt depth 1pt %D \hrule \s!width 10pt \s!height 2pt \s!depth 1pt %D \stoptyping %D %D One condition is that we have defined \type {\s!height}, \type {\s!width} and %D \type {\s!depth} as respectively \type {height}, \type {width} and \type {depth}. %D Using this scheme therefore only makes sense when a token sequence is used more %D than once. Savings like this should of course be implemented in english, just %D because \TEX\ is english. \def\s!width {width} \def\s!height {height} \def\s!depth {depth} \def\s!spread {spread} \def\s!plus {plus} \def\s!minus {minus} \def\s!to {to} \def\s!fil {fil} \def\s!fill {fill} \def\s!filll {filll} \def\s!attr {attr} \def\s!axis {axis} \def\s!both {both} \def\s!bottom {bottom} \def\s!left {left} \def\s!options {options} \def\s!orientation{orientation} \def\s!reverse {reverse} \def\s!right {right} \def\s!top {top} \def\s!xmove {xmove} \def\s!xoffset {xoffset} \def\s!ymove {ymove} \def\s!yoffset {yoffset} %D \macros %D {defineinterfaceconstant, %D defineinterfacevariable, %D defineinterfaceelement, %D definesystemvariable, %D definesystemconstant, %D definemessageconstant, %D definefileconstant} %D %D The first part of this module is dedicated to dealing with multi||lingual %D constants and variables. When \CONTEXT\ grew bigger and bigger in terms of bytes %D and used string space, we switched to predefined constants. At the cost of more %D hash table entries, the macros not only becase more compact, they became much %D faster too. Maybe an even bigger advantage was that mispelling could no longer %D lead to problems. Even a multi||lingual interface became possible. %D %D Constants |<|we'll introduce the concept of variables later on|>| are preceded by %D a type specific prefix, followed by a \type {!}. To force consistency, we provide %D a few commands for defining such constants. %D %D \starttyping %D \defineinterfaceconstant {name} {meaning} %D \defineinterfacevariable {name} {meaning} %D \defineinterfaceelement {name} {meaning} %D \stoptyping %D %D Which is the same as: %D %D \starttyping %D \def\c!name{meaning} %D \def\v!name{meaning} %D \def\e!name{meaning} %D \stoptyping \protected\def\defineinterfaceconstant#1#2{\expandafter\def\csname\c!prefix!#1\endcsname{#2}} \protected\def\defineinterfacevariable#1#2{\expandafter\def\csname\v!prefix!#1\endcsname{#2}} \protected\def\defineinterfaceelement #1#2{\expandafter\def\csname\e!prefix!#1\endcsname{#2}} %D Next come some interface independant constants: %D %D \starttyping %D \definefileconstant {name} {meaning} %D \stoptyping \protected\def\definefileconstant#1#2{\expandafter\def\csname\f!prefix!#1\endcsname{#2}} %D And finaly we have the one argument, space saving constants %D %D \starttyping %D \definesystemconstant {name} %D \definemessageconstant {name} %D \stoptyping \protected\def\definesystemconstant #1{\expandafter\def\csname\s!prefix!#1\endcsname{#1}} \protected\def\definemessageconstant#1{\expandafter\def\csname\m!prefix!#1\endcsname{#1}} %D For now here: \protected\def\definetagconstant #1{\expandafter\def\csname\t!prefix!#1\endcsname{#1}} \protected\def\aliastagconstant #1#2{\expandafter\let\csname\t!prefix!#1\expandafter\endcsname\csname\t!prefix!#2\endcsname} %D In a parameter driven system, some parameters are shared by more system %D components. In \CONTEXT\ we can distinguish parameters by a unique prefix. Such a %D prefix is defined with: %D %D \starttyping %D \definesystemvariable {name} %D \stoptyping \protected\def\definesystemvariable#1{\expandafter\edef\csname\??prefix#1\endcsname{\@@prefix#1}} \definesystemvariable{ms} %D \macros %D {selectinterface, %D defaultinterface, currentinterface, currentresponses} %D %D With \type {\selectinterface} we specify the language we are going to use. The %D system asks for the language wanted, and defaults to \type {\currentinterface} %D when we just give \type {enter}. By default the message system uses the current %D interface language, but \type {\currentresponses} can specify another language %D too. %D %D Because we want to generate formats directly too, we do not ask for interface %D specifications when these are already defined (like in cont-nl.tex and alike). \ifdefined\defaultinterface \def\selectinterface {\writestatus{interface}{defining \currentinterface\space interface}% %writeline \writestatus{interface}{using \currentresponses\space messages}% %\writeline \let\selectinterface\relax} \else \def\defaultinterface{english} \def\selectinterface {\def\selectinterface##1##2% {\bgroup \endlinechar\minusone \global\read16 to ##1 \egroup \doifnothing\currentinterface{\let##1=##2}% \doifundefined{\s!prefix!##1}{\let##1=##2}}% \selectinterface\currentinterface\defaultinterface \writestatus{interface}{defining \currentinterface\space interface}% %\writeline \selectinterface\currentresponses\currentinterface \writestatus{interface}{using \currentresponses\space messages}% %\writeline \let\selectinterface\relax} \fi \ifdefined\currentinterface \else \let\currentinterface\defaultinterface \fi \ifdefined\currentresponses \else \let\currentresponses\defaultinterface \fi %D \macros %D {startinterface} %D %D Sometimes we want to define things only for specific interface languages. This %D can be done by means of the selector: %D %D \starttyping %D \startinterface language %D %D language specific definitions & commands %D %D \stopinterface %D \stoptyping \protected\def\startinterface #1 {\doifnot{#1}{all}{\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 a decent message %D mechanism. Due to its multi||lingual interface, the message subsystem has to be %D multi||lingual too. A major drawback of this feature is that we have to code %D messages. As a result, the source becomes less self documented. On the other %D hand, consistency will improve. %D %D Because the overhead in terms of entries in the (already exhausted) hash table %D has to be minimal, messages are packed in libraries. We can extract a message %D from such a library in three ways: %D %D \starttyping %D \getmessage {library} {tag} %D \showmessage {library} {tag} {data} %D \makemessage {library} {tag} {data} %D \stoptyping %D %D The first command gets the message \type {tag} from the \type {library} %D specified. The other commands take an extra argument: a list of items to be %D inserted in the message text. While \type {\showmessage} shows the message at the %D terminal, the other commands generate the message as text. Before we explain the %D \type {data} argument, we give an example of a library. %D %D \starttyping %D \startmessages english library: alfa %D title: something %D 1: first message %D 2: second (--) message -- %D \stopmessages %D \stoptyping %D %D The first message is a simple one and can be shown with: %D %D \starttyping %D \showmessage {alfa} {1} {} %D \stoptyping %D %D The second message on the other hand needs some extra data: %D %D \starttyping %D \showmessage {alfa} {2} {and last,to you} %D \stoptyping %D %D This message is shown as: %D %D \starttyping %D something : second (and last) message to you %D \stoptyping %D %D As we can see, the title entry is shown with the message. The data fields are %D comma separated and are specified in the message text by \type {--}. %D %D It is not required to define all messages in a library at once. We can add %D messages to a library in the following way: %D %D \starttyping %D \startmessages english library: alfa %D 10: tenth message %D \stopmessages %D \stoptyping %D %D Because such definitions can take place in different modules, the system gives a %D warning when a tag occurs more than once. The first occurrence takes preference %D over later ones, so we had better use a save offset, as shown in the example. As %D we can see, the title field is specified only the first time! %D %D Because we want to check for duplicate tags, the macros are a bit more %D complicated than neccessary. The \NEWLINE\ token is used as message separator. %D %D For internal purposes one can use \type {\setmessagetext}, which puts the message %D text asked for in \type {\currentmessagetext}. %D %D These will become obsolete: \protected\def\startmessages #1 library: #2 % {\begingroup \ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi \catcode\endoflineasciicode\othercatcode \doifelseinset{#1}{\currentresponses,all}\mult_messages_start_yes\mult_messages_start_nop{#2}} \def\mult_messages_start_yes#1#2\stopmessages {\clf_setinterfacemessages{#1}{#2}% \endgroup} \def\mult_messages_start_nop#1#2\stopmessages {\endgroup} \let\stopmessages\relax \protected\def\setinterfacemessage#1#2#3% {\ifcsname\m!prefix!#1\endcsname\else\setgvalue{\m!prefix!#1}{#1}\fi \clf_setinterfacemessage{#1}{#2}{#3}} \protected\def\setmessagetext #1#2{\relax\edef\currentmessagetext{\clf_getmessage{#1}{#2}}} \protected\def\getmessage #1#2{\relax\clf_getmessage{#1}{#2}} \protected\def\doifelsemessage #1#2{\relax\clf_doifelsemessage{#1}{#2}} \protected\def\showmessage #1#2#3{\relax\clf_showmessage{#1}{#2}{#3}} \protected\def\writestatus #1#2{\relax\clf_writestatus{#1}{#2}} \protected\def\message {\relax\clf_message} \let\doifmessageelse\doifelsemessage \protected\def\inlinemessage #1{\dontleavehmode{\tttf#1}} \protected\def\displaymessage#1{\blank\inlinemessage{#1}\blank} \let\getsetupstring\clf_getsetupstring \let\rawsetupstring\clf_rawsetupstring %D For old times sake: \let\showwarning\showmessage %D \macros %D {dosetvalue,dosetevalue,dosetgvalue,dosetxvalue,docopyvalue,doresetvalue} % dogetvalue %D %D We already defined these auxiliary macros in the system modules. Starting with %D this module however, we have to take multi||linguality a bit more serious. %D %D In due time, when we exclusively use the parameter handler code, we can drop the %D backmapping (\type{\c!k...}) and make \type {\c!c...} similar to \type {\v!...}. %D In that case we can simply the following setters. \protected\def\doletvalue #1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} \protected\def\dosetvalue #1#2{\expandafter\def \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} \protected\def\dosetevalue #1#2{\expandafter\edef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} \protected\def\dosetgvalue #1#2{\expandafter\gdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} \protected\def\dosetxvalue #1#2{\expandafter\xdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} \protected\def\doresetvalue #1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname\empty} \protected\def\doignorevalue#1#2#3{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname\empty} \protected\def\docopyvalue#1#2#3% {\ifcsname\k!prefix!#3\endcsname \expandafter\def\csname#1\csname\k!prefix!#3\endcsname\expandafter\endcsname\expandafter {\csname#2\csname\k!prefix!#3\endcsname\endcsname}% \else \expandafter\def\csname#1#3\expandafter\endcsname\expandafter {\csname#2#3\endcsname}% \fi} \startinterface english \protected\def\doletvalue #1#2{\expandafter \let\csname#1#2\endcsname} \protected\def\dosetvalue #1#2{\expandafter \def\csname#1#2\endcsname} \protected\def\dosetevalue #1#2{\expandafter\edef\csname#1#2\endcsname} \protected\def\dosetgvalue #1#2{\expandafter\gdef\csname#1#2\endcsname} \protected\def\dosetxvalue #1#2{\expandafter\xdef\csname#1#2\endcsname} \protected\def\doresetvalue #1#2{\expandafter \let\csname#1#2\endcsname\empty} \protected\def\doignorevalue#1#2#3{\expandafter \let\csname#1#2\endcsname\empty} \protected\def\docopyvalue#1#2#3% {\expandafter\def\csname#1#3\expandafter\endcsname\expandafter {\csname#2#3\endcsname}} \stopinterface %D We can now redefine some messages that will be introduced in the multi||lingual %D system module. \protected\def\showassignerror #1#2{\showmessage\m!check1{#1,#2}} \protected\def\showargumenterror#1#2{\showmessage\m!check2{#1,#2}} \protected\def\showdefinederror #1#2{\showmessage\m!check3{#1,#2}} %D \CONTEXT\ is a parameter driven package. This means that users instruct the %D system by means of variables, values and keywords. These instructions take the %D form: %D %D \starttyping %D \setupsomething[some variable=some value, another one=a keyword] %D \stoptyping %D %D or by keyword only: %D %D \starttyping %D \dosomething[this way,that way,no way] %D \stoptyping %D %D Because the same variables can occur in more than one setup command, we have to %D be able to distinguish them. This is achieved by assigning them a unique prefix. %D %D Imagine a setup command for boxed text, that enables us to specify the height and %D width of the box. Behide the scenes the command %D %D \starttyping %D \setupbox [width=12cm, height=3cm] %D \stoptyping %D %D results in something like %D %D \starttyping %D \ {12cm} %D \ {3cm} %D \stoptyping %D %D while a similar command for specifying the page dimensions %D of an \cap {A4} page results in: %D %D \starttyping %D \ {21.0cm} %D \ {27.9cm} %D \stoptyping %D %D The prefixes \type {} and \type {} are hidden from users and can %D therefore be language independant. Variables on the other hand, differ for each %D language: %D %D \starttyping %D \ {} %D \ {} %D \ {} %D \stoptyping %D %D In this example we can see that the assigned values or keywords are language %D dependant too. This will be a complication when defining multi||lingual setup %D files. %D %D A third phenomena is that variables and values can have a similar meaning. %D %D \starttyping %D \ {} %D \ {12cm} %D \stoptyping %D %D A (minor) complication is that where in english we use \type {}, in dutch %D we find both \type {} and \type {}. This means that when we use %D some sort of translation table, we have to distinguish between the variables at %D the left side and the fixed values at the right. %D %D The same goes for commands that are composed of different user supplied and/or %D language specific elements. In english we can use: %D %D \starttyping %D \
%D \ %D \stoptyping %D %D But in dutch we have the following: %D %D \starttyping %D \ %D \ %D \stoptyping %D %D These subtle differences automatically lead to a solution where variables, %D values, elements and other components have a similar logical name (used in %D macro's) but a different meaning (supplied by the user). %D %D Our solution is one in which the whole system is programmed in terms of %D identifiers with language specific meanings. In such an implementation, each %D fixed variable is available as: %D %D \starttyping %D \ %D \stoptyping %D %D This means that for instance: %D %D \starttyping %D \setupbox[width=12cm] %D \stoptyping %D %D expands to something like: %D %D \starttyping %D \def\boxwidth{12cm} %D \stoptyping %D %D because we don't want to recode the source, a setup command in another language %D has to expand to this variable, so: %D %D \starttyping %D \setupblock[width=12cm] %D \stoptyping %D %D has to result in the definition of \type {\boxwidth} too. This method enables us %D to build compact, fast and readable code. %D %D An alternative method, which we considered using, uses a more indirect way. In %D this case, both calls generate a different variable: %D %D \starttyping %D \def\boxwidth {12cm} %D \def\boxbreedte {12cm} %D \stoptyping %D %D And because we don't want to recode those megabytes of already developed code, %D this variable has to be called with something like: %D %D \starttyping %D \valueof\box\width %D \stoptyping %D %D where \type {\valueof} takes care of the translation of \type {width} or \type %D {breedte} to \type {width} and combining this with \type {box} to \type %D {\boxwidth}. %D %D One advantage of this other scheme is that, within certain limits, we can %D implement an interface that can be switched to another language at will, while %D the current approach fixes the interface at startup. There are, by the way, other %D reasons too for not choosing this scheme. Switching user generated commands is %D for instance impossible and a dual interface would therefore give a strange mix %D of languages. %D %D Now let's work out the first scheme. Although the left hand of the assignment is %D a variable from the users point of view, it is a constant in terms of the system. %D Both \type {width} and \type {breedte} expand to \type {width} because in the %D source we only encounter \type {width}. Such system constants are presented as %D %D \starttyping %D \c!width %D \stoptyping %D %D This constant is always equivalent to \type {width}. As we can see, we use \type %D {c!} to mark this one as constant. Its dutch counterpart is: %D %D \starttyping %D breedte %D \stoptyping %D %D When we interpret a setup command each variable is translated to it's \type{c!} %D counterpart. This means that \type {breedte} and \type{width} expand to \type %D {breedte} and \type {\c!width} which both expand to \type {width}. That way user %D variables become system constants. %D %D The interpretation is done by means of a general setup command \type %D {\getparameters} that we introduced in the system module. Let us define some %D simple setup command: %D %D \starttyping %D \protected\def\setupbox[#1]% %D {\getparameters[\??bx][#1]} %D \stoptyping %D %D This command can be used as: %D %D \starttyping %D \setupbox [width=3cm, height=1cm] %D \stoptyping %D %D Afterwards we have two variables \type {\@@bxwidth} and \type {\@@bxheight} which %D have the values \type {3cm} and \type {1cm} assigned. These variables are a %D combinatiom of the setup prefix \type {\??bx}, which expands to \type {@@bx} and %D the translated user supplied variables \type {width} and \type {height} or \type %D {breedte} and \type {hoogte}, depending on the actual language. In dutch we just %D say: %D %D \starttyping %D \stelblokin [breedte=3cm,hoogte=1cm] %D \stoptyping %D %D and get ourselves \type {\@@bxwidth} and \type {\@@bxheight} too. In the source %D of \CONTEXT, we can recognize constants and variables on their leading \type %D {c!}, \type {v!} etc., prefixes on \type {??} and composed variables on \type %D {@@}. %D %D We already saw that user supplied keywords need some special treatment too. This %D time we don't translate the keyword, but instead use in the source a variable %D which meaning depends on the interface language. %D %D \starttyping %D \v!left %D \stoptyping %D %D Which can be used in macro's like: %D %D \starttyping %D \processaction %D [\@@bxlocation] %D [ \v!left=>\dosomethingontheleft, %D \v!middle=>\dosomthinginthemiddle, %D \v!right=>\dosomethingontheright] %D \stoptyping %D %D Because variables like \type {\@@bxlocation} can have a lot of meanings, %D including tricky expandable tokens, we cannot translate this meaning when we %D compare. This means that \type {\@@bxlocation} can be \type {left} of \type %D {links} of whatever meaning suits the language. But because \type {\v!left} also %D has a meaning that suits the language, we are able to compare. %D %D Although we know it sounds confusing we want to state two important %D characteristics of the interface as described: %D %D \startnarrower \em %D user variables become system constants %D \stopnarrower %D %D and %D %D \startnarrower \em %D user constants (keywords) become system variables %D \stopnarrower %D %D The \type {\c!internal} is a left over from the time that the user interface %D documents were not using a specification alongside a keyword specification but %D used a shared file in which case we need to go in both directions. % temporary mkiv hack (we can best just store the whole table in memory) \protected\def\setinterfaceconstant#1#2% {\clf_setinterfaceconstant{#1}{#2}% \expandafter\def\csname\c!prefix!#1\endcsname{#1}} \protected\def\setinterfacevariable#1#2% {\clf_setinterfacevariable{#1}{#2}% \expandafter\def\csname\v!prefix!#1\endcsname{#2}} %D \macros %D {defineinterfaceconstant} %D %D Next we redefine a previously defined macro to take care of interface translation %D too. It's a bit redundant, because in these situations we could use the %D c||version, but for documentation purposes the x||alternative comes in handy. \protected\def\defineinterfaceconstant#1#2% {\expandafter\def\csname\c!prefix!#1\endcsname{#2}} %D \macros %D {startelements} %D %D Due to the object oriented nature of \CONTEXT, we also need to define the %D elements that are used to build commands. %D %D Such elements sometimes are the same in different languages, but mostly they %D differ. Things can get even confusing when we look at for instance the setup %D commands. In english we say \type{\setup}, but in dutch we have: \type %D {\stelin}. Such split elements are no problem, because we just define two %D elements. When no second part is needed, we use a \type {-}: \protected\def\setinterfaceelement#1#2% {\clf_setinterfaceelement{#1}{#2}% \ifcsname\e!prefix!#1\endcsname \doifnotvalue{\e!prefix!#1}{#2}{\setvalue{\e!prefix!#1}{#2}}% \else \setvalue{\e!prefix!#1}{#2}% \fi} \protected\def\setinterfacecommand#1#2% {\doifnot{#1}{#2}% todo: let when already defined {\expandafter\def\csname#2\expandafter\endcsname\expandafter{\csname#1\endcsname}}} %D We just ignore these: \protected\def\startvariables{\gobbleuntil\stopvariables} \let\stopvariables\relax \protected\def\startconstants{\gobbleuntil\stopconstants} \let\stopconstants\relax \protected\def\startelements {\gobbleuntil\stopelements } \let\stopelements \relax \protected\def\startcommands {\gobbleuntil\stopcommands } \let\stopcommands \relax %D For at the \LUA\ end (experiment): \def\ui_c#1#2{\expandafter\gdef\csname\c!prefix!#1\endcsname{#1}% \expandafter\gdef\csname\k!prefix!#2\endcsname{#1}} % backmapping from non english \def\ui_s #1{\expandafter\gdef\csname\c!prefix!#1\endcsname{#1}% \expandafter\gdef\csname\k!prefix!#1\endcsname{#1}} % backmapping from non english \def\ui_v#1#2{\expandafter\gdef\csname\v!prefix!#1\endcsname{#2}} \def\ui_e#1#2{\expandafter\gdef\csname\e!prefix!#1\endcsname{#2}} %def\ui_m#1#2{\expandafter\gdef\csname#2\expandafter\endcsname\expandafter{\csname#1\endcsname}} \def\ui_a#1#2{\aliasmacro#2#1} \startinterface english \def\ui_c#1#2{\expandafter\gdef\csname\c!prefix!#1\endcsname{#1}} \def\ui_s #1{\expandafter\gdef\csname\c!prefix!#1\endcsname{#1}} \stopinterface %D So much for the basic multi||lingual interface commands. The macro's can be %D enhanced with more testing facilities, but for the moment they suffice. \ifdefined\zwnj \else \edef\zwnj{\directlua{utf.char(\number"200C)}} \fi % needed for cont-pe % maybe to char-utf.mkiv \ifdefined\zwj \else \edef\zwj {\directlua{utf.char(\number"200D)}} \fi % needed for cont-pe % maybe to char-utf.mkiv %D \macros %D {contextversion, contextversionnumber, contextversionno, %D contextbanner, showcontextbanner, formatversion} %D %D Out of convenience we define the banners here. This might move to the \LUA\ end. \def\contextbanner {ConTeXt \space ver: \contextversion \space \contextmark \space \space fmt: \formatversion \space \space int: \currentinterface/\currentresponses} \protected\def\showcontextbanner {\writestatus\m!system\empty \writestatus\m!system\contextbanner \writestatus\m!system\empty} \edef\formatversion {\the\normalyear.\the\normalmonth.\the\normalday} \newcount\contextversionno \ifx\contextversion\undefined \edef\contextversion{\the\normalyear.\the\normalmonth.\the\normalday\space 00:00} \fi % \def\contextversionnumber#1.#2.#3 #4:#5\relax{#1\ifnum#2<10 0\fi\purenumber{#2}\ifnum#3<10 0\fi\purenumber{#3} #4:#5} % \edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark} \protected\def \contextversionnumber #1.#2.#3 #4:#5\relax{#1#2#3} \contextversionno \expandafter\contextversionnumber\contextversion\relax \edef \contextversionnumber {\the\contextversionno\space\contextmark} %D \macros %D {everydump} %D %D This one is only used when we generate the format. \ifx\undefined\everydump \newtoks\everydump \def\dump{\the\everydump\global\everydump\emptytoks\glet\dump\relax\normaldump} \fi % \appendtoks \showcontextbanner \to \everydump \protect \endinput