font-sty.mkvi /size: 15 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=font-sty,
3%D        version=2011.01.13, % (copied fron font-ini)
4%D          title=\CONTEXT\ Font Macros,
5%D       subtitle=Styles,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Font Macros / Styles}
15
16\unprotect
17
18%D \macros
19%D   {definealternativestyle}
20%D
21%D In the main modules we are going to implement lots of parameterized commands and
22%D one of these parameters will concern the font to use. To suit consistent use of
23%D fonts we here implement a mechanism for defining the keywords that present a
24%D particular style or alternative.
25%D
26%D \starttyping
27%D \definealternativestyle [keywords] [\style] [\nostyle]
28%D \stoptyping
29%D
30%D The first command is used in the normal textflow, while the second command takes
31%D care of headings and alike. Consider the next two definitions:
32%D
33%D \starttyping
34%D \definealternativestyle [bold] [\bf]  []
35%D \definealternativestyle [cap]  [\cap] [\cap]
36%D \stoptyping
37%D
38%D A change \type {\bf} in a heading which is to be set in \type {\tfd} does not look
39%D that well, so therefore we leave the second argument of \type
40%D {\definealternativestyle} empty. When we capatalize characters using the pseudo
41%D small cap command \type {\cap}, we want this to take effect in both text and
42%D headings, which is accomplished by assigning both arguments.
43
44\installcorenamespace{alternativestyles}  % settings
45\installcorenamespace{alternativestyle}   % instances
46
47\installsetuponlycommandhandler \??alternativestyles {alternativestyles}
48
49\setnewconstant \c_font_current_alternative_style_index \plusone
50
51\unexpanded\def\definealternativestyle
52  {\dotripleempty\font_basics_define_alternative_style}
53
54\def\font_basics_define_alternative_style[#commands][#variantone][#varianttwo]%
55  {\processcommalist[#commands]{\font_basics_define_alternative_style_indeed{#variantone}{#varianttwo}}}
56
57\let\definestyle\definealternativestyle % later redefined
58
59\newconstant\c_fonts_basics_alternative_style_method
60
61\def\font_basics_define_alternative_style_indeed#variantone#varianttwo#command%
62  {\setuvalue{\??alternativestyle#command}{\font_helpers_apply_alternative_style{#variantone}{#varianttwo}}%
63   \ifcsname#command\endcsname
64     % no redefinition
65   \else\ifnum\c_fonts_basics_alternative_style_method=\plusone
66      \ifthirdargument
67        \setuevalue{#command}{\triggergroupedcommandcs\begincsname\??alternativestyle#command\endcsname}%
68      \else
69        \setuvalue{#command}{\triggergroupedcommand{#variantone}}%
70      \fi
71   \else
72     \setuvalue{#command}{\triggergroupedcommand{#variantone}}%
73   \fi\fi}
74
75\def\font_helpers_apply_alternative_style
76  {\ifcase\c_font_current_alternative_style_index
77     \expandafter\gobbletwoarguments
78   \or
79     \expandafter\firstoftwoarguments
80   \or
81     \expandafter\secondoftwoarguments
82   \else
83     \expandafter\firstoftwoarguments
84   \fi}
85
86\def\applyalternativestyle#name% public
87  {\begincsname\??alternativestyle#name\endcsname}
88
89\appendtoks
90    \doifelse{\alternativestylesparameter\c!method}\v!auto
91      {\c_fonts_basics_alternative_style_method\plusone}%
92      {\c_fonts_basics_alternative_style_method\zerocount}%
93\to \everysetupalternativestyles
94
95%D Maybe too generic, but probably ok is the following. (Maybe one day we will use a
96%D dedicated grouped command for styles.)
97
98% \appendtoks
99%     \let\groupedcommand\thirdofthreearguments
100% \to \everysimplifycommands
101
102%D This command also defines the keyword as command. This means that the example
103%D definition of \type {bold} we gave before, results in a command \type {\bold}
104%D which can be used as:
105%D
106%D \startbuffer
107%D He's a \bold{bold} man with a {\bold head}.
108%D \stopbuffer
109%D
110%D \typebuffer
111%D
112%D or
113%D
114%D \startexample
115%D \definealternativestyle[bold][\bf][]\getbuffer
116%D \stopexample
117%D
118%D Such definitions are of course unwanted for \type {\cap} because this would
119%D result in an endless recursive call. Therefore we check on the existance of both
120%D the command and the substitution. The latter is needed because for instance \type
121%D {\type} is an entirely diferent command. That command handles verbatim, while the
122%D style command would just switch to teletype font. This is just an example of a
123%D tricky naming coincidence.
124%D
125%D \macros
126%D   {doconvertfont,noconvertfont,
127%D    dontconvertfont,redoconvertfont}
128%D
129%D After having defined such keywords, we can call for them by using
130%D
131%D \starttyping
132%D \doconvertfont{keyword}{text}
133%D \stoptyping
134%D
135%D We deliberately pass an argument. This enables us to assign converters that
136%D handle one argument, like \type {\cap}.
137%D
138%D By default the first specification is used to set the style, exept when we say
139%D \type {\dontconvertfont}, after which the second specification is used. We can
140%D also directly call for \type {\noconvertfont}. In nested calls, we can restore
141%D the conversion by saying \type {\redoconvertfont}.
142%D
143%D These commands are not grouped! Grouping is most probably done by the calling
144%D macro's and would lead to unnecessary overhead.
145
146\let\m_current_convert_font   \empty
147\let\m_current_convert_font_dt\empty
148
149\unexpanded\def\doconvertfont#specification% takes second argument / this command is obsolete
150  {\edef\m_current_convert_font{#specification}%
151   \ifx\m_current_convert_font\empty
152    %\expandafter\firstofoneargument
153   \else
154     \expandafter\font_helpers_do_convert_font
155   \fi}
156
157\def\font_helpers_do_convert_font
158  {\edef\m_current_convert_font_dt{\detokenize\expandafter{\m_current_convert_font}}%
159   \ifcsname\??alternativestyle\m_current_convert_font_dt\endcsname
160     \expandafter\lastnamedcs
161   \else\ifcsname\m_current_convert_font_dt\endcsname
162     \doubleexpandafter\lastnamedcs
163   \else
164     \doubleexpandafter\m_current_convert_font
165   \fi\fi}
166
167%D Low level switches (downward compatible, but we keep them as one can use them in
168%D styles):
169%D
170%D \starttyping
171%D \usemodule[abr-02]
172%D \setuphead[chapter][style=\bfb]
173%D \setupfooter[style=\dontconvertfont\bf]
174%D \chapter{This is \TEX}
175%D \stoptyping
176
177\unexpanded\def\dontconvertfont{\c_font_current_alternative_style_index\plustwo} % needs checking in usage
178\unexpanded\def\redoconvertfont{\c_font_current_alternative_style_index\plusone} % needs checking in usage
179
180%D The new one:
181
182\setfalse\fontattributeisset
183
184\let\currentstyleparameter           \empty % these might become private
185\let\currentdetokenizedstyleparameter\empty % these might become private
186
187\unexpanded\def\dousestyleparameter#value%
188  {\edef\currentstyleparameter{#value}%
189   \ifx\currentstyleparameter\empty\else
190     \expandafter\dousecurrentstyleparameter
191   \fi}
192
193\unexpanded\def\dousestylehashparameter#hash#parameter%
194  {\ifcsname#hash#parameter\endcsname
195     \expandafter\dousestyleparameter\lastnamedcs
196   \fi}
197
198\unexpanded\def\dousecurrentstyleparameter % empty check outside here
199  {\edef\currentdetokenizedstyleparameter{\detokenize\expandafter{\currentstyleparameter}}%
200   \settrue\fontattributeisset % reset is done elsewhere
201   \ifcsname\??alternativestyle\currentdetokenizedstyleparameter\endcsname
202     \lastnamedcs
203   \else\ifcsname\currentdetokenizedstyleparameter\endcsname
204     \lastnamedcs
205   \else
206     \currentstyleparameter
207   \fi\fi}
208
209\let\dosetfontattribute\dousestylehashparameter % for a while
210
211%D New commands (not yet interfaced):
212%D
213%D \startbuffer
214%D \definestyle[one][style=bold,color=darkblue]
215%D
216%D test \one{test} test
217%D test \style[one]{test} test
218%D test \style[color=red]{test} test
219%D test \style[Serif at 20pt]{test} test
220%D \stopbuffer
221%D
222%D \typebuffer \startlines \getbuffer \stoplines
223
224% definitions .. no tagging here
225
226\installcorenamespace{style}
227\installcorenamespace{stylecheck}
228\installcorenamespace{stylehack}
229
230\installcommandhandler \??style {style} \??style
231
232\setupstyle
233  [%\c!style=,
234   %\c!color=,
235   \c!method=\v!command]
236
237\appendtoks
238    \letvalue{\??stylecheck\currentstyle}\relax
239    \edef\p_method{\styleparameter\c!method}%
240    \ifx\p_method\v!command
241        \setuevalue{\e!start\currentstyle}{\font_styles_apply_start{\currentstyle}}%
242        \setuevalue{\e!stop \currentstyle}{\font_styles_apply_stop}%
243        \setuevalue        {\currentstyle}{\font_styles_apply_grouped{\currentstyle}}% no longer groupedcommand here
244    \fi
245\to \everydefinestyle
246
247\unexpanded\def\font_styles_apply_start#name%
248  {\begingroup
249   \font_styles_use_defined{#name}}
250
251\unexpanded\def\font_styles_apply_stop
252  {\endgroup}
253
254\unexpanded\def\font_styles_apply_grouped#name% assumes that the next is { or \bgroup
255  {\bgroup
256   \def\g_style{\font_styles_use_defined{#name}}%
257   \afterassignment\g_style
258   \let\nexttoken}
259
260\unexpanded\def\font_styles_use_defined#name%
261  {\edef\currentstyle{#name}%
262   \usestylestyleandcolor\c!style\c!color}
263
264\unexpanded\def\font_styles_use_generic#specification%
265  {\let\currentstyle\s!unknown % reasonable generic tag
266   \letstyleparameter\c!style\empty
267   \letstyleparameter\c!color\empty
268   \setupcurrentstyle[#specification]%
269   \usestylestyleandcolor\c!style\c!color}
270
271% commands
272
273\installcorenamespace{styleargument}
274
275\unexpanded\def\style[#name]% as this is can be a switch we use groupedcommand
276  {\csname\??styleargument
277     \ifcsname\??stylecheck#name\endcsname
278       2% defined as style
279     \else\ifcsname\??stylehack#name\endcsname
280       4% defined as command
281     \else\ifcsname#name\endcsname
282       1% defined as command
283     \else
284       3% specification
285     \fi\fi\fi
286   \endcsname{#name}}
287
288% \setvalue{\??styleargument1}#name%
289%   {\groupedcommand{\begincsname#name\endcsname}{}}
290
291\setvalue{\??styleargument1}#name%
292  {\expandafter\triggergroupedcommandcs\begincsname#name\endcsname}
293
294% \setvalue{\??styleargument2}#name%
295%   {\groupedcommand{\font_styles_use_defined{#name}}{}} % or {\font_styles_apply_grouped{#name}}
296
297\setvalue{\??styleargument2}#name%
298  {\triggergroupedcommand{\font_styles_use_defined{#name}}} % or {\font_styles_apply_grouped{#name}}
299
300\setvalue{\??styleargument3}#specification%
301  {\doifelseassignment{#specification}\font_styles_assignment\font_styles_direct{#specification}}
302
303\setvalue{\??styleargument4}#name%
304  {\expandafter\triggergroupedcommandcs\begincsname\??stylehack#name\endcsname}
305
306\setvalue{\??stylehack\s!math}% dirty trick
307  {\groupedcommand\normalstartimath\normalstopimath}
308
309% \def\font_styles_assignment#specification{\groupedcommand{\font_styles_use_generic{#specification}}{}}
310% \def\font_styles_direct    #specification{\groupedcommand{\definedfont[#specification]}{}}
311
312\def\font_styles_assignment#specification{\triggergroupedcommand{\font_styles_use_generic{#specification}}}
313\def\font_styles_direct    #specification{\triggergroupedcommand{\definedfont[#specification]}}
314
315% environments
316
317\installcorenamespace{styleenvironment}
318
319\unexpanded\def\startstyle[#name]%
320  {\begingroup
321   \csname\??styleenvironment
322     \ifcsname\??stylecheck#name\endcsname
323       2% defined as style
324     \else\ifcsname#name\endcsname
325       1% defined as command
326     \else
327       3% specification
328     \fi\fi
329   \endcsname{#name}}
330
331\unexpanded\def\stopstyle
332  {\endgroup
333   \autoinsertnextspace} % will be configurable, maybe also in \definestartstop
334
335\setvalue{\??styleenvironment1}#name%
336  {\csname#name\endcsname}
337
338\setvalue{\??styleenvironment2}#name%
339  {\font_styles_use_defined{#name}}
340
341\setvalue{\??styleenvironment3}#specification%
342  {\doifelseassignment{#specification}\font_styles_start_assignment\font_styles_start_direct{#specification}}
343
344\def\font_styles_start_assignment#specification{\font_styles_use_generic{#specification}}
345\def\font_styles_start_direct    #specification{\definedfont[#specification]\relax}
346
347%D Still experimental (might even go away).
348
349% \definestylecollection[mine]
350
351% \definestyleinstance[mine][default][sorry]
352% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
353% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
354% \definestyleinstance[mine][bf][\sl]
355% \definestyleinstance[mine][sl][\tt]
356
357% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}
358
359\installcorenamespace{stylecollection}
360
361\unexpanded\def\definestylecollection
362  {\dosingleargument\font_styles_define_style_collection}
363
364\def\font_styles_define_style_collection[#name]%
365  {\iffirstargument
366     \setuvalue{#name}{\styleinstance[#name]}%
367     \def\font_styles_define_style_collection_a#style%
368       {\def\font_styles_define_style_collection_b#alternative{\undefinevalue{\??stylecollection#name:#style:#alternative}}%
369        \font_helpers_process_alternative_list\font_styles_define_style_collection_b
370        \font_styles_define_style_collection_b\s!default}%
371     \font_helpers_process_style_list\font_styles_define_style_collection_a
372     \font_styles_define_style_collection_a\s!default
373  \fi}
374
375\let\font_styles_define_style_collection_a\relax
376\let\font_styles_define_style_collection_b\relax
377
378\unexpanded\def\definestyleinstance
379  {\doquadrupleargument\font_styles_define_style_instance}
380
381\def\font_styles_define_style_instance[#instance][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
382  {\iffirstargument
383     \ifcsname#instance\endcsname\else\font_styles_define_style_collection[#instance]\fi
384   \fi
385   \iffourthargument
386     \setvalue{\??stylecollection#instance:#2:#3}{#4}%
387   \else\ifthirdargument
388     \setvalue{\??stylecollection#instance::#2}{#3}%
389   \else\ifsecondargument
390     \letvalueempty{\??stylecollection#instance::#2}%
391   \fi\fi\fi}
392
393% \unexpanded\def\styleinstance[#instance]% will be made faster
394%   {%\begingroup\normalexpanded{\noexpand\infofont[#1:\fontstyle:\fontalternative]}\endgroup
395%    \executeifdefined{\??stylecollection#instance:\fontstyle:\fontalternative}%
396%   {\executeifdefined{\??stylecollection#instance:\fontstyle:\s!default}%
397%   {\executeifdefined{\??stylecollection#instance::\fontalternative}
398%   {\getvalue        {\??stylecollection#instance::\s!default}}}}}
399
400\unexpanded\def\styleinstance[#instance]% maybe \lastnamedcs here too
401  {\csname\??stylecollection#instance:%
402     \ifcsname\??stylecollection#instance:\fontstyle:\fontalternative\endcsname
403       \fontstyle:\fontalternative
404     \else\ifcsname\??stylecollection#instance:\fontstyle:\s!default\endcsname
405       \fontstyle:\s!default
406     \else\ifcsname\??stylecollection#instance::\fontalternative\endcsname
407       :\fontalternative
408     \else
409       :\s!default
410     \fi\fi\fi
411   \endcsname}
412
413%D Variant selectors
414%D
415%D \starttyping
416%D \mathematics {\vsone{\utfchar{0x2229}}}
417%D \mathematics {\utfchar{0x2229}\vsone{}}
418%D \stoptyping
419
420\unexpanded\edef\vsone#character{#character\normalUchar"FE00 } % used
421\unexpanded\edef\vstwo#character{#character\normalUchar"FE01 } % not used but handy for testing
422
423%D For historic reasons we keep the following around but they are no longer that
424%D relevant for \MKIV.
425
426\unexpanded\def\doattributes#1#2#3#4%
427  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
428   \dousestylehashparameter{#1}{#2}%
429   \dousecolorhashparameter{#1}{#3}%
430   #4%
431   \endgroup}
432
433\unexpanded\def\dostartattributes#1#2#3%
434  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
435   \dousestylehashparameter{#1}{#2}%
436   \dousecolorhashparameter{#1}{#3}}
437
438\let\dostopattributes\endgroup
439
440%D New but it needs to be supported explicitly (as in natural tables).
441
442\newconditional\c_font_styles_math
443
444\unexpanded\def\font_styles_math_reset
445  {\setfalse\c_font_styles_math}
446
447\unexpanded\def\font_styles_math_start
448  {\ifconditional\c_font_styles_math
449     \startimath
450   \fi
451   \relax}
452
453\unexpanded\def\font_styles_math_stop
454  {\relax
455   \ifconditional\c_font_styles_math
456     \stopimath
457   \fi}
458
459\definealternativestyle[\v!math][\settrue\c_font_styles_math]
460
461\protect \endinput
462