summaryrefslogtreecommitdiff
path: root/tex/context/base/mkii/lang-spe.mkii
blob: 11c57af3f2347d65b1941acf894f08b1c937c7ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
%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 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 code was originally placed in the language
%D initialization module, but isolating it is clearer. Language
%D specifics evolved out of user demands for special features,
%D like the german active quote. After a while I decided to
%D associate them to languages in a more general way so that we
%D could associate all kind of things with language switching.
%D
%D This is a typical example of functionality that occasionally
%D gets improved based on user input and experience. Much of the
%D code is pretty old and could probabbly be done in better ways.
%D It's probably also the kind of code that has been and will be
%D written over and over again by \TEX\ users around the world,
%D so there are probably better implementations of similar
%D functionality around. Therefore, users are invited to pop in
%D their own handling as long as it does not interfere with
%D existing code. Writing the more obscure macros that deal with
%D this is a good learning experience (catcodes, lccodes, token
%D lists, expansion, \unknown).

\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 \starttyping
%D \startlanguagespecifics[de]
%D   \installcompoundcharacter "a {\"a}
%D   \installcompoundcharacter "e {\"e}
%D   \installcompoundcharacter "s {\SS}
%D \stoplanguagespecifics
%D \stoptyping
%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.

% We should use token registers, but alas, we run out of them and
% \ETEX\ has a bug. Well, let's use a token register now (2006).

\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
   \processcommalist[#1]{\dosetlanguagespecifics{#3}}}

% \long\def\dosetlanguagespecifics#1#2%
%   {\ifundefined{\??la\languageencoding#2\??la}\forgetlanguagespecifics[#2]\fi
%    % the next line catches the case that specifics are enabled *before* they are defined
%    \expandafter\ifx\csname\??la\languageencoding#2\??la\endcsname\relax\forgetlanguagespecifics[#2]\fi
%    \appendvalue{\??la\languageencoding#2\??la}{#1}%
%    \bgroup
%    \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}%
%    \ifdim\wd\scratchbox>\zeropoint
%      \showmessage\m!linguals7{\currentencoding-#2,\the\wd\scratchbox\space}\wait
%    \else
%      \showmessage\m!linguals8{\currentencoding-#2}%
%    \fi
%    \egroup
%    \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}}

\def\languagespectag#1{\??la\languageencoding#1\??la}

\long\def\dosetlanguagespecifics#1#2%
  {\edef\askedlanguagespecificstag{\languagespectag{#2}}%
   \ifcsname\askedlanguagespecificstag\endcsname \else
      \expandafter\newtoks\csname\askedlanguagespecificstag\endcsname
   \fi
   \csname\askedlanguagespecificstag\endcsname\@EA{\the\csname\askedlanguagespecificstag\endcsname#1}%
   \bgroup
   \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}%
   \ifdim\wd\scratchbox>\zeropoint
     \showmessage\m!linguals7{\currentencoding-#2,\the\wd\scratchbox\space}\wait
   \else
     \showmessage\m!linguals8{\currentencoding-#2}%
   \fi
   \egroup
   \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}}

\def\forgetlanguagespecifics[#1]%
  {\csname\languagespectag{#1}\endcsname\emptytoks}

%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]%
%   {\the\executeifdefined{\??la
%      \@EA\ifx\csname\??la#1\c!default\endcsname\relax
%        \languageencoding
%      \else
%        \csname\??la#1\c!default\endcsname
%      \fi
%      \??la}\emptytoks
%    \the\executeifdefined{\??la#1\??la}\emptytoks
%    \the\executeifdefined{\??la\languageencoding#1\??la}\emptytoks} % dup ?

\def\enablelanguagespecifics[#1]%
  {\edef\askedlanguagespecificslanguage{\defaultlanguage{#1}}%
   \ifcsname\??la\askedlanguagespecificslanguage\??la\endcsname
     \the\csname\??la\askedlanguagespecificslanguage\??la\endcsname
   \fi
   \ifx\languageencoding\empty\else
     \ifcsname\??la\languageencoding\askedlanguagespecificslanguage\??la\endcsname
       \the\csname\??la\languageencoding\askedlanguagespecificslanguage\??la\endcsname
     \fi
   \fi}

%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% test 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

% yes or no (taco wins: no)

% \startlanguagespecifics[nl,cs,sk,fr]
%   \lccode`\'=`\'
% \stoplanguagespecifics

%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.

\ifx\high          \undefined \let\high          \firstofoneargument \fi % todo
\ifx\notsmallcapped\undefined \let\notsmallcapped\firstofoneargument \fi % todo

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

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

%D Language specific converters have definitions like:
%D
%D \starttyping
%D \def\enordinaldaynumber#1{...}
%D \stoptyping
%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