%D \module
%D   [       file=lang-spe,
%D        version=2002.05.07, % 1996.01.25,
%D          title=\CONTEXT\ Language Macros,
%D       subtitle=Specifics,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D This code was originally placed in the language 
%D initialization module, but isolating it is clearer.

\writestatus{loading}{Context Language Macros / Specifics}

\unprotect

%D \macros 
%D   {everyresetlanguagespecifics,resetlanguagespecifics}
%D 
%D Cleanup macros. 

\newevery \everyresetlanguagespecifics \relax

\def\resetlanguagespecifics
  {\ifcase\protectionlevel
     \the\everyresetlanguagespecifics
   \else % to be translated 
     \writestatus\m!systems{don't change language in unprotected mode!}%
   \fi}

\appendtoks
  \resetlanguagespecifics
\to \everycleanupfeatures

%D \macros
%D   {startlanguagespecifics,enablelanguagespecifics}
%D
%D Each language has its own typographic pecularities. Some of
%D those can be influenced by parameters, others are handled by
%D the interface, but as soon as specific commands come into
%D view we need another mechanism. In the macro that activates
%D a language, we call \type{\enablelanguagespecifics}. This
%D macro in return calls for the setup of language specific
%D macros. Such specifics are defined as:
%D
%D \starttypen
%D \startlanguagespecifics[de]
%D   \installcompoundcharacter "a {\"a}
%D   \installcompoundcharacter "e {\"e}
%D   \installcompoundcharacter "s {\SS}
%D \stoplanguagespecifics
%D \stoptypen
%D
%D Instead of \type{[du]} we can pass a comma separated
%D list, like \type{[du,nl]}. Next calls to this macro add the
%D specifics to the current list.
%D
%D Before we actually read the specifics, we first take some
%D precautions that will prevent spurious spaces to creep into
%D the list.

\def\startlanguagespecifics%                % we use double to
  {\bgroup
   \catcode`\^^I=\@@ignore
   \catcode`\^^M=\@@ignore
   \catcode`\^^L=\@@ignore
   \dodoubleempty\dostartlanguagespecifics} % get rid of spaces

%D The main macro looks quite complicated but actually does
%D nothing special. By embedding \type{\do} we can easily
%D append to the lists and also execute them at will. Just to
%D be sure, we check on spurious spaces. The second dummy
%D argument gobbles spaces.

\def\languageencoding%
  {\ifx\characterencoding\nocharacterencoding \else
     \characterencoding-%
   \fi}

% \long\def\dostartlanguagespecifics[#1][#2]#3\stoplanguagespecifics%
%   {\egroup
%    \long\def\docommando##1%
%      {\doifdefinedelse{\??la\languageencoding##1\??la}
%         {\long\def\do####1####2####3%
%            {\setvalue{\??la\languageencoding####1\??la}{\do{####1}{####2####3}}}%
%          \getvalue{\??la\languageencoding##1\??la}{#3}}
%         {\setvalue{\??la\languageencoding##1\??la}{\do{##1}{#3}}}%
%       \bgroup
%       \setbox0=\hbox{\enablelanguagespecifics[##1]}%
%       \ifdim\wd0>\!!zeropoint
%         \showmessage{\m!linguals}{7}{\currentencoding-##1,\the\wd0\space}\wait
%       \else
%         \showmessage{\m!linguals}{8}{\currentencoding-##1}%
%       \fi
%       \egroup
%       \doif{##1}{\currentmainlanguage}
%         {\enablelanguagespecifics[##1]}}%
%    \processcommalist[#1]\docommando}

% This saves 3K in the fmt file.

\long\def\dostartlanguagespecifics[#1][#2]#3\stoplanguagespecifics%
  {\egroup
   \processcommalist[#1]{\dosetlanguagespecifics{#3}}}

\long\def\dosetlanguagespecifics#1#2%
  {\doifdefinedelse{\??la\languageencoding#2\??la}
     {\long\def\do##1##2##3%
        {\setvalue{\??la\languageencoding##1\??la}{\do{##1}{##2##3}}}%
      \getvalue{\??la\languageencoding#2\??la}{#1}}
     {\setvalue{\??la\languageencoding#2\??la}{\do{#2}{#1}}}%
   \bgroup
   \setbox0=\hbox{\enablelanguagespecifics[#2]}%
   \ifdim\wd0>\zeropoint
     \showmessage{\m!linguals}{7}{\currentencoding-#2,\the\wd0\space}\wait
   \else
     \showmessage{\m!linguals}{8}{\currentencoding-#2}%
   \fi
   \egroup
   \doif{#2}{\currentmainlanguage}
     {\enablelanguagespecifics[#2]}}

%D Enabling them is rather straightforward. We only have to
%D define \type{\do} in such a way that \type{{ }} is removed
%D and the language key is gobbled.

%\def\enablelanguagespecifics[#1]%
%  {\let\do\secondoftwoarguments
%   \doifvaluesomething{\??la#1\c!default}
%     {\getvalue{\??la\getvalue{\??la#1\c!default}\??la}%
%      \getvalue{\??la\languageencoding\??la}}%
%   \getvalue{\??la#1\??la}%
%   \getvalue{\??la\languageencoding#1\??la}}
%
% sped up since used often:

\def\enablelanguagespecifics[#1]%
  {\let\do\secondoftwoarguments
   \csname
     \??la
     \@EA\ifx\csname\??la#1\c!default\endcsname\relax
       \languageencoding
     \else
       \csname\??la#1\c!default\endcsname
     \fi
     \??la
   \endcsname
   \csname\??la#1\??la\endcsname
   \csname\??la\languageencoding#1\??la\endcsname} % dup ?

%D \macros 
%D   {deactivatelanguagespecific}
%D 
%D The next code makes it possible to disable the specifics.

\def\deactivatelanguagespecific#1%
  {\ifundefined{l g s \string#1}%
     \letgvalueempty{l g s \string#1}% signal to prevent dup def 
     \bgroup
     \catcode`#1=\@@active
     \uccode`~=`#1
     \uppercase{\doglobal\appendtoks\dodeactivatetoken{~}\to\everyresetlanguagespecifics}%
     \egroup
     \expanded{\doglobal\noexpand\appendtoks{#1}{\the\catcode`#1}}\to\everyresetlanguagespecifics
   \fi}

% \def\dodeactivatetoken#1#2#3%
%   {\def#1{#2}\catcode`#2=#3\relax}

\def\dodeactivatetoken#1#2#3% tets needed to avoid clash with \unprotect 
  {\def#1{#2}\ifnum\catcode`#2=\@@active\catcode`#2=#3\relax\fi}

%D We cannot hook this into the installer since language 
%D specifics can be anything. So far, we have the following 
%D potentially active characters. 

%D Beware, this should happen under an unprotected regime; 
%D thanks to Giuseppe Oblomov Bilotta, who first noticed 
%D that something was wrong. 

\protect 

\deactivatelanguagespecific "
\deactivatelanguagespecific /
\deactivatelanguagespecific :
\deactivatelanguagespecific ;
\deactivatelanguagespecific ?
\deactivatelanguagespecific !

\unprotect 

%D \macros 
%D   {ordinaldaynumber, highordinalstr, ordinalstr}    
%D 
%D Efficient general ordinal number converters are sometimes 
%D difficult to implement. Fortunately dates never exceed the 
%D number~31.

\def\highordinalstr#1{\high{\nocap{#1}}}
\def\ordinalstr    #1{\nocap{#1}}

\def\ordinaldaynumber#1% \strippedcsname\ordinaldaynumber
  {\expanded{\executeifdefined{\currentlanguage ordinaldaynumber}%
     \noexpand\firstofoneargument{\number#1}}}

%D Language specific converters have definitions like:
%D 
%D \starttypen
%D \def\enordinaldaynumber#1{...} 
%D \stoptypen
%D 
%D Examples can be found in the other \type {lang} modules.

% \ifprocessingXML is a nasty dependency 

\appendtoks
  \ifprocessingXML \else \resetlanguagespecifics \fi
\to \everylanguage

\protect \endinput 
