%% LANG: multi-language system for plain
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Apr. 2004                   Petr Olsák

%%%% See langdoc.tex for more details

\ifx\setlang\undefined \else \endinput \fi

\def\LANGversion {Beta-c} 

\ifx\setfonts\undefined \input ofs \relax \fi

\ifx\ofsinput\undefined 
   \errmessage{Upgrade OFS to version Apr. 2004, please}
   \endinput \fi

\loadingenc=1

\message{LANG (Multi-language System) based on plain initialized. 
   <\LANGversion>}


%%%% \langusage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bgroup \catcode`\#=12 
  \catcode`\^^M=14 \catcode`\ =12 \catcode`\|=0\catcode`\\=12
|gdef|langusage{%
|immediate|write16{%---------------------------------------------------
\langusage: ========= LANG: multiple languages in plain, usage: ==========^^J
in iniTeX:   \input lang^^J
patterns loading, languages declaration:  see langdef.tex file^^J
in your document:^^J
\showlangs  ... shows all declared languages^^J 
\setlang [LANG/encoding]  ... local switch to the language and font encoding^^J
\setlang [LANG/] ... local switch to the language, font encoding unchanged^^J
\setlang [/encoding] ... local switch to font encoding, LANG unchannged^^J
Language selectors: \german etc. ... the same as \setlang [de/] etc.^^J
         default language: none, default encoding: 8t.^^J  
\setlang [LANG/encoding]\setfonts[Family/] ... change LANG/encoding/Family.^^J
\setlang [LANG/]\langinfo ... more information about language.^^J
\setlang [LANG/]\printlangdoc ... full documentation about LANG's style file.^^J
\langphrases ... sets phrases of \chaptername etc. to current language.^^J
\activechar<char> ... sets <char> as active, behavior dependent on language.^^J
\nolangmessages, \loglangmessages ... levels of log.^^J
    See langdoc.pdf or langdoce.pdf for more information
}}}%-------------------------------------------------------------------


%%%% \declareenc, \declarelang %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newread\testin 

\def\declareenc #1 #2 {%
   \openin\testin=ofs-#1.tex
   \ifeof\testin \langmessagewarn {File "ofs-#1.tex" doesn't exist,^^J
                            \sssp  encoding "#1" cannot be declared.}%
   \else \closein\testin 
      \knownfam #2? \iftrue 
          \registeredfam #2? \iftrue 
              \expandafter \xdef \csname a:>#1\endcsname {#2}%
          \else
              \langmessagewarn {Font family "#2" unregistered 
                           in "#1" encoding}\fi
      \else \langmessagewarn {Font family "#2" undeclared in OFS}%
   \fi\fi
}
\def\defaultfam{\csname a:>\fotenc\endcsname}

\def\declarelang #1#2 #3 #4 ; {%
   \openin\testin #3
      \ifeof\testin \langmessagewarn {Style "#4" doesn't exist,^^J
                             \sssp  language "#2" cannot be declared.}%
   \else \closein\testin 
      \expandafter\edef \csname s:>#2\endcsname {#3}% style file
      \edef#1{\noexpand\setlang[#2/]}%
      \expandafter \def \csname l:>#2\endcsname {}%
      \edef\currentlang {#2}%
      \encodingsforlang #4 ;
      \expandafter \ifx \csname l:>#2\endcsname \empty
          \expandafter \let \csname l:>#2\endcsname=\relax
          \langmessagewarn {The language "#2" is undeclared because
                            there are no encodings.}%
      \else {\let\showLANG=\relax \def\tmpa{\noexpand\tmpa \noexpand}%
             \xdef\langdeclaredlist{\langdeclaredlist\showLANG\tmpa#1 #2 }}\fi
  \fi
}
\def\langdeclaredlist{} % for \showlangs purpose
\def\encodingsforlang #1#2 {%
   \if ;#1\else
      \if=#1%
         \expandafter \ifx \csname a:>#2\endcsname \relax
             \langmessagewarn {Unregistered encoding "#2": ignored}% 
         \else \expandafter \ifx \csname l:>\currentlang\endcsname \empty
                   \errmessage {the first must not be daclared by "="}\fi            
             \edef\act {\def\expandafter \noexpand \csname l:>\currentlang\endcsname {%
                  \csname l:>\currentlang\endcsname =#2 }}\act
         \fi
      \else \expandafter \ifx \csname a:>#1#2\endcsname \relax
             \langmessagewarn {Unregistered encoding "#1#2": ignored}%           
         \else  \expandafter \ifx \csname l:>\currentlang\endcsname \empty
                   \expandafter \def\csname de:>\currentlang\endcsname{#1#2}\fi 
                \edef\act {\def\expandafter \noexpand \csname l:>\currentlang\endcsname {%
                \csname l:>\currentlang\endcsname #1#2 }}\act
      \fi\fi
      \expandafter \encodingsforlang
   \fi        
}


%%% \showlangs %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\showlangs{\immediate\write16{%
LANG selector\sssp\sssp style-file \sssp encodings<num.of.hyphen.table>^^J%
---------------------------------------------------------------}\langdeclaredlist}

\def\showLANG #1#2 #3 {%
   \bgroup
      \def\tmpa ##1{\if^^X##1\else\advance\count2 by-1 \expandafter\tmpa\fi}%
      \def\tmpb {\ifnum\count2>0 \advance\count2 by-1 \edef\tmpc{\tmpc\space}%
                 \expandafter\tmpb\fi}%     
      \def\tmpc{#3}%
      \count2=5 \tmpa#3^^X\tmpb
      \edef\tmpc{\tmpc\string#2}%
      \count2=14 \expandafter\tmpa\string#2^^X\tmpb
      \edef\tmpc{\tmpc\csname s:>#3\endcsname}%
      \count2=14 \expandafter\expandafter\expandafter
                      \tmpa\csname s:>#3\endcsname^^X\tmpb
      \def\tmpa ##1##2 {\if;##1\else
         \if=##1\def\tmpb{##2}\else\def\tmpb{##1##2}\fi
         \expandafter \ifx \csname p:>#3/\tmpb\endcsname\relax 
            \edef\tmpc{\tmpc\space\tmpb<?>}%
         \else \edef\tmpc{\tmpc\space\tmpb<%
                    \ifnum \csname p:>#3/\tmpb\endcsname=\emptyhyphentable=\else
                \the \csname p:>#3/\tmpb\endcsname\fi>}\fi
         \expandafter \tmpa\fi}%
      \expandafter\expandafter\expandafter\tmpa \csname l:>#3\endcsname;
      \immediate\write16{\tmpc}
   \egroup
}


%%%% \setpatterns, \loadpatterns %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcount\defaulthyphentable
\def\emptyhyphentable{255}
\defaulthyphentable=\emptyhyphentable

\def\hyphentable [#1]{\if|#1|\emptyhyphentable\relax
   \else \hyphentableA [#1]\fi}
\def\hyphentableA [#1/#2]{%
   \expandafter \ifx \csname p:>#1/#2\endcsname \relax
      \defaulthyphentable \nohyphentablewarn{#1/#2}%
   \else \csname p:>#1/#2\endcsname \relax \fi
   \ignorespaces
}
\def\nohyphentablewarn#1{%
  \langmessagewarn {Hyphenation table [#1] was not loaded^^J
         \sssp I use "\string\defaulthyphentable=\the\defaulthyphentable"
               instead of given table^^J
         \sssp Modify \noexpand\loadpatterns parameters in langdef.tex and^^J
         \sssp run iniTeX again if you need given table exactly.}%
} 

\newcount\numpatterns  \numpatterns=0  % The number of patterns loaded

\def\declarehyphentable [#1/#2]{%
   \edef\tmpa{#2}%
   \ifx\fotenc\tmpa
      \lccodesloop ^^80^^ff^^80%  % identity mapping
   \else \input h#2-\fotenc.tex   % no-identity mapping
   \fi
}
\def\loadpatternstable #1#2{%
   \ifnum\numpatterns >254
      \langmessagewarn {Loading table [#1/#2] ignored, too many patterns.}%
   \else
      \openin\testin=hyph-#1.tex
      \ifeof\testin \langmessagewarn {File "hyph-#1.tex" doesn't exist,^^J
                         \sssp  hyphenation patterns cannot be loaded.}%
         \language=-1
      \else \closein\testin 
         \expandafter \ifx \csname p:>#1/#2\endcsname \relax
            \language=\numpatterns
            \global\advance \numpatterns by1
            \langmessage {Loading hyphenation table [#1/#2]: \language = \the\language}%
            \ifx\savinghyphcodes\undefined \else
               \expandafter \ifx \csname #2:lccodes\endcsname \relax
                  \input ofs-#2.tex
               \fi
               \expandafter \let\expandafter \resetlccodes \csname #2:lccodes\endcsname
               \ifx \resetlccodes\relax 
                  \langmessagewarn {There is no lccodes 
                       in ofs-#2.tex, hyphcodes not saved.}
                  \savinghyphcodes=0 
                  \let\patterns=\oripatterns \let\hyphenation=\orihyphenation
               \else
                  \langmessage {eTeX's hyphenation codes "#2" are saved.}
                  \savinghyphcodes=1 
                  \let\patterns=\newpatterns \let\hyphenation=\newhyphenation
            \fi\fi            
            \begingroup
               \input hyph-#1.tex
            \endgroup
            \global \expandafter\chardef \csname p:>#1/#2\endcsname =\language
         \else \langmessagewarn {Hyphen table [#1/#2] loaded already.}
   \fi\fi\fi
}

\def\loadpatterns {\bgroup 
   \ifx\savinghyphcodes\undefined \else 
      \message{eTeX's hyphenation codes are used}
      \let\oripatterns=\patterns
      \let\orihyphenation=\hyphenation
      \def\newpatterns ##1{\lowercase{\resetlccodes\oripatterns{##1}}}
      \def\newhyphenation ##1{\lowercase{\orihyphenation{##1}}}
      \def\modifydef ##1;##2{\expandafter \def \csname##1\endcsname {##2}\endinput}
      \def\protectreading ##1 {}
   \fi
   \doloadpatterns}

\def\doloadpatterns #1#2 {\if;#1\egroup
   \else 
       \expandafter \ifx \csname l:>#1#2\endcsname \relax
           \langmessagewarn {Language "#1#2" is undeclared, patterns
                             loading ignored}%
           \def\tmpa{\futurelet \tmpa \doloadpatternsA}%
           \expandafter\expandafter\expandafter \tmpa
       \else
          \def\currentlang{#1#2}\edef\langlist{\langlist #1#2 }%
          \def\tmpa {\futurelet \tmpa \loadpatternsforlangA}%
          \expandafter\expandafter\expandafter \tmpa
   \fi\fi
}
\def\doloadpatternsA {\ifx\tmpa\bgroup \expandafter \doloadpatternsB
   \else \expandafter \doloadpatterns \fi}
\def\doloadpatternsB #1{\doloadpatterns}

\def\loadpatternsforlangA {%
   \ifx\tmpa\bgroup 
      \expandafter \loadpatternsforlangB
   \else 
      \expandafter \expandafter \expandafter
      \loadpatternslist \csname l:>\currentlang\endcsname;
      \expandafter \doloadpatterns
   \fi
}
\def\loadpatternsforlangB #1{\loadpatternslist #1 ; \doloadpatterns}

\def\loadpatternslist #1#2 {\if;#1\else
      \if=#1\ifnum\language<0 \else \global\expandafter
               \chardef \csname p:>\currentlang/#2\endcsname =\language
            \fi
      \else 
         \if[#1\relax \setspecialpatterns #1#2
         \else \def\fotenc{#1#2}\loadpatternstable \currentlang\fotenc 
      \fi\fi
      \expandafter \loadpatternslist
   \fi
}
\def\setspecialpatterns [#1]=#2 {\language=\hyphentable[#1]
   \global \expandafter\chardef \csname p:>\currentlang/#2\endcsname =\language
}
\def\langlist{}

%%%% \setlang %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\setlang [#1/#2]{%
   \ifx\expandaction\noexpand
      \noexpand\setlang [#1/#2]%
   \else
      \csname fragilecommand!\endcsname
      \edef\newlang{#1}\edef\newenc{#2}%
      \ifx\newlang\empty \let\newlang=\currentlang \fi
      \ifx\newenc\empty  
          \ifx\langisused\undefined 
             \expandafter\let \expandafter\newenc \csname de:>\newlang\endcsname 
          \else 
             \let\newenc=\fotenc 
      \fi\fi
      \let\tmpa=\setlangA
      \ifx\newlang\currentlang \ifx\newenc\fotenc
          \ifx\langisused\undefined \else \let\tmpa=\ignorespaces \fi
      \fi\fi      
      \expandafter \ifx \csname l:>\newlang\endcsname \relax
          \langmessagewarn {Unknown language "\newlang". 
                        \noexpand\setlang ignored.}%
          \let\tmpa=\ignorespaces
      \fi
      \expandafter \tmpa
   \fi 
}
\def\setlangA {%
   \allowedenc \newlang/\newenc? \iftrue \else 
       \langmessagewarn {The "\newenc" encoding is not allowed in
                         language "\newlang".^^J 
                         \sssp Encoding reset to: 
                         "\csname de:>\newlang\endcsname"}%
       \edef\newenc{\csname de:>\newlang\endcsname}%
   \fi
   \ifx\newlang\langnone \else
      \ifx \newlang\currentlang
         \ifx \newenc\fotenc
         \else \language=\hyphentable[\newlang/\newenc]
         \fi
      \else \language=\hyphentable[\newlang/\newenc]
   \fi\fi      
   \ifx \newlang\currentlang \else
      \afterlangstack  \def\afterlangstack{}%
      \let\currentlang=\newlang
      \langmessage {The language "\currentlang" is selected.}%
      \ifx\currentlang\langnone \else   
         \expandafter \ofsinput \csname s:>\newlang \expandafter\endcsname\space
      \fi
      \currentdialect=0\relax
      \csname c:>langinit(\currentlang)\endcsname % silent \langinit
      \ignorespaces
   \fi
   \ifx \langisused\undefined \let\fotenc=\relax \fi
   \ifx \newenc\fotenc \else
      {\globaldefs=1 \lccodesback \let\lccodesback=\relax }%
      \ifx\ienc\udnefined \else 
         \ifx \langisused\undefined \else\unsetienc[\ienc/\fotenc]\relax \fi\fi
      \let\fotenc=\newenc  \let\langisused=\relax
      \global\let\gfotenc=\fotenc  \aftergroup\resetcodes
      \langmessage {Font encoding "\fotenc" is set.}%
      \ofsinput ofs-\fotenc.tex
      \ifx\ienc\undefined \else \setienc [\inec/\fotenc]\relax \fi
      {\globaldefs=1 \csname \fotenc:lccodes\endcsname }% commands from \modifyenc
      \expandafter \edef \csname de:>\currentlang\endcsname {\fotenc}%
      \expandafter\futurelet \expandafter\nextchar \expandafter\testfamily 
   \fi
}
\def\testfamily {%
   \ifx\nextchar\setfonts
       \expandafter \runsetfonts
   \else \setfonts[/]\relax \def\newfosize{}%
       \expandafter \testfontsOK
   \fi
}
\def\runsetfonts \setfonts [#1/#2]{\setfonts[#1/#2]\relax
   \def\newfosize{#2}\testfontsOK
}
\def\testfontsOK {%
   \ifx \setfontsOK\relax \else
      \langmessagewarn {The "\defaultfam" is used instead "\currentfamily".}%
      \setfonts [\defaultfam/\newfosize]\relax
   \fi \ignorespaces
}
\let\lccodesback=\relax

\def\resetcodes {%
   \ifx\langisused\undefined \setlang[/]\relax 
   \else
      \ifx\fotenc\gfotenc \else
         {\globaldefs=1 \lccodesback \let\lccodesback=\relax }%
         \ifx\ienc\udnefined \else 
             \unsetienc [\ienc/\gfotenc]\relax
             \setienc   [\ienc/\fotenc]\relax 
         \fi
         {\globaldefs=1 \csname \fotenc:lccodes\endcsname }%
         \global\let\gfotenc=\fotenc
   \fi\fi
} 

%%%% \afterlang %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\afterlangstack{}

\def\afterlang #1{%
   \ifx\expandaction\noexpand
      \noexpand\afterlang {#1}%
   \else
      \csname fragilecommand!\endcsname
      \def\tmpa{#1}%
      \expandafter\expandafter\expandafter \def 
      \expandafter\expandafter\expandafter \afterlangstack 
      \expandafter\expandafter\expandafter{%
         \expandafter \tmpa \afterlangstack}%
   \fi
}


%%%% \lccodes (used in ofs-*.tex files), %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\lccodes #1#2{\lccode`#1=`#1 \uccode`#1=`#2
   \lccode`#2=`#1 \uccode`#2=`#2
   \ifnum \catcode`#1=12 \catcode`#1=11 \fi
   \ifnum \catcode`#2=12 \catcode`#2=11 \fi
}
\newcount \uccodenum
\newcount \lccodenum

\def\lccodesloop #1#2#3{\lccodenum=`#1 \uccodenum=`#3
   \loop
      \lccode\lccodenum=\lccodenum \lccode\uccodenum=\lccodenum
      \uccode\lccodenum=\uccodenum \uccode\uccodenum=\uccodenum
      \ifnum \catcode\lccodenum=12 \catcode\lccodenum=11 \fi
      \ifnum \catcode\uccodenum=12 \catcode\uccodenum=11 \fi
      \ifnum\lccodenum < `#2% 
         \advance\lccodenum by1 \advance\uccodenum by1
         \repeat
}
\def\zerolccodes #1#2{\lccodenum=`#1
   \loop
      \lccode\lccodenum=0 \uccode\lccodenum=0
      \ifnum \catcode\lccodenum=11 \catcode\lccodenum=12 \fi
      \ifnum \catcode\uccodenum=11 \catcode\uccodenum=12 \fi      
      \ifnum\lccodenum < `#2% 
         \advance\lccodenum by1
         \repeat
}      
      

%%% \allowedenc %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\allowedenc #1/#2?#3{%
   \edef\tmpc{#1}%
   \ifx\tmpc\langnone
      \expandafter \ifx \csname a:>#2\endcsname \relax
         \def\tmpc{iffalse}%
      \else
         \def\tmpc{iftrue}%
      \fi
   \else
      \edef\act{\def\noexpand\tmpc ####1 #2 ####2^^X%
                {\def\noexpand\tmpc{####2}}}\act
      \edef\act{\noexpand\tmpc\space \csname l:>#1\endcsname\space #2 ^^X}\act
      \ifx\tmpc\empty
          \edef\act{\def\noexpand\tmpc ####1=#2 ####2^^X%
                {\def\noexpand\tmpc{####2}}}\act
          \edef\act{\noexpand\tmpc \csname l:>#1\endcsname =#2 ^^X}\act
          \ifx\tmpc\empty \def\tmpc{iffalse}%
          \else \def\tmpc{iftrue}\fi
      \else \def\tmpc{iftrue}%
   \fi\fi
   \csname \tmpc\endcsname
}

\def\langmessage #1{\wlog{\langmessageheader #1}}
\def\langmessagewarn #1{\immediate\write16 {\langmessageheader WARNING. #1}}
\def\sssp{ \space\space}
\def\langmessageheader{LANG (l.\the\inputlineno): }


%%% \langdef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\langdef {\futurelet\tmpa \langdefA}

\def\langdefA {\ifx\tmpa(\expandafter \langdefB
   \else \expandafter \langdefB 
         \expandafter(\expandafter\langdeflist\expandafter)%
   \fi
}
\def\langdefB (#1)#2{\savetokenname #2\tmpc
   \edef \tmpb{\noexpand\langcommand {\tmpc}}%
   \expandafter \ifx \csname\tmpc\endcsname \relax \let#2=\tmpb \fi
   \ifx #2\tmpb \else \langdefwarn #2\fi
   \edef\tmpb{#1 }%
   \expandafter \separefromlanglist \tmpb;% \def\tmpa{firstLANG} \def\tmpb{otherLANGS}
   \edef\tmpd{\tmpc(\tmpa)}%
   \afterassignment\langdefC
   \langdefprefix \expandafter \def \csname c:>\tmpd\endcsname   
}
\def\langdefC {%
   \ifx\tmpb\empty \let\langdefprefix=\relax
   \else \expandafter \separefromlanglist \tmpb;%
      \expandafter \let \csname c:>\tmpc(\tmpa)\expandafter\endcsname
                        \csname c:>\tmpd\endcsname
      \expandafter\langdefC
   \fi
}
\def\separefromlanglist #1 #2;{\def\tmpa{#1}\def\tmpb{#2}}

\def\langdefwarn #1{\langmessagewarn 
    {"\string#1" is defined already, \noexpand\langdef ignored.}}

\let\langdefprefix=\relax

\def\langcommand #1{\langprotect{\expandafter \noexpand\csname #1\endcsname}%
     {\runifdefined{c:>#1(\currentlang)}{}%
        {\runifdefined{c:>#1(*)}{}{\langcommandwarn{#1}}}}%
}
\def\runifdefined #1{\expandafter \ifx \csname #1\endcsname\relax
     \expandafter \expandtosecond % what to do if command is undefined
  \else 
     \csname #1\expandafter\expandafter\expandafter\endcsname
     \expandafter\expandtofirst % parameters of command
  \fi
}
\def\expandtofirst  #1#2{#1}
\def\expandtosecond #1#2{#2}

\def\langcommandwarn #1{%
   \csname fragilecommand!\endcsname
   \langmessagewarn {The \expandafter\noexpand \csname #1\endcsname
                     is undefined in language "\currentlang"}%
}

%%% \doublechardef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\doublechardef {\futurelet\tmpa \doublechardefA}

\def\doublechardefA {\ifx\tmpa(\expandafter \doublechardefB
   \else \expandafter \doublechardefB 
         \expandafter(\expandafter\langdeflist\expandafter)%
   \fi
}
\def\doublechardefB (#1)#2{\edef\tmpc{\string#2}% #2 = <char1>
   \edef\tmpb{#1 }%
   \futurelet  \tmpa \doublechardefC
}
\def\doublechardefC {\ifx\tmpa##%
      \expandafter \doublechardefD
   \else \expandafter \doublechardefE \fi
}
\def\doublechardefE #1{\edef\tmpc{\tmpc\ssstring#1}\doublechardefD} % <char2>

\def\doublechardefD {%
   \expandafter \separefromlanglist \tmpb;% \def\tmpa{firstLANG} \def\tmpb{otherLANGS}
   \edef\tmpd{\tmpc(\tmpa)}%
   \afterassignment\doublechardefF
   \langdefprefix \expandafter \def \csname d:>\tmpd\endcsname   
}
\def\doublechardefF {%
   \ifx\tmpb\empty \let\langdefprefix=\relax
   \else \expandafter \separefromlanglist \tmpb;%
      \expandafter \let \csname d:>\tmpc(\tmpa)\expandafter\endcsname
                        \csname d:>\tmpd\endcsname
      \expandafter\doublechardefF
   \fi
}
\def\expdoublechar {\langprotect \noexpand
  {\textormath \expdoublecharT \expdoublecharM}
}
\def\expdoublecharM #1{%
  \runifdefined {d:>\string#1\ssstring\mathchar(\currentlang)}{}%
    {\runifdefined {d:>\string#1\ssstring\mathchar(*)}{}{\expdoublecharT{#1}}}%
}
\def\expdoublecharT #1#2{%
  \runifdefined {d:>\string#1\ssstring#2(\currentlang)}{}%
    {\runifdefined{d:>\string#1(\currentlang)}{{#2}}%
      {\runifdefined{d:>\string#1\ssstring#2(*)}{}%
         {\runifdefined{d:>\string#1(*)}{{#2}}%
            {\string #1#2}}}}%
}
\def\ssdoublechar #1{%
  \ifx\expandaction\noexpand  \noexpand#1%
  \else \csname fragilecommand!\endcsname
        \def\tmpb{#1}%
        \def\tmpa{\futurelet\tmpa\ssdoublecharA}%
        \expandafter \tmpa
  \fi
}
\def\ssdoublecharA {\def\tmpc{}%
  \ifx \tmpa\spacetoken \def\tmpc {\space}\fi
  \ifx \tmpa\bgroup     \def\tmpc {\bgroup}\fi
  \ifx \tmpa\egroup     \def\tmpc {\egroup}\fi
  \ifmmode \let\tmpd=\expdoublecharM \else \let\tmpd=\expdoublecharT \fi
  \ifx \tmpc\empty \expandafter \expandafter \expandafter
                   \tmpd \expandafter \tmpb
  \else \def\tmpa{\let\tmpa= }%
        \afterassignment \ssdoublecharB
        \expandafter \tmpa
  \fi
}
\def\ssdoublecharB{\expandafter \expandafter \expandafter
  \tmpd \expandafter \tmpb \tmpc}

\def\ssstring#1{% space-sensitive string
  \ifx#1\mathchar XmX\else
  \ifx#1\bgroup \string{\else
  \ifx#1\egroup \string}\else
  \ifx#1\space  \space\else 
  \string#1\fi\fi\fi\fi
}
\edef\act{\let\noexpand\spacetoken= \space}\act

%%% \activedef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\activedef #1{\edef\tmpa{\the\uccode`\~}%
   \def\tmpb{#1}%
   \uccode`\~=`#1%
   \afterassignment \activedefA
   \uppercase{\def~}%
}
\def\activedefA{\uccode`\~=\tmpa\relax
   \catcode\expandafter`\tmpb=13\relax
}
\def\maybeactive #1#2{\def\tmpc{#1}%
   \ifnum\catcode`#2=13 \bgroup \uccode`~=`#2 
        \def\tmpd{\uppercase{\egroup\tmpc~}}%
   \else \def\tmpd{\tmpc#2}\fi
   \tmpd
}
\def\activecharwarn #1{\langmessagewarn {%
   The \string#1 character cannot be activated in "\currentlang".}}

%%% \setdialect %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcount\currentdialect \currentdialect=0

\def\setdialect [#1]{%
   \ifx\expandaction\noexpand
      \noexpand\setdialect[#1]%
   \else
      \csname fragilecommand!\endcsname
      \def\tmpc{}%
      \expandafter \ifx \csname c:>whichdialect(\currentlang)\endcsname \relax
          \if|#1|\else
             \langmessagewarn {No dialects defined in "\currentlang" language.}\fi
      \else
         \edef\tmpb{#1}%
         \chardef\tmpd=\currentdialect  \currentdialect=0
         \expandafter\expandafter \expandafter\setdialectA
   \fi\fi
   \ignorespaces
}
\def\setdialectA {%
   \edef\tmpa{\whichdialect}%
   \ifx\tmpa\empty
      \ifx\tmpb\empty % list of dialects is in \tmpc
      \else
         \langmessagewarn {Dialect "\tmpb" is unavailable in "\currentlang".}\fi
      \currentdialect=\tmpd
   \else 
      \ifx\tmpa\tmpb % dialect is found
      \else 
          \edef\tmpc{\tmpc\ifx\tmpc\empty\else\space\fi\tmpa}%
          \advance\currentdialect by1
          \expandafter\expandafter\expandafter \setdialectA
   \fi\fi
}
\langdef (*) \whichdialect {none}


%%% \langprotect, \textormath %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\langprotect {\ifx\expandaction\noexpand
   \expandafter \expandtofirst \else \expandafter \expandtosecond \fi
}
\def\textormath {\ifmmode 
   \expandafter\expandtosecond \else \expandafter\expandtofirst \fi}

%%% \inputonce, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\inputonce #1 {\expandafter \ifx \csname f:>#1\endcsname \relax
   \input #1
   \expandafter \def \csname f:>#1\endcsname {}\fi
}

%%% \printlangdoc %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\printlangdoc {\ifx\currentlang\langnone
     \langmessagewarn {There is no documentation for "none" language.}
  \else
     \par
     \plaincatcodes
     \inputonce l-doc.tex
     \catcode`<=13 \catcode`"=13
     \immediate\write16 {\langmessageheader 
         The documentation of "\currentlang" language is printed.}
     \edef\tmpa {\noexpand \english
         \noexpand\langdocinput \csname s:>\currentlang \endcsname\space}%
     \tmpa
  \fi
}
\def\langdocinput #1 {\long\def\tmpa##1\langdocbegin{}%
  \expandafter \tmpa \input #1 }


%%% defaults %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\input langdef.tex

\def\langnone    {none}  \let\currentlang=\langnone
\def\langdeflist {null}
\def\fotenc{8t}
\expandafter\let \csname de:>\langnone\endcsname = \fotenc
\expandafter\def \csname l:>\langnone\endcsname {}%

\endinput









