font-sty.mklx /size: 14 Kb    last modification: 2024-01-16 09:02
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\permanent\tolerant\protected\def\definealternativestyle[#commands]#spacer[#variantone]#spacer[#varianttwo]%
52  {\processcommalist[#commands]{\font_basics_define_alternative_style_indeed{#variantone}{#varianttwo}}}
53
54% \let\definestyle\definealternativestyle % later redefined
55
56\newconstant\c_fonts_basics_alternative_style_method
57
58% maybe permanent
59
60\def\font_basics_define_alternative_style_indeed#variantone#varianttwo#command%
61  {\protected\defcsname\??alternativestyle#command\endcsname{\font_helpers_apply_alternative_style{#variantone}{#varianttwo}}%
62   \ifcsname#command\endcsname
63     % no redefinition
64   \orelse\ifnum\c_fonts_basics_alternative_style_method=\plusone
65      \ifparameter#command\or
66        \permanent\protected\edefcsname#command\endcsname{\triggergroupedcommandcs\begincsname\??alternativestyle#command\endcsname}%
67      \else
68        \permanent\protected\defcsname#command\endcsname{\triggergroupedcommand{#variantone}}%
69      \fi
70   \else
71     \permanent\protected\defcsname#command\endcsname{\triggergroupedcommand{#variantone}}%
72   \fi}
73
74\def\font_helpers_apply_alternative_style
75  {\ifcase\c_font_current_alternative_style_index
76     \expandafter\gobbletwoarguments
77   \or
78     \expandafter\firstoftwoarguments
79   \or
80     \expandafter\secondoftwoarguments
81   \else
82     \expandafter\firstoftwoarguments
83   \fi}
84
85\permanent\def\applyalternativestyle#name% public .. expandable? frozen?
86  {\begincsname\??alternativestyle#name\endcsname}
87
88\appendtoks
89    \c_fonts_basics_alternative_style_method
90      \ifcstok{\alternativestylesparameter\c!method}\v!auto
91        \plusone
92      \else
93        \zerocount
94      \fi
95\to \everysetupalternativestyles
96
97%D Maybe too generic, but probably ok is the following. (Maybe one day we will use a
98%D dedicated grouped command for styles.)
99
100% \appendtoks
101%     \let\groupedcommand\thirdofthreearguments
102% \to \everysimplifycommands
103
104%D This command also defines the keyword as command. This means that the example
105%D definition of \type {bold} we gave before, results in a command \type {\bold}
106%D which can be used as:
107%D
108%D \startbuffer
109%D He's a \bold{bold} man with a {\bold head}.
110%D \stopbuffer
111%D
112%D \typebuffer
113%D
114%D or
115%D
116%D \startexample
117%D \definealternativestyle[bold][\bf][]\getbuffer
118%D \stopexample
119%D
120%D Such definitions are of course unwanted for \type {\cap} because this would
121%D result in an endless recursive call. Therefore we check on the existance of both
122%D the command and the substitution. The latter is needed because for instance \type
123%D {\type} is an entirely diferent command. That command handles verbatim, while the
124%D style command would just switch to teletype font. This is just an example of a
125%D tricky naming coincidence.
126%D
127%D \macros
128%D   {doconvertfont,noconvertfont,
129%D    dontconvertfont,redoconvertfont}
130%D
131%D After having defined such keywords, we can call for them by using
132%D
133%D \starttyping
134%D \doconvertfont{keyword}{text}
135%D \stoptyping
136%D
137%D We deliberately pass an argument. This enables us to assign converters that
138%D handle one argument, like \type {\cap}.
139%D
140%D By default the first specification is used to set the style, exept when we say
141%D \type {\dontconvertfont}, after which the second specification is used. We can
142%D also directly call for \type {\noconvertfont}. In nested calls, we can restore
143%D the conversion by saying \type {\redoconvertfont}.
144%D
145%D These commands are not grouped! Grouping is most probably done by the calling
146%D macro's and would lead to unnecessary overhead.
147
148\lettonothing\m_current_convert_font
149\lettonothing\m_current_convert_font_dt
150
151\permanent\protected\def\doconvertfont#specification% takes second argument / this command is obsolete
152  {\edef\m_current_convert_font{#specification}%
153   \ifempty\m_current_convert_font
154    %\expandafter\firstofoneargument
155   \else
156     \expandafter\font_helpers_do_convert_font
157   \fi}
158
159\def\font_helpers_do_convert_font
160  {\edef\m_current_convert_font_dt{\detokenize\expandafter{\m_current_convert_font}}%
161   \ifcsname\??alternativestyle\m_current_convert_font_dt\endcsname
162     \expandafter\lastnamedcs
163   \orelse\ifcsname\m_current_convert_font_dt\endcsname
164     \expandafter\lastnamedcs
165   \else
166     \expandafter\m_current_convert_font
167   \fi}
168
169%D Low level switches (downward compatible, but we keep them as one can use them in
170%D styles):
171%D
172%D \starttyping
173%D \usemodule[abr-02]
174%D \setuphead[chapter][style=\bfb]
175%D \setupfooter[style=\dontconvertfont\bf]
176%D \chapter{This is \TEX}
177%D \stoptyping
178
179\permanent\protected\def\dontconvertfont{\c_font_current_alternative_style_index\plustwo} % needs checking in usage
180\permanent\protected\def\redoconvertfont{\c_font_current_alternative_style_index\plusone} % needs checking in usage
181
182%D The new one:
183
184\newconditional\fontattributeisset
185
186\mutable\lettonothing\currentdetokenizedstyleparameter
187
188\permanent\protected\def\dousestyleparameter#value%
189  {\cdef\currentstyleparameter{#value}%
190   \ifempty\currentstyleparameter\else
191     \expandafter\dousecurrentstyleparameter
192   \fi}
193
194\permanent\protected\def\dousestylehashparameter#hash#parameter%
195  {\ifcsname#hash#parameter\endcsname
196     \expandafter\dousestyleparameter\lastnamedcs
197   \fi}
198
199\permanent\protected\def\dousecurrentstyleparameter % empty check outside here
200  {\cdef\currentdetokenizedstyleparameter{\detokenize\expandafter{\currentstyleparameter}}%
201   \fontattributeisset\conditionaltrue % reset is done elsewhere
202   \ifcsname\??alternativestyle\currentdetokenizedstyleparameter\endcsname
203     \lastnamedcs
204   \orelse\ifcsname\currentdetokenizedstyleparameter\endcsname
205     \lastnamedcs
206   \else
207     \currentstyleparameter
208   \fi}
209
210%D New commands (not yet interfaced):
211%D
212%D \startbuffer
213%D \definestyle[one][style=bold,color=darkblue]
214%D
215%D test \one{test} test
216%D test \style[one]{test} test
217%D test \style[color=red]{test} test
218%D test \style[Serif at 20pt]{test} test
219%D \stopbuffer
220%D
221%D \typebuffer \startlines \getbuffer \stoplines
222
223% definitions .. no tagging here
224
225\installcorenamespace{style}
226\installcorenamespace{stylecheck}
227\installcorenamespace{stylehack}
228
229\installcommandhandler \??style {style} \??style
230
231\setupstyle
232  [%\c!style=,
233   %\c!color=,
234   \c!method=\v!command]
235
236\appendtoks
237    \letcsname\??stylecheck\currentstyle\endcsname\relax
238    \ifcstok{\styleparameter\c!method}\v!command
239        \frozen\instance\protected\edefcsname\e!start\currentstyle\endcsname{\font_styles_apply_start{\currentstyle}}%
240        \frozen\instance\protected\edefcsname\e!stop \currentstyle\endcsname{\font_styles_apply_stop}%
241        \frozen\instance\protected\edefcsname        \currentstyle\endcsname{\font_styles_apply_grouped{\currentstyle}}% no longer groupedcommand here
242    \fi
243\to \everydefinestyle
244
245\protected\def\font_styles_apply_start#name%
246  {\begingroup
247   \font_styles_use_defined{#name}}
248
249\protected\def\font_styles_apply_stop
250  {\endgroup}
251
252\protected\def\font_styles_apply_grouped#name% assumes that the next is { or \bgroup
253  {\bgroup % \beginsimplegroup
254   \cdef\currentstyle{\font_styles_use_defined{#name}}%
255   \afterassignment\currentstyle
256   \let\nexttoken}
257
258\protected\def\font_styles_use_defined#name%
259  {\cdef\currentstyle{#name}%
260   \usestylestyleandcolor\c!style\c!color}
261
262\protected\def\font_styles_use_generic#specification%
263  {\let\currentstyle\s!unknown % reasonable generic tag
264   \resetstyleparameter\c!style
265   \resetstyleparameter\c!color
266   \setupcurrentstyle[#specification]%
267   \usestylestyleandcolor\c!style\c!color}
268
269% commands
270
271\installcorenamespace{styleargument}
272
273\permanent\protected\def\style[#name]% as this is can be a switch we use groupedcommand % frozen?
274  {\csname\??styleargument
275     \ifcsname\??stylecheck#name\endcsname
276       2% defined as style
277     \orelse\ifcsname\??stylehack#name\endcsname
278       4% defined as command
279     \orelse\ifcsname#name\endcsname
280       1% defined as command
281     \else
282       3% specification
283     \fi
284   \endcsname{#name}}
285
286\defcsname\??styleargument1\endcsname#name%
287  {\expandafter\triggergroupedcommandcs\begincsname#name\endcsname}
288
289\defcsname\??styleargument2\endcsname#name%
290  {\triggergroupedcommand{\font_styles_use_defined{#name}}} % or {\font_styles_apply_grouped{#name}}
291
292\defcsname\??styleargument3\endcsname#specification%
293  {\doifelseassignment{#specification}\font_styles_assignment\font_styles_direct{#specification}}
294
295\defcsname\??styleargument4\endcsname#name%
296  {\expandafter\triggergroupedcommandcs\begincsname\??stylehack#name\endcsname}
297
298\defcsname\??stylehack\s!math\endcsname% dirty trick
299  {\groupedcommandcs\normalstartimath\normalstopimath}
300
301\def\font_styles_assignment#specification{\triggergroupedcommand{\font_styles_use_generic{#specification}}}
302\def\font_styles_direct    #specification{\triggergroupedcommand{\definedfont[#specification]}}
303
304% environments
305
306\installcorenamespace{styleenvironment}
307
308\permanent\protected\def\startstyle[#name]%
309  {\begingroup
310   \csname\??styleenvironment
311     \ifcsname\??stylecheck#name\endcsname
312       2% defined as style
313     \orelse\ifcsname#name\endcsname
314       1% defined as command
315     \else
316       3% specification
317     \fi
318   \endcsname{#name}}
319
320\permanent\protected\def\stopstyle
321  {\endgroup
322   \autoinsertnextspace} % will be configurable, maybe also in \definestartstop
323
324\defcsname\??styleenvironment1\endcsname#name%
325  {\csname#name\endcsname}
326
327\defcsname\??styleenvironment2\endcsname#name%
328  {\font_styles_use_defined{#name}}
329
330\defcsname\??styleenvironment3\endcsname#specification%
331  {\doifelseassignment{#specification}\font_styles_start_assignment\font_styles_start_direct{#specification}}
332
333\def\font_styles_start_assignment#specification{\font_styles_use_generic{#specification}}
334\def\font_styles_start_direct    #specification{\definedfont[#specification]\relax}
335
336%D Still experimental (might even go away).
337
338% \definestylecollection[mine]
339
340% \definestyleinstance[mine][default][sorry]
341% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
342% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
343% \definestyleinstance[mine][bf][\sl]
344% \definestyleinstance[mine][sl][\tt]
345
346% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}
347
348% too messy for this:
349%
350% \definestylecollection[mine]
351% \definestyleinstance[mine][tt][tf][\nohyphencollapsing]
352% {\tt\mine test--test \bf test--test}
353
354\installcorenamespace{stylecollection}
355
356\permanent\tolerant\protected\def\definestylecollection[#name]%
357  {\ifarguments\or
358     \protected\instance\edefcsname#name\endcsname{\styleinstance[#name]}% \frozen ?
359     \def\font_styles_define_style_collection_a#style%
360       {\def\font_styles_define_style_collection_b#alternative{\undefinevalue{\??stylecollection#name:#style:#alternative}}%
361        \font_helpers_process_alternative_list\font_styles_define_style_collection_b
362        \font_styles_define_style_collection_b\s!default}%
363     \font_helpers_process_style_list\font_styles_define_style_collection_a
364     \font_styles_define_style_collection_a\s!default
365  \fi}
366
367\let\font_styles_define_style_collection  \relax
368\let\font_styles_define_style_collection_a\relax
369\let\font_styles_define_style_collection_b\relax
370
371\permanent\tolerant\protected\def\definestyleinstance[#instance]#*[#2]#*[#3]#*[#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
372  {\ifparameter#instance\or
373     \ifarguments\or\or
374       \letcsname\??stylecollection#instance::#2\endcsname\empty
375     \or
376       \defcsname\??stylecollection#instance::#2\endcsname{#3}%
377     \or
378       \defcsname\??stylecollection#instance:#2:#3\endcsname{#4}%
379     \fi
380     \ifcsname#instance\endcsname\else\font_styles_define_style_collection[#instance]\fi
381  \fi}
382
383\permanent\protected\def\styleinstance[#instance]% maybe \lastnamedcs here too
384  {\csname\??stylecollection#instance:%
385     \ifcsname\??stylecollection#instance:\fontstyle:\fontalternative\endcsname
386       \fontstyle:\fontalternative
387     \orelse\ifcsname\??stylecollection#instance:\fontstyle:\s!default\endcsname
388       \fontstyle:\s!default
389     \orelse\ifcsname\??stylecollection#instance::\fontalternative\endcsname
390       :\fontalternative
391     \else
392       :\s!default
393     \fi
394   \endcsname}
395
396%D Variant selectors
397%D
398%D \starttyping
399%D \mathematics {\vsone{\utfchar{0x2229}}}
400%D \mathematics {\utfchar{0x2229}\vsone{}}
401%D \stoptyping
402
403\permanent\protected\edef\vsone#character{#character\tocharacter"FE00 } % used
404\permanent\protected\edef\vstwo#character{#character\tocharacter"FE01 } % not used but handy for testing
405
406%D For historic reasons we keep the following around but they are no longer that
407%D relevant for \MKIV. But \unknown\ they will be dropped in \LMTX !
408
409\permanent\protected\def\doattributes#1#2#3#4%
410  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
411   \dousestylehashparameter{#1}{#2}%
412   \dousecolorhashparameter{#1}{#3}%
413   #4%
414   \endgroup}
415
416\permanent\protected\def\dostartattributes#1#2#3%
417  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
418   \dousestylehashparameter{#1}{#2}%
419   \dousecolorhashparameter{#1}{#3}}
420
421\aliased\let\dostopattributes\endgroup
422
423%D New but it needs to be supported explicitly (as in natural tables).
424
425\newconditional\c_font_styles_math
426
427\protected\def\font_styles_math_reset
428  {\c_font_styles_math\conditionalfalse}
429
430\protected\def\font_styles_math_start
431  {\ifconditional\c_font_styles_math
432     \startimath
433   \fi
434   \relax}
435
436\protected\def\font_styles_math_stop
437  {\relax
438   \ifconditional\c_font_styles_math
439     \stopimath
440   \fi}
441
442\definealternativestyle[\v!math][\c_font_styles_math\conditionaltrue]
443
444\protect \endinput
445