summaryrefslogtreecommitdiff
path: root/tex/context/base/font-ini.mkiv
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2010-07-04 15:32:09 +0300
committerMarius <mariausol@gmail.com>2010-07-04 15:32:09 +0300
commit85b7bc695629926641c7cb752fd478adfdf374f3 (patch)
tree80293f5aaa7b95a500a78392c39688d8ee7a32fc /tex/context/base/font-ini.mkiv
downloadcontext-85b7bc695629926641c7cb752fd478adfdf374f3.tar.gz
stable 2010-05-24 13:10
Diffstat (limited to 'tex/context/base/font-ini.mkiv')
-rw-r--r--tex/context/base/font-ini.mkiv3896
1 files changed, 3896 insertions, 0 deletions
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
new file mode 100644
index 000000000..c7d515cca
--- /dev/null
+++ b/tex/context/base/font-ini.mkiv
@@ -0,0 +1,3896 @@
+%D \module
+%D [ file=font-ini,
+%D version=1998.09.11, % (second)
+%D version=2001.02.20, % (third)
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=Initialization,
+%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.
+
+% runtime commands will move to modules
+
+% simplification ... we no longer deal with specific mmtfa specifications
+
+% todo: always fontclass, then less testing
+
+% \definefontfeature[smallcaps][smcp=yes,script=latn]
+% \definefontfeature[smallcaps][SmallCapitals=yes,script=latn]
+% \definefontfeature[smallcaps][Small Capitals=yes,script=latn]
+% \definefontfeature[smallcaps][small capitals=yes,script=latn]
+% \definefontfeature[smallcaps][smallcapitals=yes,script=latn]
+%
+% \definedfont[cambria*smallcaps] test
+
+% \starttext
+% \definefontfeature[basekerned][default][mode=base]
+% \definefontfeature[nodekerned][default][mode=node]
+% \definefontfeature[nonekerned][default][mode=base,kern=no]
+% \setupcolors[state=start]
+% \startoverlay
+% {\vbox{\red \definedfont[Serif*nonekerned at 12pt]\input tufte }}
+% {\vbox{\blue \definedfont[Serif*basekerned at 12pt]\input tufte }}
+% {\vbox{\green\definedfont[Serif*nodekerned at 12pt]\input tufte }}
+% \stopoverlay
+% \stoptext
+
+% \enabletrackers[otf.kerns]
+%
+% \definefontfeature[withkern][default][mode=node]
+% \definefontfeature[nokern] [default][mode=node,kern=no]
+% \definefontfeature[single] [default][mode=node,cpsp=yes]
+% \definefontfeature[simple] [default][mode=node,cpsp=yes,kern=no]
+%
+% {\definedfont[Serif*default] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+% {\definedfont[Serif*nokern] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+% {\definedfont[Serif*single] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+% {\definedfont[Serif*simple] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+
+% figure out why \fontbody is not expanded
+
+\writestatus{loading}{ConTeXt Font Macros / Initialization}
+
+\registerctxluafile{font-ini}{1.001}
+\registerctxluafile{node-fnt}{1.001} % here
+\registerctxluafile{font-enc}{1.001}
+\registerctxluafile{font-map}{1.001}
+\registerctxluafile{font-syn}{1.001}
+\registerctxluafile{font-log}{1.001}
+\registerctxluafile{font-tfm}{1.001}
+\registerctxluafile{font-enh}{1.001}
+\registerctxluafile{font-afm}{1.001}
+\registerctxluafile{font-cid}{1.001} % cid maps
+\registerctxluafile{font-ott}{1.001} % otf tables
+\registerctxluafile{font-otf}{1.001} % otf main
+\registerctxluafile{font-otd}{1.001} % otf dynamics
+\registerctxluafile{font-oti}{1.001} % otf initialization
+\registerctxluafile{font-otb}{1.001} % otf main base
+\registerctxluafile{font-otn}{1.001} % otf main node
+\registerctxluafile{font-ota}{1.001} % otf analyzers
+\registerctxluafile{font-otp}{1.001} % otf pack
+\registerctxluafile{font-otc}{1.001} % otf context
+\registerctxluafile{font-vf} {1.001}
+\registerctxluafile{font-def}{1.001}
+\registerctxluafile{font-ctx}{1.001}
+\registerctxluafile{font-xtx}{1.001}
+\registerctxluafile{font-fbk}{1.001}
+\registerctxluafile{font-gds}{1.001}
+\registerctxluafile{font-ext}{1.001}
+\registerctxluafile{font-pat}{1.001}
+\registerctxluafile{font-chk}{1.001}
+\registerctxluafile{font-agl}{1.001}
+
+\unprotect
+
+% \def\fontrange#1%
+% {\dofontrange{#1 =\bodyfontsize}}
+%
+% \def\dofontrange#1%
+% {\dodofontrange#1 \relax}% \fontstringA
+%
+% \def\dodofontrange#1 #2 %
+% {\ifdim\bodyfontsize#2%
+% #1\expandafter\gobbleuntilrelax
+% \else
+% \expandafter\dodofontrange
+% \fi}
+%
+% \definefont
+% [crap]
+% [\fontrange
+% {Regular <10pt
+% RegularBold <12pt
+% RegularSlanted <15pt
+% Regular} sa 1]
+%
+% may be better:
+%
+% \definefontrange
+% [crap]
+% [Regular <10pt
+% RegularBold <12pt
+% RegularSlanted <15pt]
+% [Regular sa 1]
+%
+%
+% \dostepwiserecurse{2}{15}{1}
+% {{\switchtobodyfont[\recurselevel pt]\crap test}\endgraf}
+
+% adapted, else wrong interlinespace
+
+\def\setfontparameters
+ {\synchronizefontsfalse
+ \the\everybodyfont
+ \synchronizefontstrue}
+
+% handy
+
+\newcounter\pushedfont
+
+\def\savefont
+ {\edef\savedfont{\the\font}%
+ \pushmacro\savedfont}
+
+\def\restorefont
+ {\popmacro\savedfont
+ \savedfont}
+
+\def\pushcurrentfont
+ {\edef\popcurrentfont
+ {\noexpand\def\noexpand\fontbody{\fontbody}%
+ \noexpand\def\noexpand\fontstyle{\fontstyle}%
+ \noexpand\dosetcurrentfontalternative{\fontalternative}%
+ \noexpand\dosetcurrentfontsize{\fontsize}%
+ \noexpand\synchronizefont}}
+
+% \definetypeface[one][rm][serif][computer-roman][default]
+% \definetypeface[two][rm][serif][computer-roman][default][rscale=.9]
+%
+% {\one \bf test \two test}
+% {\one \bf test \pushcurrentfont \two \popcurrentfont test}
+
+%D \macros
+%D {definedfont,startfont,doiffontcharelse}
+%D
+%D A couple of relatively new macros:
+
+% \newtoks \everydefinedfont % not ot be confused with \everydefinefont
+
+\def\dodefinedfont[#1]%
+ {\iffirstargument\definefont[thedefinedfont][#1]\fi % we can speed this one up
+ \csname thedefinedfont\endcsname
+ \the\everydefinedfont}
+
+\unexpanded\def\definedfont
+ {\dosingleempty\dodefinedfont}
+
+\unexpanded\def\startfont
+ {\bgroup\definedfont}
+
+\unexpanded\def\stopfont
+ {\egroup}
+
+\def\doiffontcharelse#1#2%
+ {\bgroup
+ \definedfont[#1]%
+ \iffontchar\font#2\relax
+ \egroup\expandafter\firstoftwoarguments
+ \else
+ \egroup\expandafter\secondoftwoarguments
+ \fi}
+
+%D For more detailed (and historic information) we refer to the file
+%D \type {font-ini.mkii}. Here we have a much simplified lower level
+%D implementation due to a different approach to math. Also the chapter
+%D on fonts in the reference manual explains a lot.
+
+%D \macros
+%D {rm,ss,tt,hw,cg}
+%D
+%D Fonts are defined in separate files. When we define a font,
+%D we distinguish between several styles. In most cases we will
+%D use:
+%D
+%D \startlinecorrection
+%D \starttable[|l||]
+%D \HL
+%D \NC roman regular serif \NC \type{\rm} \NC\FR
+%D \NC sansserif sans support \NC \type{\ss} \NC\MR
+%D \NC type teletype mono \NC \type{\tt} \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D The number of styles is not limited to these three. When
+%D using Lucida Bright we can for instance also define:
+%D
+%D \startlinecorrection
+%D \starttable[|l||]
+%D \HL
+%D \NC handwritten \NC \type{\hw} \NC\FR
+%D \NC calligraphic \NC \type{\cg} \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D Within such a font set (\type{cmr}) and style (\type{\rm})
+%D we can define a number of text font alternatives:
+%D
+%D \startlinecorrection
+%D \starttable[|l||]
+%D \HL
+%D \NC typeface \NC \type{\tf} \NC\FR
+%D \NC boldface \NC \type{\bf} \NC\MR
+%D \NC slanted \NC \type{\sl} \NC\MR
+%D \NC italic \NC \type{\it} \NC\MR
+%D \NC boldslanted \NC \type{\bs} \NC\MR
+%D \NC bolditalic \NC \type{\bi} \NC\MR
+%D \NC smallcaps \NC \type{\sc} \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D Internally fonts are stored as combination of size, style
+%D and alternative, e.g. \type{12pt}+\type{\ss}+\type{\bf}.
+%D Users are not confronted with sizes, but use the style or
+%D style+alternative to activate them.
+%D
+%D During the definition of a bodyfont one can also declare the
+%D available larger alternatives:
+%D
+%D \starttyping
+%D \tf \tfa \tfb \tfc ...
+%D \bf \bfa \bfb \bfc ...
+%D \sl \sla \slb \slc ...
+%D \stoptyping
+%D
+%D The smaller ones are automatically supplied and derived from
+%D the the bodyfont environment.
+%D
+%D \starttyping
+%D \tfx \tfxx
+%D \bfx \bfxx
+%D \slx \slxx
+%D \stoptyping
+%D
+%D There are only two smaller alternatives per style. The
+%D larger alternatives on the other hand have no limitations.
+%D
+%D These larger alternatives are mostly used in chapter and
+%D section titles or on title pages. When one switches to a
+%D larger alternative, the bold an other ones automatically
+%D adapt themselves:
+%D
+%D \startbuffer
+%D \tfd Hi \bf there\sl, here \tfb I \bf am
+%D \stopbuffer
+%D
+%S \startnarrower
+%D \typebuffer
+%S \stopnarrower
+%D
+%D therefore becomes:
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D Maybe this mechanism isn't always as logic, but as said
+%D before, we tried to make it as intuitive as possible.
+%D
+%D So a specific kind of glyph can be characterized by:
+%D
+%D \startnarrower
+%D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a)
+%D \stopnarrower
+%D
+%D The last component (the size) is optional.
+%D
+%D We introduced \type{\tf} as command to call for the current
+%D normally sized typeface. This commands results in roman,
+%D sans serif, teletype or whatever style is in charge. Such
+%D rather massive switches of style sometimes take more
+%D processing time than comfortable. Of course there is a
+%D workaround for this: we can call fonts directly by means of
+%D commands like:
+%D
+%D \starttyping
+%D \rmtf \sssl \tttf \rmbsa
+%D \stoptyping
+%D
+%D One should realize that this fast calls have limitations,
+%D they lack for instance automatic super- and subscript
+%D support.
+%D
+%D This leaves us two more commands: \type{\tx} and
+%D \type{\txx}. These activate a smaller and even more smaller
+%D font than the current one and adapt themselves to the
+%D current alternative, so when \type{\bf} is active,
+%D \type{\tx} gives a smaller boldface, which in turn can be
+%D called directly by \type{\bfx}.
+%D
+%D These two smaller alternatives are specified by the bodyfont
+%D environment and therefore not necessarily have similar sizes
+%D as \type{\scriptsize} and \type{\scriptscriptsize}. The main
+%D reason for this incompatibility (which can easily be undone)
+%D lays in the fact that we often want a bit bigger characters
+%D than in math mode. In \CONTEXT\ for instance the \type{\tx}
+%D and \type{\txx} commands are used for surrogate
+%D \cap{smallcaps} which support both nesting and alternatives,
+%D like in {\bf\cap{a \cap{small} world}}, which was typeset by
+%D
+%D \starttyping
+%D \bf\cap{a \cap{small} world}
+%D \stoptyping
+%D
+%D And compare $\rm \scriptstyle THIS$ with the slightly larger
+%D \cap{THIS}: \ruledhbox{$\rm \scriptstyle scriptstyle: THIS$}
+%D or \ruledhbox{\cap{x style: THIS}} makes a big difference.
+%D
+%D The \type{x..d} sizes should be used grouped. If you
+%D don't group them, i.e. call them in a row, \CONTEXT\ will
+%D not be able to sort out your intention (\type {x} inside
+%D \type {d} inside \type {x}. etc.). The following table
+%D demonstrates this:
+%D
+%D \def\FontState{\setstrut\ruledhbox{\strut Hello}}
+%D
+%D \starttabulate[|||||]
+%D \HL
+%D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR
+%D \HL
+%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR
+%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR
+%D \NC \type{\tf} \NC \tf \FontState \NC \tf \tx \FontState \NC \tf \txx \FontState \NC \NR
+%D \NC \type{\tfa} \NC \tfa \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState \NC \NR
+%D \NC \type{\tfb} \NC \tfb \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState \NC \NR
+%D \NC \type{\tfc} \NC \tfc \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState \NC \NR
+%D \NC \type{\tfd} \NC \tfd \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState \NC \NR
+%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR
+%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR
+%D \HL
+%D \stoptabulate
+%D
+%D \blank
+%D
+%D \starttabulate[|||||]
+%D \HL
+%D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR
+%D \HL
+%D \NC \type{\tfx}
+%D \NC \tfx \FontState
+%D \NC \tfx \tx \FontState
+%D \NC \tfx \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfxx}
+%D \NC \tfx\tfxx \FontState
+%D \NC \tfx\tfxx \tx \FontState
+%D \NC \tfx\tfxx \txx \FontState
+%D \NC \NR
+%D \NC \type{\tf}
+%D \NC \tfx\tfxx\tf \FontState
+%D \NC \tfx\tfxx\tf \tx \FontState
+%D \NC \tfx\tfxx\tf \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfa}
+%D \NC \tfx\tfxx\tf\tfa \FontState
+%D \NC \tfx\tfxx\tf\tfa \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfb}
+%D \NC \tfx\tfxx\tf\tfa\tfb \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfc}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfd}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfx}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfxx}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState
+%D \NC \NR
+%D \HL
+%D \stoptabulate
+%D
+%D Remark: math support has changed a bit.
+
+%D \macros
+%D {uchar}
+%D
+%D This macro prepares \CONTEXT\ for \UNICODE\ support. By
+%D defining it here, we have at least an safeguard for utility
+%D file reading.
+
+\ifdefined\uchar\else \unexpanded\def\uchar#1#2{[#1,#2]} \fi
+
+%D We define some (very private) constants to improve speed,
+%D memory usage and consistency.
+
+\def\@size@ {@f@si@} % bodyfont size prefix (12pt etc)
+\def\@style@ {@f@st@} % full style prefix (roman etc)
+\def\@shortstyle@ {@f@sh@} % short style prefix (rm etc)
+\def\@letter@ {@f@le@} % first alternative typeface
+\def\@noletter@ {@f@no@} % second alternative typeface
+\def\@fontclass@ {@f@cl@} % fontclass
+
+%D \macros
+%D {fontclass, defaultfontclass}
+%D
+%D The fontclass model was introduced a while after we implement
+%D the basic font model and at that time we still defaulted to
+%D no model at all. Nowadays we default to the \type {modern}
+%D fontclass.
+
+\let\fontclass \empty
+\let\defaultfontclass\empty
+
+%D \macros
+%D {textonly}
+%D
+%D Traditionally math has a big impact on font definitions, mainly
+%D because we need to define alphabet variants using families and
+%D fonts. This means that one can easily get 10 fonts loaded per
+%D math size. In \MKIV\ we use a different approach: one family
+%D which has either a virtual font made of traditional fonts, or
+%D an \OPENTYPE\ font that has it all.
+%D
+%D We currently use only one math family but in the future we
+%D might consider using a second one for bold math. For the
+%D moment we keep the \MKII\ method of using a token register
+%D for definitions but we already dropped the text and symbols
+%D ones since they now live in the same family.
+
+\newtoks \mathstrategies
+
+\newif\ifsynchronizemathfonts \synchronizemathfontstrue
+
+\def\synchronizemath % math stuff in mmode
+ {\ifsynchronizemathfonts\the\mathstrategies\fi}
+
+\def\textonly{\synchronizemathfontsfalse} % document this
+
+%D The main math font definer. We have removed some optimized
+%D code simply because we now always have a fontclass. We could
+%D check for fontclass being default or empty and save a few
+%D tests but it does not help us when no math is defined.
+
+\chardef\mrfam\zerocount % math regular
+\chardef\mbfam\plusone % math bold
+
+\unexpanded\def\mr{\ifmmode\fam\zerocount\else\setcurrentfontalternative\c!mr\fi} % \fam\csname\c!mr fam\endcsname
+\unexpanded\def\mb{\ifmmode\fam\plusone \else\setcurrentfontalternative\c!mb\fi} % \fam\csname\c!mb fam\endcsname
+
+\def\mathtextsuffix {-text}
+\def\mathscriptsuffix {-script}
+\def\mathscriptscriptsuffix{-scriptscript}
+
+% \let\mathsizesuffix\empty
+
+\let\currentmathsize\empty
+
+\def\mathsizesuffix{\ifcase0\currentmathsize\or\mathtextsuffix\or\mathscriptsuffix\or\mathscriptscriptsuffix\fi}
+
+\def\dodosetmathfamily#1#2%
+ {\ifcsname\fontclass \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse
+ \csname\fontclass \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else
+ \ifcsname\fontclass \fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue
+ \csname\fontclass \fontbody\c!mm\fontfamily \currentmathsize\endcsname \else
+ \dodosetmathfamilyx#1#2%
+ \fi\fi
+ #1#2\font}
+
+\def\dodosetmathfamilyx#1#2%
+ {\ifcsname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse
+ \csname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else
+ \ifcsname\defaultfontclass\fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue
+ \csname\defaultfontclass\fontbody\c!mm\fontfamily \currentmathsize\endcsname \else
+ \dodosetmathfamilyxx#1#2%
+ \fi\fi}
+
+\def\dodosetmathfamilyxx#1#2%
+ {\ifcsname \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse
+ \csname \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else
+ \ifcsname \fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue
+ \csname \fontbody\c!mm\fontfamily \currentmathsize\endcsname \else
+ \nullfont \autofontsizetrue
+ \fi\fi}
+
+\def\dosetmathfamily#1#2%
+ {\let\savedfontbody\fontbody % op hoger plan
+ \let\fontfamily#2%
+ \let\currentmathsize\!!plusthree\let\fontbody\scriptscriptface\dodosetmathfamily\scriptscriptfont#1%
+ \let\currentmathsize\!!plustwo \let\fontbody\scriptface \dodosetmathfamily\scriptfont #1%
+ \let\currentmathsize\!!plusone \let\fontbody\textface \dodosetmathfamily\textfont #1%
+ \let\currentmathsize\empty
+ \let\fontbody\savedfontbody
+ \autofontsizefalse}
+
+\appendtoks
+ \dosetmathfamily\mrfam\c!mr
+\to \mathstrategies
+
+% not official !
+
+\chardef\boldmathmode\zerocount % might change ... maybe \mathfontsupport 1 (normal) 2 (bold too)
+
+\def\enableboldmath {\chardef\boldmathmode\plusone } % todo: \setupbodyfont[boldmath,...]
+\def\disableboldmath{\chardef\boldmathmode\zerocount}
+
+\appendtoks
+ \ifcase\boldmathmode\or\dosetmathfamily\mbfam\c!mb\fi
+\to \mathstrategies
+
+% \chardef\msfam\plustwo % math symbol
+%
+% \def\c!ms{ms}
+%
+% \unexpanded\def\ms{\ifmmode\fam\plustwo\else\setcurrentfontalternative\c!ms\fi}
+%
+% \chardef\symbolmathmode\zerocount
+%
+% \def\enablesymbolmath {\chardef\symbolmathmode\plusone }
+% \def\disablesymbolmath{\chardef\symbolmathmode\zerocount}
+%
+% \appendtoks
+% \ifcase\symbolmathmode\or\dosetmathfamily\msfam\c!ms\fi
+% \to \mathstrategies
+
+%D All used styles, like rm, ss and tt, are saved in a comma
+%D separated list. Appart from practical limitations one can
+%D define as many styles as needed.
+
+\def\fontrelativesizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small}
+
+%D There are several ways to specify a font. Three of them are
+%D pure \TeX\ ones, the fourth one is new:
+%D
+%D \starttyping
+%D \font\name=cmr12
+%D \font\name=cmr12 at 10pt
+%D \font\name=cmr12 scaled 2
+%D \font\name=cmr12 sa 1.440
+%D \stoptyping
+%D
+%D The non||\TEX\ alternative \type{sa} stands for {\em scaled
+%D at}. This means as much as: scale the bodyfontsize with this
+%D factor. The scaled option is not that useful as one needs to
+%D know the design size.
+%D
+%D Because \type {sa} (scaled at) and \type {mo} (mapped on)
+%D are not low level \TEX\ supported alternatives, we have to
+%D test for it ourselves. In doing so, we need an auxiliary
+%D \DIMENSION. We cannot use \type{\scratchdimen} because font
+%D loading can happen at any moment due to postponed loading.
+%D We could instead have used dirty grouping tricks, but this
+%D one works too.
+
+% \enableexperiments[fonts.autorscale]
+%
+% \starttypescript[mscore]
+% \definetypeface [mscore] [rm] [serif] [mscoretimes] [default]
+% \definetypeface [mscore] [ss] [sans] [mscorearial] [default] [rscale=auto] % 0.860]
+% \definetypeface [mscore] [tt] [mono] [mscorecourier] [default] [rscale=auto] % 1.065]
+% \definetypeface [mscore] [mm] [math] [times] [default] [rscale=auto] % 1.020]
+% \stoptypescript
+%
+% \starttext
+% \setupbodyfont[mscore,12pt]
+% \startTEXpage
+% test \ss test \tt test
+% \stopTEXpage
+% \stoptext
+
+\let\defaultrelativefontsize \plusone
+\let\localrelativefontsize \plusone
+\def\localabsolutefontsize {\fontbody}
+
+\let\relativefontsize \defaultrelativefontsize
+
+% \def\saverelativefontsize#1#2% #1=rm|ss|.. #2=waarde
+% {\setxvalue{\fontclass#1\s!rscale}{#2}}
+
+\def\checkrelativefontid
+ {\ifcsname\??tf\fontclass\s!rname\endcsname
+ \@EA\let\@EA\relativefontid\csname\??tf\fontclass\s!rname\endcsname
+ \else
+ \@EA\xdef\csname\??tf\fontclass\s!rname\endcsname{\the\lastfontid}%
+ \let\relativefontid\empty
+ \fi}
+
+\def\checkrelativefontsize#1%
+ {\edef\relativefontsize
+ {\ifcsname\fontclass#1\s!rscale\endcsname
+ \csname\fontclass#1\s!rscale\endcsname
+ \else\ifcsname\defaultfontclass#1\s!rscale\endcsname
+ \csname\defaultfontclass#1\s!rscale\endcsname
+ \else
+ \defaultrelativefontsize
+ \fi\fi}%
+ \ifx\relativefontsize\v!auto
+ \let\relativefontsize\plusone
+ \checkrelativefontid
+ \else
+ \let\relativefontid\minusone
+ \fi}
+
+%D Scaling macros:
+%D
+%D This system is somewhat complicated by two (possible conflicting)
+%D demands:
+%D
+%D \startitemize
+%D \item We support wildcards like \type {sa *} which will adapt
+%D to the current size. This is also the default specification.
+%D \item We support named scales like \type {sa d}; beware: \type
+%D {x} and \type {xx} are valid scales but they are not alway
+%D the same as the ones used in for instance \type {\bfx} because
+%D there the sized come from the bodyfont environment. In the
+%D future there maybe a switch that also honors the environment
+%D in named scales.
+%D \stopitemize
+
+%D Keep in mind that the smaller sizes are just for text super and
+%D subscripts while larger sizes can be used in titles where for
+%D instance math follows the size.
+
+% b:x{\definedfont[SerifBold sa b]x}{\bfb x $x^x$}\par
+% 1:x{\definedfont[SerifBold sa 1]x}{\bf x $x^x$}\par
+% x:x{\definedfont[SerifBold sa x]x}{\bfx x $x^x$}\par
+% xx:x{\definedfont[SerifBold sa xx]x}{\bfxx x $x^x$}\par
+%
+% *:x{\definedfont[Serif sa *]x}\par
+% 1:x{\definedfont[Serif sa 1]x}\par
+% 2:x{\definedfont[Serif sa 2]x}\par
+% 3:x{\definedfont[Serif sa 3]x}\par
+% 4:x{\definedfont[Serif sa 4]x}\par
+% 5:x{\definedfont[Serif sa 5]x}\par
+%
+% {\definedfont[cmbx10 at 10pt]x\definedfont[cmbx8 at 10pt]x}
+
+\def\safontscale{\number\dimexpr\localabsolutefontsize\relax}
+\def\mofontscale{\number\dimexpr\setmappedfontsize\localabsolutefontsize\relax}
+
+\let\somefontname\s!unknown
+\let\somefontspec\s!unknown
+\let\somefontsize\zerocount
+
+\newcount\scaledfontmode
+\newdimen\scaledfontsize
+\newtoks \everydefinefont
+\newcount\lastfontid
+
+\def\currentfontbodysize
+ {\ifcsname\??ft\s!default\somefontsize\endcsname
+ \csname\??ft\s!default\somefontsize\endcsname
+ \else
+ \somefontsize
+ \fi}
+
+\let\relativefontid\empty
+
+\def\lowleveldefinefont#1#2% #2 = cs
+ {%
+ \ctxlua{fonts.define.command_1("\luaescapestring{#1}")}% the escapestring catches at \somedimen
+ % sets \scaledfontmode and \somefontname and \somefontsize
+ \ifcase\scaledfontmode\relax
+ % none, avoid the designsize if possible
+ \scaledfontsize-1000\scaledpoint
+ \or
+ % at
+ \scaledfontsize\somefontsize
+ \or
+ % sa
+ \scaledfontsize\localabsolutefontsize\relax
+ \scaledfontsize\currentfontbodysize\scaledfontsize
+ \or
+ % mo
+ \scaledfontsize\setmappedfontsize\localabsolutefontsize
+ \scaledfontsize\currentfontbodysize\scaledfontsize
+ \or
+ % scaled, don't use this one as it's unpredictable
+ \scaledfontsize-\somefontsize\scaledpoint
+ \fi
+ \scaledfontsize\localrelativefontsize\scaledfontsize
+ \ifautofontsize
+ \scaledfontsize\currentfontbodyscale\scaledfontsize
+ \fi
+ \edef\somefontspec{at \number\scaledfontsize sp}%
+ \edef\somefontfile{\truefontname\somefontname}%
+ \ifx\somefontfile\s!unknown
+ \edef\somefontfile{\defaultfontfile}%
+ \fi
+ \updatefontparameters
+ \updatefontclassparameters
+ \ctxlua{fonts.define.command_2(
+ \ifx\fontclass\empty false\else true\fi,
+ "#2", % cs, trailing % is gone
+ "\somefontfile",
+ \number\scaledfontsize,
+ "\@@fontclassfeatures",
+ "\@@fontfeatures",
+ "\@@fontclassfallbacks",
+ "\@@fontfallbacks",
+ 0\currentmathsize,
+ \number\dimexpr\textface\relax,
+ "\relativefontid" % experiment
+ )}%
+ \edef\somefontspec{at \somefontsize}% we need the resolved designsize (for fallbacks)
+ \expandafter\let\expandafter\lastrawfontcall\csname#2\endcsname
+ \the\everydefinefont}
+
+\def\updatefontclassparameters
+ {\edef\@@fontclassfeatures {\ifcsname\fontclass\fontstyle\s!features \endcsname\csname\fontclass\fontstyle\s!features \endcsname\fi}%
+ \edef\@@fontclassfallbacks{\ifcsname\fontclass\fontstyle\s!fallbacks\endcsname\csname\fontclass\fontstyle\s!fallbacks\endcsname\fi}}
+
+% resolve
+
+\def\@@thefeaturesyes#1%
+ {\ifcsname\??ff\fontclass#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff\fontclass#1\s!features \endcsname\else
+ \ifcsname\??ff #1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff #1\s!features \endcsname\else
+ \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefeaturesyes \csname\??ff\fontclass #1\endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesyes \csname\??ff #1\endcsname\else
+ \let \@@fontfeatures \empty \fi\fi\fi\fi}
+
+\def\@@thefallbacksyes#1%
+ {\ifcsname\??ff\fontclass#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff\fontclass#1\s!fallbacks\endcsname\else
+ \ifcsname\??ff #1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff #1\s!fallbacks\endcsname\else
+ \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefallbacksyes\csname\??ff\fontclass #1\endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksyes\csname\??ff #1\endcsname\else
+ \let \@@fontfallbacks \empty \fi\fi\fi\fi}
+
+\def\@@thefeaturesnop#1%
+ {\ifcsname\??ff#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff#1\s!features \endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesnop \csname\??ff #1\endcsname\else
+ \let \@@fontfeatures \empty \fi\fi}
+
+\def\@@thefallbacksnop#1%
+ {\ifcsname\??ff#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff#1\s!fallbacks\endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksnop\csname\??ff #1\endcsname\else
+ \let \@@fontfallbacks \empty \fi\fi}
+
+\def\updatefontparametersyes
+ {\@@thefeaturesyes \somefontname
+ \@@thefallbacksyes\somefontname}
+
+\def\updatefontparametersnop
+ {\@@thefeaturesnop \somefontname
+ \@@thefallbacksnop\somefontname}
+
+\def\updatefontparameters
+ {\ifx\fontclass\empty\updatefontparametersnop\else\updatefontparametersyes\fi}
+
+\let\@@fontclassfeatures \empty
+\let\@@fontclassfallbacks\empty
+
+\let\@@fontfallbacks\empty
+\let\@@fontfeatures \empty
+\let\@@hyphenchar \empty % todo, will go to encoding
+
+%D This brings down maps processing from 466 to 309 seconds
+%D ($-33$\%) and mfonts from 42 to 34 seconds ($-15$\%).
+
+\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue
+
+%D When fontclasses are used, we define the font global,
+%D since namespaces are used. Otherwise we parse the specs
+%D each time.
+
+\let\fontfile\s!unknown
+
+% \definefontfeature[slanted] [default][slant=.25]
+% \definefontfeature[stretched][default][stretch=2]
+%
+% \start \definedfont[SerifBold*slanted at 20pt] \ruledhbox{Test!} \stop
+% \start \definedfont[SerifBold*stretched at 20pt] \ruledhbox{Test!} \stop
+
+% \definefontfeature[default] [liga=yes,texligatures=yes,texquotes=yes]
+% \definefontfeature[default-caps][liga=yes,texligatures=yes,texquotes=yes,smcp=yes,script=latn]
+%
+% \starttypescript [serif] [palatino-nova-regular] [name]
+% \definefontsynonym[Serif] [palatinonova-regular][features=default]
+% \definefontsynonym[SerifCaps][palatinonova-regular][features=default-caps] % also sets Serif
+% \stoptypescript
+%
+% \starttypescript [serif] [palatino-nova-regular] [name]
+% \definefontsynonym[Serif] [palatinonova-regular*default]
+% \definefontsynonym[SerifCaps] [palatinonova-regular*default-caps]
+% \stoptypescript
+
+% \definetypeface[mainface][rm][serif][palatino-nova-regular][default] \setupbodyfont[mainface]
+%
+% \starttext
+% ``Test'' -- --- ff fi fl \sc ``Test'' -- --- ff fi fl
+% \stoptext
+
+% \starttext
+% \definefont
+% [blabla]
+% [name:Latin Modern Something]
+% \definefont
+% [blabla]
+% [file:texnansi-lmr10]
+% \blabla test
+% \definefont
+% [blabla]
+% [texnansi-lmtt10]
+% \blabla test
+% \stoptext
+
+% \starttext
+%
+% \setupcolors[state=start]
+%
+% \definefontfeature
+% [default-base]
+% [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes]
+% \definefontfeature
+% [default-node]
+% [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes,mode=node]
+% \definefontfeature
+% [default-none]
+% [script=latn,language=dflt,liga=yes,kern=no, tlig=yes,trep=yes]
+%
+% \startoverlay
+% {\vtop{\color[red] {\font\test=name:lmroman12regular*default-node \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[green]{\font\test=name:lmroman12regular*default-base \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[blue] {\font\test=name:lmroman12regular*default-none \test \input ward \input zapf \input linden }}}
+% \stopoverlay
+%
+% \blank
+%
+% \startoverlay
+% {\vtop{\color[red] {\font\test=name:texgyrepagella*default-node \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[green]{\font\test=name:texgyrepagella*default-base \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[blue] {\font\test=name:texgyrepagella*default-none \test \input ward \input zapf \input linden }}}
+% \stopoverlay
+%
+% \blank
+%
+% \startoverlay
+% {\vtop{\color[red] {\font\test=name:palatinonovaregular*default-node \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[green]{\font\test=name:palatinonovaregular*default-base \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[blue] {\font\test=name:palatinonovaregular*default-none \test \input ward \input zapf \input linden }}}
+% \stopoverlay
+%
+% \startoverlay
+% {\vtop{\color[red] {\font\test=name:OfficinaSerifBookITC*default-node \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[green]{\font\test=name:OfficinaSerifBookITC*default-base \test \input ward \input zapf \input linden }}}
+% {\vtop{\color[blue] {\font\test=name:OfficinaSerifBookITC*default-none \test \input ward \input zapf \input linden }}}
+% \stopoverlay
+%
+% \definefontfeature[superdefault][default][compose=yes]
+%
+% {\font\oeps=name:lmroman10regular*default at 30pt \oeps test \char7683}
+% {\font\oeps=name:lmroman10regular*superdefault at 30pt \oeps test \char7683}
+%
+% \stoptext
+
+\def \defaultfontfile{\truefontname{Normal}} % was cmtt10, but that one is gone
+\edef\nullfontname {\fontname\nullfont}
+
+%D \macros
+%D {everyfont,everyfontswitch}
+%D
+%D For special purposes, we provide a hook.
+
+% \newevery \everyfont \relax
+% \newevery \everyfontswitch \relax
+
+%D We also accept \type{sa a}||\type{sa d} as specification.
+
+%D \macros
+%D {definefontsynonym, doifelsefontsynonym,
+%D expandfontsynonym, truefontname, truefontdata}
+%D
+%D While looking for fonts, fontsynonyms are used for accessing
+%D the files!
+%D
+%D \starttyping
+%D \definefontsynonym[Serif][Lucida-Bright]
+%D \definefontsynonym[Lucida-Bright][lbr][encoding=texnansi]
+%D \stoptyping
+
+\def\classfont#1#2{#1#2} % \definefont[whatever][\classfont{xx}{yy} at 10pt]
+
+% We need to move the feature into the filename else it may be
+% overloaded by another reference. For instance the definition of
+% a regular and caps variant can use the same font.
+
+% We could use an indirect method ... store in 'array' and refer to
+% slot.
+
+\unexpanded\def\definefontsynonym[#1]#2[#3]%
+ {\edef\@@fontname{#1}%
+ \edef\@@fontfile{#3}%
+ \ifx\fontclass\empty
+ \expandafter\dodefinefontsynonymnop
+ \else
+ \expandafter\dodefinefontsynonymyes
+ \fi}
+
+\def\dodefinefontsynonymnop
+ {\@EA\let\csname\??ff\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
+ \doifnextoptionalelse\dododefinefontsynonymnop\nonodefinefontsynonymnop}
+
+\def\dodefinefontsynonymyes
+ {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
+ \doifnextoptionalelse\dododefinefontsynonymyes\nonodefinefontsynonymyes}
+
+\def\dododefinefontsynonymnop[#1]%
+ {\let\@@ff@@features \undefined
+ \let\@@ff@@fallbacks\undefined
+ \expandafter\dogetfontparameternop#1,]=,}
+
+\def\dododefinefontsynonymyes[#1]%
+ {\let\@@ff@@features \undefined
+ \let\@@ff@@fallbacks\undefined
+ \expandafter\dogetfontparameteryes#1,]=,}
+
+\def\dogetfontparameternop#1=#2,%
+ {\if]#1%
+ \dodododefinefontsynonymnop
+ \else
+ \expandafter\def\csname @@ff@@#1\endcsname{#2}%
+ \expandafter\dogetfontparameternop
+ \fi}
+
+\def\dogetfontparameteryes#1=#2,%
+ {\if]#1%
+ \dodododefinefontsynonymyes
+ \else
+ \expandafter\def\csname @@ff@@#1\endcsname{#2}%
+ \expandafter\dogetfontparameteryes
+ \fi}
+
+% hm, was wrong, class/global reversed
+
+\let\fcglobal\global
+\let\fcxdef \xdef
+\let\fcglet \glet
+
+\def\nonodefinefontsynonymnop
+ {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined
+ \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined}
+
+\def\nonodefinefontsynonymyes
+ {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined
+ \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined}
+
+\def\dodododefinefontsynonymnop
+ {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features
+ \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks}
+
+\def\dodododefinefontsynonymyes
+ {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features
+ \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks}
+
+\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater
+
+\unexpanded\def\setupfontsynonym
+ {\dodoubleempty\dosetupfontsynonym}
+
+\def\dosetupfontsynonym[#1][#2]% not yet supported, will do when needed
+ {}
+
+\def\truefontname#1%
+ {\@EA\dotruefontname#1*\empty*\relax}
+
+\def\dotruefontname#1*#2#3*#4\relax
+ {\ifcsname\??ff\fontclass#1\endcsname
+ \ifx#2\empty
+ \@EA\truefontname\csname\??ff\fontclass#1\endcsname
+ \else
+ \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3%
+ \fi
+ \else\ifcsname\??ff\defaultfontclass#1\endcsname
+ \ifx#2\empty
+ \@EA\truefontname\csname\??ff\defaultfontclass#1\endcsname
+ \else
+ \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname*#2#3%
+ \fi
+ \else\ifcsname\??ff#1\endcsname
+ \ifx#2\empty
+ \@EA\truefontname\csname\??ff#1\endcsname
+ \else
+ \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3%
+ \fi
+ \else
+ #1\ifx#2\empty\else*#2#3\fi
+ \fi\fi\fi}
+
+\def\redotruefontname#1%
+ {\@EA\dodotruefontname#1*\relax}
+
+\def\dodotruefontname#1*#2\relax
+ {\ifcsname\??ff\fontclass#1\endcsname
+ \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname
+ \else\ifcsname\??ff\defaultfontclass#1\endcsname
+ \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname
+ \else\ifcsname\??ff#1\endcsname
+ \@EA\redotruefontname\csname\??ff#1\endcsname
+ \else
+ #1%
+ \fi\fi\fi}
+
+\def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1)
+ {\ifcsname\??ff\fontclass#2\endcsname
+ \expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}%
+ \else\ifcsname\??ff\defaultfontclass#2\endcsname
+ \expandafter\def\expandafter#1\expandafter{\csname\??ff\defaultfontclass#2\endcsname}%
+ \fi\fi}
+
+\def\doifelsefontsynonym#1%
+ {\ifcsname\??ff\fontclass#1\endcsname
+ \@EA\firstoftwoarguments
+ \else\ifcsname\??ff\defaultfontclass#1\endcsname
+ \@EAEAEA\firstoftwoarguments
+ \else
+ \@EAEAEA\secondoftwoarguments
+ \fi\fi}
+
+% \definetypeface[palatino][rm][serif][palatino,allbold][default]
+%
+% \startfontclass[palatino]
+% \definefontsynonym [Serif] [SerifBold]
+% \definefontsynonym [SerifItalic] [SerifBoldItalic]
+% \definefontsynonym [SerifSlanted] [SerifBoldSlanted]
+% \definefontsynonym [SerifCaps] [SerifBold]
+% \stopfontclass
+%
+% \setupbodyfont[palatino]
+
+\unexpanded\def\startfontclass
+ {\dosingleempty\dostartfontclass}
+
+\def\dostartfontclass[#1]%
+ {\pushmacro\fontclass
+ \doifelse{#1}\v!each
+ {\let\fontclass\empty}
+ {\doifsomething{#1}{\def\fontclass{#1}}}}
+
+\unexpanded\def\stopfontclass
+ {\popmacro\fontclass}
+
+%D \macros
+%D {tracedfontname}
+%D
+%D A goody:
+
+\def\tracedfontname#1%
+ {#1\ifcsname\??ff\fontclass#1\endcsname
+ \@EA\tracedfontname\csname\??ff\fontclass#1\endcsname
+ \else\ifcsname\??ff#1\endcsname
+ \@EA\tracedfontname\csname\??ff#1\endcsname
+ \fi\fi}
+
+%D \macros
+%D {definefont}
+%D
+%D Before we implement the main definition macro, we first show
+%D one for local use:
+%D
+%D \starttyping
+%D \definefont[Some][LucidaBright at 100pt] \Some some
+%D \definefont[More][LucidaBright scaled 3000] \More more
+%D \definefont[Nice][LucidaBright mo 2] \Nice nice
+%D \definefont[Text][LucidaBright sa 5.4] \Text last
+%D \stoptyping
+%D
+%D The implementation looks as follows:
+
+\unexpanded\def\definefont
+ {\dotripleempty\dodefinefont}
+
+\def\dodefinefont[#1][#2][#3]% [name][spec][1.6 | line=10pt | setup_id]
+ {\ifthirdargument
+ \setuvalue{#1}{\redodefinefont{#1}{#2}{#3}}%
+ \else
+ \setuvalue{#1}{\dododefinefont{#1}{#2}}%
+ \fi}
+
+\def\redodefinefont#1#2#3%
+ {\dododefinefont{#1}{#2}%
+ \doifsetupselse{#3}
+ {\setups[#3]} % don't forget to document this !
+ {\setuplocalinterlinespace[#3]%
+ \setupspacing}} % needed ?
+
+\unexpanded\def\definefrozenfont
+ {\dotripleempty\dodefinefrozenfont}
+
+\def\dodefinefrozenfont[#1][#2][#3]%
+ {\dodefinefont[#1][#2][#3]%
+ \expandafter\let\csname\lastfontidentifier\expandafter\endcsname\csname\rawfontidentifier\endcsname}
+
+%D The \type {*} makes the switch local, so that we can redefine a
+%D logical name and/or change the size in between.
+
+\newif\ifautofontsize \autofontsizetrue
+
+\let\lastfontidentifier\empty
+
+\def\rawfontidentifier{**\lastfontidentifier\fontsize\currentmathsize**}
+\def\newfontidentifier{*\fontclass\lastfontidentifier\fontsize\currentmathsize*}
+
+\let\oldrawfontidentifier\rawfontidentifier
+\let\oldnewfontidentifier\newfontidentifier
+
+\def\newfontidentifier{*\fontclass\lastfontidentifier\fontstyle\fontsize*}
+
+\def\dododefinefont#1#2%
+ {\edef\lastfontidentifier{#1}%
+ \let\localrelativefontsize\defaultrelativefontsize
+ \let\localabsolutefontsize\fontbody
+ \lowleveldefinefont{#2}\rawfontidentifier
+ \csname\rawfontidentifier\endcsname
+ \autofontsizefalse
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \let\rawfontidentifier\oldrawfontidentifier}
+
+\def\xxdododefinefont#1#2#3#4% \autofontsizetrue is set by calling routine
+ {\edef\lastfontidentifier{#3}%
+ \ifcsname\newfontidentifier\endcsname\else
+ \def\localrelativefontsize{#1}%
+ \def\localabsolutefontsize{#2}%
+ \lowleveldefinefont{#4}\newfontidentifier
+ \fi
+ \csname\newfontidentifier\endcsname
+ \autofontsizefalse
+ %\edef\lastfontidentifier{#3}%
+ \ifskipfontcharacteristics \else
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \fi
+ \let\newfontidentifier\oldnewfontidentifier}
+
+%D \macros
+%D {mapfontsize}
+%D
+%D For special purposes, like in math, you may want to use
+%D slightly different sizes than the ones given. This happens
+%D for instance with the Math Times fonts. Mapped font sizes
+%D can be specified by using the \type {mo} key instead of
+%D \type {sa} in font definitions.
+%D
+%D \startbuffer
+%D \mapfontsize[10pt][11pt]
+%D \mapfontsize[11pt][12pt]
+%D \mapfontsize[12pt][13pt]
+%D
+%D \definefont[test][Serif]\test TEST \par
+%D \definefont[test][Serif sa 5]\test TEST \par
+%D \definefont[test][Serif mo 5]\test TEST \par
+%D \definefont[test][Serif sa d]\test TEST \par
+%D \definefont[test][Serif at 60pt]\test TEST \par
+%D \definefont[test][Serif scaled 6000]\test TEST \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startpacked
+%D \getbuffer
+%D \stoppacked
+
+\def\mapfontsize
+ {\dodoubleargument\domapfontsize}
+
+\def\domapfontsize[#1][#2]%
+ {\setvalue{\??ft*\the\dimexpr#1\relax}{#2}}
+
+\def\setmappedfontsize#1%
+ {\ifcsname\??ft*#1\endcsname
+ \csname\??ft*#1\endcsname
+ \else
+ #1%
+ \fi}
+
+%D \macros
+%D {getfontname}
+%D
+%D The names of the fonts can be called with the rather simple
+%D macro \type{\getfontname}. When for instance we pass
+%D \type{12ptrmtf} as argument, we get \getfontname{12ptrmtf}.
+
+\def\getfontname#1%
+ {\csname\??ft#1\endcsname}
+
+%D To be documented.
+
+\let\fontsizelist \empty
+\let\fontalternativelist\empty
+\let\fontstylelist \empty
+
+\def\checkfontnamecombinations % we need to split math and text here ... todo (math only has mr and mb)
+ {\def\docommand##1%
+ {\def\dodocommand####1%
+ {\def\dododocommand########1{\checkbodyfont{########1}{####1}{##1}}%
+ \processcommacommand[\fontstylelist]\dododocommand}%
+ \processcommacommand[\fontalternativelist]\dodocommand}%
+ \processcommacommand[\fontsizelist]\docommand}
+
+\unexpanded\def\definefontsize[#1]% sneller met toks
+ {\addtocommalist{#1}\fontsizelist
+ \checkfontnamecombinations}
+
+\unexpanded\def\definefontalternative[#1]%
+ {\addtocommalist{#1}\fontalternativelist
+ \checkfontnamecombinations}
+
+%D \macros
+%D {currentfontscale,currentfontbodyscale}
+%D
+%D Sometimes we need to have access to the font scale
+%D including the \type{a}||\type{d} sizes. The next macro
+%D returns the current scaling factor. Take a look at
+%D \type {cont-log.tex} for an example of its use.
+
+\def\currentfontscale
+ {\csname\??ft\s!default
+ \ifcsname\??ft\s!default\xfontsize\endcsname \xfontsize \else
+ \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi
+ \endcsname}
+
+\def\currentfontbodyscale
+ {\csname\??ft\s!default
+ \ifcsname\??ft\s!default\fontsize\endcsname \fontsize \else
+ \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi
+ \endcsname}
+
+\setvalue{\??ft\s!default}{1}
+
+%D Both alternatives use \type {\xfontsize}, a macro that
+%D expands to the current size in terms of \type {a} \unknown
+%D \type {d}, nothing, or \type {x} \unknown \type {xx}.
+
+\def\xfontsize{\ifcase\currentxfontsize\fontsize\or\c!x\else\c!xx\fi}
+
+%D A typical use of this command is in commands that switch
+%D to another font bypassing the font mechanism:
+%D
+%D \starttyping
+%D \font\myfont=\truefontname{MyFont} at \the\dimexpr\currentfontscale\bodyfontsize\relax
+%D \stoptyping
+
+%D Now we enter the area of font switching. The switching
+%D mechanism has to take care of several situations, like:
+%D
+%D \startitemize[packed]
+%D \item changing the overal document fonts (including margins,
+%D headers and footers)
+%D \item changing local fonts (only the running text)
+%D \item smaller and even more smaller alternatives (super-
+%D and subscripts)
+%D \stopitemize
+%D
+%D \TEX\ offers a powerfull family mechanism for super- and
+%D subscripts in math mode. In text mode however, we don't use
+%D families for the smaller alternatives, and therefore have
+%D to take care of it otherwise.
+
+%D \macros
+%D {definebodyfontenvironment,setupbodyfontenvironment}
+%D
+%D The relationship between the several sizes of a font, is
+%D defined by:
+%D
+%D \showsetup{definebodyfontenvironment}
+%D
+%D Later on we will see how these parameters are used, so for
+%D the moment we stick with an example:
+%D
+%D \starttyping
+%D \definebodyfontenvironment
+%D [12pt]
+%D [ text=12pt,
+%D script=9pt,
+%D scriptscript=7pt,
+%D x=10pt,
+%D xx=8pt,
+%D big=12pt,
+%D small=10pt]
+%D \stoptyping
+%D
+%D The first argument specifies the bodyfont size to which the
+%D settings apply. All second parameters are specified in
+%D dimensions and tell us more about related sizes.
+%D
+%D Afterwards, one can change values with
+%D
+%D \showsetup{setupbodyfontenvironment}
+%D
+%D Due to the fact that \type{\c!text} and \type{\s!text} can
+%D have a similar meaning, and therefore can lead to an
+%D unwanted loop, we temporary redefine \type{\c!text}. For
+%D the moment this in only place that some trickery is needed
+%D to fool the multilingual interface. However, long ago
+%D we decided to stick to \s!text in definitions as it closely
+%D relates to the math model where text, script and scriptscript
+%D are used untranslated. Also, we are now english at the low
+%D level so it cannot go wrong anymore.
+%D
+%D When instead of a size the keyword \type{unknown} is
+%D passed, fractions (relations) are used instead of fixed
+%D sizes.
+
+\let\bodyfontenvironmentlist\empty
+
+\newcount\@@fontdefhack % check if this is still needed
+
+\def\@@beginfontdef
+ {\ifcase\@@fontdefhack
+ \let\k!savedtext \k!text \let\k!text \s!text
+ \let\k!k!savedtext \k!k!text \let\k!k!text \!!plusone
+ \let\k!saveddefault \k!default \let\k!default \s!default
+ \let\k!k!saveddefault\k!k!default \let\k!k!default \!!plusone
+ \fi
+ \advance\@@fontdefhack \plusone }
+
+\def\@@endfontdef
+ {\advance\@@fontdefhack \minusone
+ \ifcase\@@fontdefhack
+ \let\k!k!default\k!k!saveddefault
+ \let\k!default \k!saveddefault
+ \let\k!k!text \k!k!savedtext
+ \let\k!text \k!savedtext
+ \fi}
+
+\unexpanded\def\definebodyfontenvironment
+ {\dotripleempty\dodefinebodyfontenvironment}
+
+\def\dodefinebodyfontenvironment[#1][#2][#3]% class size settings
+ {\ifthirdargument
+ \@@beginfontdef
+ \doifelse{#2}\s!default
+ {\getparameters[\??ft\s!default][#3]}
+ {\normalizebodyfontsize#2\to\tempbodyfontsize
+ \addtocommalist\tempbodyfontsize\bodyfontenvironmentlist
+ \@EA\dododefinebodyfontenvironment\@EA[\tempbodyfontsize][#1][#3]}%
+ \@@endfontdef
+ \else
+ \ifx\fontclass\empty\else
+ \writestatus\m!fonts{beware: fontclass ignored (if needed use: [fontclass][size][settings])}%
+ \fi
+ \pushmacro\fontclass
+ \let\fontclass\empty
+ \definebodyfontenvironment[\fontclass][#1][#2]% change */*
+ \popmacro\fontclass
+ \fi}
+
+\def\dododefinebodyfontenvironment[#1][#2][#3]% size class settings
+ {\@@beginfontdef % \s!text goes wrong in testing because the 12pt alternative will called when typesetting the test (or so)
+ \ifcsname\??ft#2#1\c!em\endcsname
+ % we test for em as we assume it to be set
+ \else
+ \def\docommand##1%
+ {\scratchdimen\csname\??ft\s!default##1\endcsname\dimexpr#1\relax
+ \normalizebodyfontsize\scratchdimen\to\tempbodyfontsize
+ \letvalue{\??ft#2#1##1}\tempbodyfontsize}%
+ \processcommacommand[\fontrelativesizelist]\docommand
+ \copyparameters
+ [\??ft#2#1][\??ft\s!default]
+ [\c!interlinespace,\c!em]%
+ \fi
+ \getparameters[\??ft#2#1][#3]%
+ \@@endfontdef
+ % new code, see remark
+ \ifloadingfonts
+ % only runtime
+ \else\ifcsname\@size@#1\endcsname
+ % only once
+ \else
+ % prevent loop (hence \empty)
+ \letvalue{\@size@#1}\empty
+ \pushmacro\fontclass % new per 26102009
+ \edef\fontclass{#2}% % new per 26102009
+ \defineunknownfont{#1}%
+ \popmacro\fontclass % new per 26102009
+ \fi\fi
+ % so far
+ \setvalue{\@size@#1}{\docompletefontswitch[#1]}}
+
+%D {\bf Remark:} We need to cover the following cases,
+%D otherwise users can get confused:
+%D
+%D \starttyping
+%D \setupbodyfont[23pt]
+%D
+%D \definebodyfontenvironment[23pt]
+%D \setupbodyfont[23pt]
+%D
+%D \definebodyfontenvironment[23pt]
+%D \definebodyfont[23pt][rm,ss,tt][default]
+%D \setupbodyfont[23pt]
+%D \stoptyping
+
+%D Beware: while some font defs can be global, the bodyfont
+%D environment checks local. This means that multiple local
+%D checks resulting in definitions are not that efficient.
+%D So, apart from an occasional switch, one should define an
+%D environment at the outer level.
+
+\def\checkbodyfontenvironment[#1]%
+ {\definebodyfontenvironment[\fontclass][#1][]}
+
+\def\checkbodyfontenvironment[#1]%
+ {\ifcsname\??ft\fontclass#1\c!em\endcsname
+ % we test for em as we assume it to be set
+ \else
+ \definebodyfontenvironment[\fontclass][#1][]%
+ \fi}
+
+% this one already catches both define/setup
+
+\let\setupbodyfontenvironment\definebodyfontenvironment
+
+%D Just a couple of interface macros:
+
+\def\bodyfontvariable#1%
+ {\??ft\ifcsname\??ft\fontclass#1\endcsname\fontclass\fi#1}
+
+\def\bodyfontinterlinespecs
+ {\bodyfontvariable{\normalizedbodyfontsize\c!interlinespace}}
+
+\def\bodyfontinterlinespace
+ {\csname\bodyfontinterlinespecs\endcsname}
+
+%D We default all parameters to the main bodyfont size (begin
+%D \type{#1}), so the next setup is valid too:
+%D
+%D \starttyping
+%D \definebodyfontenvironment[24pt]
+%D \stoptyping
+%D
+%D All parameters can be redefined when needed, so one does
+%D not have to stick to the default ones.
+
+%D \macros
+%D {definebodyfont}
+%D
+%D The next step in defining a bodyfont involves the actual font
+%D files, which can be recognized by their extension
+%D \type{tfm}. Installing those file is often beyond the
+%D scope of the user and up to the system administrator.
+%D
+%D \showsetup{definebodyfont}
+%D
+%D This commands takes three arguments: a (series of) bodyfont
+%D size(s), the style group to which the definitions belong,
+%D and an alternative, as specified by the \TEX\ (math) families,
+%D extended with~a, b~\unknown.
+%D
+%D We show two examples, that show all the alternative
+%D scaling options. The \type{\tfa} alternatives can be
+%D extended with \type{\bfa}, \type{\slb}, etc. or even
+%D \type{e} and higher alternatives. The magic scaled
+%D values are derived from plain \TEX's \type {\magstep}:
+%D
+%D \starttyping
+%D \definebodyfont [12pt] [rm]
+%D [tf=cmr12,
+%D bf=cmbx12,
+%D it=cmti12,
+%D sl=cmsl12,
+%D bi=cmbxti10 at 12pt,
+%D bs=cmbxsl10 at 12pt,
+%D tfa=cmr12 scaled 1.200,
+%D tfb=cmr12 scaled 1.440,
+%D tfc=cmr12 scaled 1.728,
+%D tfd=cmr12 scaled 2.074,
+%D sc=cmcsc10 at 12pt]
+%D
+%D \definebodyfont [12pt,11pt,10pt,9pt,8pt] [rm]
+%D [tf=lbr sa 1,
+%D bf=lbd sa 1,
+%D it=lbi sa 1,
+%D sl=lbsl sa 1,
+%D bi=lbdi sa 1,
+%D bs=lbdi sa 1,
+%D tfa=lbr sa 1.200,
+%D tfb=lbr sa 1.440,
+%D tfc=lbr sa 1.728,
+%D tfd=lbr sa 2.074,
+%D sc=lbr sa 0.833]
+%D \stoptyping
+%D
+%D The second example shows that we can define more sizes at
+%D once. The main difference between these examples is that the
+%D Computer Modern Roman come in many design sizes. This means
+%D that there we cannot define them in bulk using \type{sa}.
+%D Instead of \type{rm} (roman) one can define \type{ss} (sans
+%D serif), \type{tt} (teletype), \type{hw} (hand written),
+%D \type{cg} (calygraphic) and whatever styles.
+%D
+%D The first argument may be a comma separated list. This,
+%D combined with specifications using \type{sa} can save a lot
+%D of typing. Although all arguments should be specified, we
+%D treat the second argument as optional.
+%D
+%D Defining a bodyfont involves two actions: defining the
+%D specific style related alternatives, like \type{\rma},
+%D \type{\bfa} and \type{\rmsla}, and storing the definitions
+%D of their bodyfont size related fonts. The first step is
+%D bodyfont independant but executed every time. This permits
+%D user definitions like \type{\tfw} or \type{\bfq} for real
+%D large alternatives.
+
+\unexpanded\def\definebodyfont
+ {\doquadrupleempty\redefinebodyfont}
+
+\def\redefinebodyfont[#1][#2][#3][#4]%
+ {\iffourthargument
+ \processcommacommand[#1]{\reredefinebodyfont[#2][#3][#4]}%
+ \else
+ \dodefinebodyfont[#1][#2][#3]%
+ \fi}
+
+\def\reredefinebodyfont[#1][#2][#3]#4%
+ {\pushmacro\fontclass
+ \doifelse{#4}\s!default
+ {\let\fontclass\empty}
+ {\def\fontclass{#4}}%
+ \definebodyfont[#1][#2][#3]%
+ \popmacro\fontclass}
+
+\def\dodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier
+ {\ifthirdargument
+ \doifnumberelse{#1}
+ {\doifassignmentelse{#3}
+ {% [12pt] [style] [settings]
+ \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new
+ \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}}
+ {% [12pt] [style] [identifier]
+ \dodefinedefaultbodyfont[#1][#2][#3]}} % body style identifier
+ {% [identifier] [style] [settings] % see ***
+ \setvalue{\s!default#1#2}##1##2{\normalexpanded{\noexpand\xdodefinebodyfont[##1][##2][#3]}}}%
+ \else\ifsecondargument
+ \definebodyfont[#1][\c!rm][#2]%
+ \else
+ % Maybe there are default dependencies defined which we can use ([unknown]) and
+ % if not, then we have at least to make sure some basics are set up.
+ \ifcsname\@size@#1\endcsname \else
+ \defineunknownfont{#1}%
+ \fi
+ \ifcsname\@size@#1\endcsname \else
+ \definebodyfont[#1][\c!rm][]%
+ \fi
+ \fi\fi}
+
+\def\xdodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier
+ {\checkrelativefontsize{#2}% rather new, inherit from other defs
+ \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new
+ \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}%
+ \let\relativefontsize\defaultrelativefontsize}
+
+\def\dododefinebodyfont#1#2#3% style defs body
+ {\checkbodyfontenvironment[#3]% just to be sure.
+ \processcommalist[#2]{\dodododefinebodyfont{#1}{#3}}}
+
+\def\dodododefinebodyfont#1#2#3% style body def
+ {\dododododefinebodyfont{#1}{#2}[#3]}
+
+\def\dododododefinebodyfont
+ {\ifx\fontclass\empty
+ \expandafter\dododododefinebodyfontnop
+ \else
+ \expandafter\dododododefinebodyfontyes
+ \fi}
+
+\def\dododododefinebodyfontyes#1% style body def
+ {\edef\askedbodyfontstyle{#1}%
+ \ifx\askedbodyfontstyle\c!mm
+ \expandafter\dodefinebodyfontyesmm
+ \else
+ \expandafter\dodefinebodyfontyesxx
+ \fi\askedbodyfontstyle} % we can get rid of #1
+
+\def\dododododefinebodyfontnop#1% style body def
+ {\edef\askedbodyfontstyle{#1}%
+ \ifx\askedbodyfontstyle\c!mm
+ \expandafter\dodefinebodyfontnopmm
+ \else
+ \expandafter\dodefinebodyfontnopxx
+ \fi\askedbodyfontstyle} % we can get rid of #1
+
+\def\dodefinebodyfontnopxx#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \@EA\let\csname*#2#1#3#4#5*\endcsname\undefined
+ \unexpanded\@EA\edef\csname#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}}
+
+\def\dodefinebodyfontyesxx#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#5*\endcsname\undefined
+ \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}}
+
+\def\dodefinebodyfontnopmm#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \@EA\let\csname*#2#1#3#4#51*\endcsname\undefined
+ \@EA\let\csname*#2#1#3#4#52*\endcsname\undefined
+ \@EA\let\csname*#2#1#3#4#53*\endcsname\undefined
+ \unexpanded\@EA\edef\csname#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}%
+ \unexpanded\@EA\edef\csname#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}%
+ \unexpanded\@EA\edef\csname#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}}
+
+\def\dodefinebodyfontyesmm#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#51*\endcsname\undefined
+ \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#52*\endcsname\undefined
+ \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#53*\endcsname\undefined
+ \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}%
+ \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}%
+ \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}}
+
+\def\checkbodyfont#1% tests for ttsl mmbf
+ {\edef\c!!mm{#1}%
+ \ifx\c!!mm\c!mm % prevents \max and alike (re)defs
+ \expandafter\checkmathbodyfont
+ \else
+ \expandafter\checktextbodyfont
+ \fi{#1}} % no \c!!mm, not expanded later on
+
+% some day we can do an auto-fam if needed
+
+\def\checkmathbodyfont#1#2#3% style alt size / gdef % #3 can be empty
+ {%\message{!m #1 #2 #3!}%
+ % #1 #2 #3 = signal
+ %setugvalue {#2}{\setcurrentfontalternative {#2}}% \mr \mb
+ \setugvalue {#1}{\setcurrentfontstyle {#1}}}% \mm
+
+\def\checktextbodyfont#1#2#3% style alt size / gdef % #3 can be empty
+ {%\message{!t #1 #2 #3!}%
+ \setugvalue {#1#3}{\setcurrentfontstylesize {#1}{#3}}% \rma
+ \setugvalue {#2#3}{\setcurrentfontalternativesize {#2}{#3}}% \sla
+ \setugvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \rmsla
+ \setugvalue {#1}{\setcurrentfontstyle {#1}}% \rm
+ \setugvalue {#2}{\setcurrentfontalternative {#2}}% \sl
+ \setugvalue {#1\c!x}{\setcurrentfontxstylealternative {#1}}% \rmx
+ \setugvalue{#1\c!xx}{\setcurrentfontxxstylealternative {#1}}% \rmxx
+ \setugvalue {#2\c!x}{\setcurrentfontxalternative {#2}}% \slx
+ \setugvalue{#2\c!xx}{\setcurrentfontxxalternative {#2}}% \slxx
+ \setugvalue {#1#2}{\setcurrentfontstylealternative {#1}{#2}}}% \rmsl
+
+\def\dodefinedefaultbodyfont[#1][#2][#3]% sizes styles identifier
+ {\def\dododefinedefaultbodyfont##1%
+ {\def\dodododefinedefaultbodyfont####1%
+ {\def\dododododefinedefaultbodyfont########1%
+ {\ifcsname\s!default########1####1\endcsname
+ % [12pt] [style] [identifier]
+ \csname\s!default########1####1\endcsname{##1}{####1}%
+ \fi}%
+ \processcommalist[#3]\dododododefinedefaultbodyfont}%
+ \processcommalist[#2]\dodododefinedefaultbodyfont}%
+ \processcommalist[#1]\dododefinedefaultbodyfont}
+
+%D Unknown families are added to the family list! For the
+%D moment we also set the direct calls here. Some day a better
+%D solution will be implemented. The good news is that unknown
+%D fonts are defined automatically.
+
+\newif\ifdefiningunknownfont
+
+\def\dodefineunknownfont#1#2%
+ {\ifcsname\??ft\s!default#2\endcsname
+ \donetrue
+ \normalizebodyfontsize\csname\??ft\s!default#2\endcsname\dimexpr#1\relax\to\tempbodyfontsize
+ \letvalue{\??ft#1#2}\tempbodyfontsize
+ \fi}
+
+\def\dodefineunknownbodyfont#1#2% see ***
+ {\ifcsname\s!default\s!default#2\endcsname % somehow related to */*
+ \donetrue
+ \csname\s!default\s!default#2\endcsname{#1}{#2}%
+ \fi}
+
+\def\dodefineunknownsubfont#1#2%
+ {\ifcsname\@size@\csname\??ft#1#2\endcsname\endcsname
+ \else
+ \donetrue
+ \defineunknownfont{\csname\??ft#1#2\endcsname}%
+ \fi}
+
+\unexpanded\def\defineunknownfont#1%
+ {\let\c!savedtext\c!text
+ \let\c!text\s!text
+ \donefalse
+ \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}%
+ \let\c!text\c!savedtext
+ \ifdone
+ \donefalse
+ \processcommacommand
+ [\fontstylelist]
+ {\dodefineunknownbodyfont{#1}}%
+ \ifdone
+ \donefalse
+ \setvalue{\@size@#1}{\docompletefontswitch[#1]}%
+ \ifdefiningunknownfont \else
+ \definingunknownfonttrue
+ \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}%
+ \definingunknownfontfalse
+ \fi
+ \fi
+ \ifdone
+ \showmessage\m!fonts{14}{#1}%
+ \fi
+ \fi}
+
+%D These macros show that quite some definitions take place.
+%D Fonts are not loaded yet! This means that at format
+%D generation time, no font files are preloaded.
+
+%D \macros
+%D {everybodyfont,Everybodyfont,everyglobalbodyfont}
+%D
+%D Every change in bodyfont size has conseqences for the baseline
+%D distance and skips between paragraphs. These are initialized
+%D in other modules. Here we only provide the hooks that
+%D garantees their handling.
+
+%D At the system level one can initialize thing like:
+%D
+%D \starttyping
+%D \appendtoks \setupspacing \to \everybodyfont
+%D \stoptyping
+%D
+%D While users can add their own non standard commands like:
+%D
+%D \starttyping
+%D \EveryBodyFont{\message{changing to bodyfont \the\bodyfontsize}}
+%D \stoptyping
+%D
+%D Personnaly I never felt the need for such extensions, but
+%D at least its possible.
+
+%D \macros
+%D {globalbodyfontsize,localbodyfontsize}
+%D
+%D Next we'll do the tough job of font switching. Here we
+%D have to distinguish between the global (overal) bodyfont
+%D size and the local (sometimes in the textflow) size. We
+%D store these dimensions in two \DIMENSION\ registers.
+
+\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt
+\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize
+
+%D \macros
+%D {bodyfontsize}
+%D
+%D These two registers are not to be misused in calculations.
+%D For this purpose we keep a copy:
+
+\newdimen\bodyfontsize \bodyfontsize=\globalbodyfontsize
+
+%D \macros
+%D {bodyfontfactor,bodyfontpoints}
+%D
+%D For multiplication purposes we keep an auxiliary counter
+%D and macro (here the expansion is not explicitly needed):
+
+\newcount\bodyfontpoints \dimensiontocount\bodyfontsize\bodyfontpoints
+
+\edef\bodyfontfactor{\withoutpt\the\bodyfontsize}
+
+%D When we assign for instance 12pt to a \DIMENSION\ register
+%D the \type{\the}'d value comes out as 12.0pt, which is
+%D often not the way users specify the bodyfont size. Therefore
+%D we also store the normalized value.
+
+\chardef\fontdigits=2 % was 1
+
+% \def\normalizebodyfontsize#1\to#2%
+% {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}
+%
+% \def\donormalizedbodyfontsize#1.#2#3#4#5\to#6% \points ?
+% {\edef#6% not \ifcase#2\else due to \relax adding
+% {#1%
+% \ifcase\fontdigits
+% \or \ifcase#2 \else .#2\fi % 1
+% \or \ifcase#2#3 \else .#2\ifcase#3 \else #3\fi\fi % 2
+% \else \ifcase#2#3#4 \else .#2\ifcase#4 \ifcase#3 \else#3\fi \else#3#4\fi\fi % 3
+% \fi
+% \s!pt}}
+
+\def\normalizebodyfontsize#1\to#2%
+ {\edef#2{\ctxlua{fonts.nbfs(\number\dimexpr#1\relax,\number\fontdigits)}}}
+
+\def\thenormalizedbodyfontsize#1%
+ {\ctxlua{fonts.nbfs(\number\dimexpr#1\relax,\number\fontdigits)}}
+
+\normalizebodyfontsize\bodyfontsize\to\normalizedglobalbodyfontsize
+\normalizebodyfontsize\bodyfontsize\to\normalizedlocalbodyfontsize
+\normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize
+
+%D \macros
+%D {fontstyle,fontalternative,fontsize}
+%D
+%D Within a bodyfont, fonts can come in different sizes. For
+%D instance \type{\tf} is accompanied by \type{\tfa},
+%D \type{\tfb} etc. The first two characters denote the
+%D alternative, while the third character in these sequences
+%D represents the size. The actual size is saved in a macro
+%D
+%D The style, being roman (\type{\rm}), sans serif (\type{\ss})
+%D etc. is also available in a macro in \type{rm}, \type{ss}
+%D etc. form:
+
+\let\defaultfontalternative = \c!tf
+\let\defaultfontstyle = \empty
+\let\defaultfontsize = \empty
+
+\let\fontalternative = \defaultfontalternative
+\let\fontstyle = \defaultfontstyle
+\let\fontsize = \defaultfontsize
+
+%D When \type {\loadfontfileoncetrue}, such files are
+%D only loaded once! This permits redundant loading, but at
+%D the same time forced grouping when we want continuously mix
+%D all kind of font, which of course is a kind of
+%D typographically sin. The \type{"} is made inactive if
+%D needed to prevent problems with loading files that use this
+%D character in numbers.
+
+% can be made faster (only used internally now)
+
+\def\doswitchpoints[#1]%
+ {\normalexpanded{\dodoswitchpoints{#1}}}
+
+\unexpanded \def\dodoswitchpoints#1%
+ {\ifcsname\@size@#1\endcsname \else
+ \defineunknownfont{#1}%
+ \fi%
+ %\defineunknownfontstyles{#1}%
+ \ifcsname\@size@#1\endcsname
+ \csname\@size@#1\endcsname
+ \localbodyfontsize#1\relax
+ \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize
+ % \edef\fontbody{\fontbody}% to be tested but we can clean up mkiv further
+ \checkbodyfontenvironment[\normalizedbodyfontsize]%
+ \else
+ \showmessage\m!fonts4{#1}%
+ \fi}
+
+\unexpanded \def\doswitchstyle[#1]%
+ {\ifcsname\@style@#1\endcsname
+ \csname\@style@#1\endcsname
+ \edef\fontstyle{#1}%
+ \ifmmode\mr\fi % in order to be compatible with \rm in math mode
+ % \the\everybodyfont % cleaner, in setting size as well as style
+ \else
+ \showmessage\m!fonts5{#1}%
+ \fi}
+
+%D \TEX\ loads font metric files like \type{cmr10.tfm} and
+%D \type{tir.tfm} only once. In \PLAIN\ \TEX\ some font files
+%D are {\em preloaded}. This means that the font files are
+%D loaded, but not accessible yet by name. This is accomplished
+%D by saying:
+%D
+%D \starttyping
+%D \font\preloaded=cmr10 at 11pt
+%D \stoptyping
+%D
+%D and using the name \type{\preloaded} again and again, so
+%D fonts are indeed loaded, but unnamed, and therefore
+%D unaccessible. In \CONTEXT\ we don't preload fonts, not even
+%D the \PLAIN\ \TEX\ ones, although users can access them. Now
+%D why is this done?
+
+%D Defining fonts using \type{\definebodyfont} takes time, so we
+%D prefer to predefine at least the Computer Modern Roman
+%D fonts. However, loading all those fonts at definition time
+%D would take both time and space. But even worse, once fonts
+%D are loaded into memory, their encoding vector is fixed,
+%D which is a handicap when we want to distribute the compact
+%D \type{fmt} files. So what we want to do is defining fonts in
+%D a way that postpones the loading. We accomplish this by only
+%D loading the fonts when we switch to another bodyfont size.
+%D Among the other alternatives, such as loading the font at
+%D the moment of activation and redefining the activation
+%D macro afterwards, this proved to be the most efficient
+%D alternative.
+%D
+%D The next few macros take care of the one exeption on this
+%D scheme. When at format generation time we load the default
+%D font file, the one that defines the Computer Modern Fonts,
+%D we don't want the fonts metrics to end up in the format
+%D file, so we temporary prohibit loading. This means that at
+%D runtime we have to load the default bodyfont size just before
+%D we start typesetting.
+%D
+%D Therefore we have to signal the font switching macros that
+%D we are preloading fonts. As long as the next boolean is,
+%D true, no loading is done.
+
+\newif\ifloadingfonts \loadingfontstrue
+
+%D \macros
+%D {preloadfonts}
+%D
+%D Preloading is only called for once, during the startup
+%D sequence of a session. After the loading job is done, the
+%D macro relaxes itself and reset the signal.
+
+% \appendtoks
+% \to \everysetupdocument
+
+\newconditional\fontsareloaded
+
+\def\preloadfonts % never called, needs a clean up
+ {\global\loadingfontsfalse
+ \ifconditional\fontsareloaded \else
+ \doifmodeelse {*nofonts}
+ {\writestatus\m!fonts{latin modern fonts are not preloaded}}
+ {\writestatus\m!fonts{preloading latin modern fonts}%
+ \usetypescript[modern]%
+ \setuptypeface[modern]%
+ \showmessage\m!fonts6{\normalizedbodyfontsize\normalspace\fontstyle}}%
+ \fi
+ \global\let\preloadfonts\relax}
+
+% maybe add this to \everystarttext
+%
+% \ifconditional\fontsareloaded\else
+% \usetypescript[modern]%
+% \setuptypeface[modern]%
+% \fi
+
+%D Here comes the main font switching macros. These macros
+%D handle changes in size as well as returning to the global
+%D bodyfont size.
+
+\def\dosetfont#1#2% #1 = set/switch state
+ {\doifelse{#2}\v!global
+ {\restoreglobalbodyfont}
+ {\processcommacommand[#2]{\dodosetfont{#1}}% ##1 get also passed
+ \ifloadingfonts\else
+ \global\settrue\fontsareloaded
+ \doswitchpoints[\normalizedbodyfontsize]%
+ \doswitchstyle[\fontstyle]%
+ \ifx\defaultfontclass\empty
+ \let\defaultfontclass\fontclass
+ \fi
+ \fi}%
+ \chardef\currentxfontsize\zerocount}
+
+\def\dodosetfont#1#2% #1 = set/switch state | check fo rempty, else space
+ {\doifsomething{#2}{\dododosetfont{#1}{#2}{\showmessage\m!fonts4{#2}}}}
+
+% % % this can be retrofitted in mkii code % % %
+
+% \def\normalizebodyfontsize#1\to#2%
+% {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}
+
+\def\dododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii
+ {\doifnumberelse{#2}\dodododosetfont\redododosetfont{#1}{#2}{#3}}
+
+\def\redododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii
+ {\edef\expandedfontthing{#2}%
+ \def\interfacedfontsize{\normalizedbodyfontsize\interfaced\expandedfontthing}%
+ \ifcsname\??ft\interfacedfontsize\endcsname
+ \edef\fontstep{\csname\bodyfontvariable\interfacedfontsize\endcsname}%
+ \normalexpanded{\noexpand\dodododosetfont{#1}{\fontstep}}{#3}%
+ \else\ifx\expandedfontthing\v!reset
+ \let\fontstyle\empty % new 31/7/2006
+ \let\fontsize \empty
+ \else
+ \ifcsname\@style@\expandedfontthing\endcsname
+ \let\fontstyle\expandedfontthing
+ \else
+ \setcurrentfontclass\expandedfontthing
+ \ifcase#1\relax
+ \let\globalfontclass\globalfontclass
+ \else
+ \let\globalfontclass\fontclass
+ \fi
+ \ifx\fontclass\empty
+ \let\fontstyle\c!rm
+ \else\ifcsname\??tf\fontclass\s!default\endcsname
+ \edef\fontstyle{\csname\??tf\fontclass\s!default\endcsname}%
+ \else
+ \let\fontstyle\c!rm
+ \fi\fi
+ \fi
+ \fi\fi}
+
+\def\dodododosetfont#1#2#3% #1 = set/switch state
+ {\normalizebodyfontsize#2\to\normalizedsetfont
+ \ifcsname\@size@\normalizedsetfont\endcsname \else
+ \defineunknownfont{#2}%
+ \fi
+ \ifcsname\@size@\normalizedsetfont\endcsname
+ \localbodyfontsize\normalizedsetfont
+ \let\normalizedbodyfontsize\normalizedsetfont
+ \else
+ #3\dosetsubstitutefont{#1}{#2}%
+ \fi}
+
+% % %
+
+%D In the previous macros we use \type{\currentxfontsize} to
+%D hold the current x||size of the font. This enables us to
+%D support for instance \type{\sl} inside a \type{\tx} switch.
+
+\chardef\currentxfontsize=0
+
+%D When users specify for instance a 13 point bodyfont while no
+%D such bodyfont is defined, the system automatically tries to
+%D find a best fit, that is the nearest smaller defined
+%D bodyfontzize. A smaller one is definitely better than a larger
+%D one, simply because otherwise a lot of overfull box messages
+%D are more probable to occur. By taking a value slightly
+%D smaller than half a point, we can use the next method.
+
+\def\dosetsubstitutefont#1#2% #1 = set/switch state
+ {\scratchdimen#2\relax
+ \advance\scratchdimen .499\points
+ \dimensiontocount\scratchdimen\scratchcounter
+ \advance\scratchcounter \minusone
+ \ifnum\scratchcounter>\plusthree
+ \dododosetfont{#1}{\the\scratchcounter\s!pt}{}%
+ \fi}
+
+% The following bunch of macros deals with the (run time)
+% expansion of names onto the definitions made by \type
+% {\definebodyfont}.
+
+% \let\fontbody \empty % ... 10pt 11pt 12pt ...
+% \let\fontstyle \empty % rm ss tt mm hw cg ...
+% \let\fontalternative\empty % tf bf sl it bs bi sc ...
+% \let\fontsize \empty % xy-abcd ...
+
+\def\defaultfontbody{\normalizedbodyfontsize}
+
+\let\fontbody\defaultfontbody
+
+\let\fontclass\empty \let\globalfontclass\fontclass
+
+% we need to check the fontclass
+
+\def\registerfontclass#1%
+ {\letgvalue{\@fontclass@#1}\v!yes} % global ?
+
+\edef\@no@fontclass@{\@fontclass@:?:}
+
+\def\setcurrentfontclass#1%
+ {\ifcsname\@fontclass@#1\endcsname
+ \edef\fontclass{#1}%
+ \else\ifcsname\@no@fontclass@#1\endcsname
+ % already tried
+ \else\ifcase\currentgrouplevel
+ \trycurrentfontclass{#1}%
+ \fi\fi\fi}
+
+\def\savefontclassparameters#1#2#3#4% #1=rm|ss|.. rscale features fallbacks
+ {\setxvalue{\fontclass#1\s!rscale }{#2}%
+ \setxvalue{\fontclass#1\s!features }{#3}%
+ \setxvalue{\fontclass#1\s!fallbacks}{#4}}
+
+\settrue\autotypescripts
+
+% \def\trycurrentfontclass#1%
+% {\ifconditional\autotypescripts
+% \usetypescript[#1]%
+% \ifcsname\@fontclass@#1\endcsname
+% \edef\fontclass{#1}%
+% \else
+% \letvalue{\@no@fontclass@#1}\empty
+% \fi
+% \else
+% \letvalue{\@no@fontclass@#1}\empty
+% \fi}
+
+\def\trycurrentfontclass#1%
+ {\ifconditional\autotypescripts
+ % try to load typescript #1
+ \usetypescript[#1]%
+ \ifcsname\@fontclass@#1\endcsname
+ \edef\fontclass{#1}%
+ \else
+ % try to load type-#1.mkiv
+ \usetypescriptfile[\f!typeprefix#1]%
+ % try to load typescript #1
+ \usetypescript[#1]%
+ \ifcsname\@fontclass@#1\endcsname
+ \edef\fontclass{#1}%
+ \else
+ % todo: message
+ \letvalue{\@no@fontclass@#1}\empty
+ \fi
+ \fi
+ \else
+ % todo: message
+ \letvalue{\@no@fontclass@#1}\empty
+ \fi}
+
+\let\defaultfontstyle \c!rm
+\let\defaultfontalternative \c!tf
+\let\defaultfontsize \empty
+
+%D \macros
+%D {bigmath,nobigmath}
+%D
+%D We can inhibit this slow||downer with:
+
+% these can best be combined
+
+% 0=never 1=everymath 2=always
+
+\chardef\synchronizebigmathflag=1
+
+\appendtoks
+ \ifcase\synchronizebigmathflag
+ % never
+ \or
+ \synchronizebigmath
+ \or
+ % always
+ \fi
+\to \everymathematics
+
+\def\nobigmath {\chardef\synchronizebigmathflag\zerocount}
+\def\autobigmath{\chardef\synchronizebigmathflag\plusone\synchronizebigmath}
+\def\bigmath {\chardef\synchronizebigmathflag\plustwo\synchronizebigmath}
+
+\let\bigmathfontsize\empty
+
+\def\synchronizebigmath
+ {\ifx\bigmathfontsize\fontsize
+ % already in sync
+ \else
+ \let\bigmathfontsize\fontsize
+ \synchronizemath
+ \fi}
+
+\def\checkbigmathsynchronization
+ {\ifcase\synchronizebigmathflag
+ % never
+ \or
+ \ifmmode \synchronizebigmath \fi
+ \or
+ \synchronizebigmath
+ \fi}
+
+%D So far for synchronisation. (We can inline the following macros.)
+
+\def\dosetcurrentfontsize#1%
+ {\edef\fontsize{#1}%
+ \checkbigmathsynchronization}
+
+\def\dosetcurrentfontalternative#1%
+ {\edef\fontalternative{#1}}
+
+\def\setcurrentfont#1#2#3#4%
+ {%\message{[1 #1 #2 #3 #4]}%
+ \edef\fontbody{#1}%
+ \edef\fontstyle{#2}%
+ \dosetcurrentfontalternative{#3}%
+ \dosetcurrentfontsize{#4}%
+ \synchronizefont}
+
+\def\setcurrentfontbody#1%
+ {%\message{[2 #1]}%
+ \edef\fontbody{#1}%
+ \synchronizefont}
+
+% For Taco: optional fall backs:
+
+\ifx\checkfontclass\undefined \let\checkfontclass\gobbleoneargument \fi % implemented in type-ini
+
+% \def\setcurrentfontstyle#1%
+% {%\message{[3 #1]}%
+% \checkfontclass{#1}%
+% \edef\fontstyle{#1}%
+% \ifmmode\mr\fi % otherwise \rm not downward compatible
+% \synchronizefont}
+
+\def\setcurrentfontstyle#1%
+ {%\message{[3 #1]}%
+ \edef\fontstyle{#1}%
+ \checkfontclass\fontstyle
+ \ifmmode\mr\fi % otherwise \rm not downward compatible
+ \synchronizefont}
+
+\def\setcurrentfontbodyalternative#1#2%
+ {%\message{[4 #1 #2]}%
+ \edef\fontbody{#1}%
+ \dosetcurrentfontalternative{#2}%
+ \synchronizefont}
+
+\def\setcurrentfontalternative#1%
+ {%\message{[5 #1]}%
+ \dosetcurrentfontalternative{#1}%
+ \synchronizefont}
+
+\def\setcurrentfontsize#1%
+ {%\message{[6 #1]}%
+ \dosetcurrentfontsize{#1}%
+ \synchronizefont}
+
+\def\setcurrentfontstylealternative#1#2% \rmsl
+ {%\message{[7 #1 #2]}%
+ \edef\fontstyle{#1}%
+ \dosetcurrentfontalternative{#2}%
+ \synchronizefont}
+
+\def\setcurrentfontstylesize#1#2% \rmsla
+ {%\message{[8 #1 #2]}%
+ \edef\fontstyle{#1}%
+ \dosetcurrentfontsize{#2}%
+ \synchronizefont}
+
+\def\setcurrentfontalternativesize#1#2% \sla
+ {%\message{[9 #1 #2]}%
+ \dosetcurrentfontalternative{#1}%
+ \dosetcurrentfontsize{#2}%
+ \synchronizefont}
+
+\def\setcurrentfontstylealternativesize#1#2#3% \rmsla
+ {%\message{[10 #1 #2 #3]}%
+ \edef\fontstyle{#1}%
+ \dosetcurrentfontalternative{#2}%
+ \dosetcurrentfontsize{#3}%
+ \synchronizefont}
+
+%D In principle one can assign alternative fallback routines.
+%D Some day we will.
+
+\newtoks\fontstrategies
+\newif\iftryingfont
+
+\let\fontstrategy\relax
+
+\def\synchronizefont % we can have dups i.e. no need to let fontstrategy
+ {\tryingfonttrue
+ \ifx\fontclass\empty
+ \applyfontstrategies
+ \else
+ \applyfontclassstrategies
+ \fi
+ \autofontsizefalse
+ \ifskipfontcharacteristics
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \fi}
+
+\def\fontclassstrategiesa % --- --- --- --- % pt tt bf a
+ {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname
+ \autofontsizefalse
+ \csname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname
+ \else
+ \expandafter\fontclassstrategiesb
+ \fi}
+
+\def\fontclassstrategiesb % --- --- --- def % pt tt bf
+ {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
+ \autofontsizetrue
+ \csname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontclassstrategiesc
+ \fi}
+
+\def\fontclassstrategiesc % --- --- def --- % pt tt tf a
+ {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
+ \autofontsizetrue
+ \csname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
+ \else
+ \expandafter\fontclassstrategiesd
+ \fi}
+
+\def\fontclassstrategiesd % --- --- def def % pt tt tf
+ {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \autofontsizetrue
+ \csname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontclassstrategiese
+ \fi}
+
+\def\fontclassstrategiese % --- def def def % pt rm tf
+ {\ifcsname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \autofontsizefalse
+ \csname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontclassstrategiesf
+ \fi}
+
+\def\fontclassstrategiesf % def def def def % rm tf
+ {\ifcsname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \autofontsizetrue
+ \csname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontstrategiesa
+ \fi}
+
+% no class
+
+\def\fontstrategiesa % --- --- --- --- % pt tt bf a
+ {\ifcsname\fontbody \fontstyle \fontalternative \fontsize\endcsname
+ \autofontsizefalse
+ \csname\fontbody \fontstyle \fontalternative \fontsize\endcsname
+ \else
+ \expandafter\fontstrategiesb
+ \fi}
+
+\def\fontstrategiesb % --- --- --- --- % pt tt bf a
+ {\ifcsname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
+ \autofontsizetrue
+ \csname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontstrategiesc
+ \fi}
+
+\def\fontstrategiesc % --- --- --- --- % pt tt bf a
+ {\ifcsname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
+ \autofontsizetrue
+ \csname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
+ \else
+ \expandafter\fontstrategiesd
+ \fi}
+
+\def\fontstrategiesd % --- --- --- --- % pt tt bf a
+ {\ifcsname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \autofontsizetrue
+ \csname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontstrategiese
+ \fi}
+
+\def\fontstrategiese % --- --- --- --- % pt tt bf a
+ {\ifcsname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \autofontsizefalse
+ \csname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \else
+ \expandafter\fontstrategiesf
+ \fi}
+
+\def\fontstrategiesf % --- --- --- --- % pt tt bf a
+ {\ifcsname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \autofontsizetrue
+ \csname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
+ \fi}
+
+\let\applyfontstrategies \fontstrategiesa
+\let\applyfontclassstrategies\fontclassstrategiesa
+
+%D Let's synchronize:
+
+\newif\ifsynchronizefonts \synchronizefontstrue
+
+\prependtoks
+ \ifsynchronizefonts
+ \synchronizemath
+ \synchronizefont % problem: syncs last font
+ \fi
+\to \everybodyfont
+
+%D Setting the normal sizes as well as the x and xx smaller
+%D sizes is accomplished by the next set of macros. When in
+%D math mode, the commands \type{\tx} and \type{\txx} are
+%D just a switch to the script and double script styles, but
+%D in text mode the values defined by the bodyfontenvironment are
+%D used. Here we also set \type{\currentxfontsize}.
+
+\def\dosetcurrentfontxxxalternative#1#2#3#4%
+ {\chardef\currentxfontsize#2\relax
+ \ifmmode
+ #4%
+ \else\ifcsname\bodyfontvariable{\normalizedbodyfontsize#3}\endcsname
+ \setcurrentfontbodyalternative{\csname\bodyfontvariable\normalizedbodyfontsize#3\endcsname}{#1}%
+ \fi\fi}
+
+\def\setcurrentfontxalternative#1%
+ {\dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle
+ \let\tx\txx}
+
+\def\setcurrentfontxxalternative#1%
+ {\dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle
+ \let\tx\empty
+ \let\txx\empty}
+
+\def\checknestedxfontsize % option
+ {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else
+ \chardef\currentxfontsize\zeropoint
+ \let\fontsize\empty
+ \let\tx\normaltx
+ \let\txx\normaltxx
+ \fi\fi}
+
+\def\setcurrentfontxalternative#1%
+ {\checknestedxfontsize
+ \dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle
+ \let\tx\txx}
+
+\def\setcurrentfontxxalternative#1%
+ {\checknestedxfontsize
+ \dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle
+ \let\tx\empty
+ \let\txx\empty}
+
+% This alterative is not really needed, but for old time's sake
+% we keep it there. We can speed it up when needed.
+
+\def\setcurrentfontxstylealternative #1{\csname#1\endcsname\tx}
+\def\setcurrentfontxxstylealternative#1{\csname#1\endcsname\txx}
+
+%D These macros also show us that when we call for \type{\tx},
+%D this macro is redefined to be \type{\txx}. Therefore calls
+%D like:
+%D
+%D \startbuffer
+%D {small \tx is \tx beautiful}
+%D {small \tx is \txx beautiful}
+%D {small \txx is \tx beautiful}
+%D {small \txx is \txx beautiful}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D result in:
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D Setting the main size involves the style list and therefore
+%D takes a bit more time. Keep in mind that the fontsize is
+%D represented by a character or empty.
+
+\unexpanded\def\tx {\setcurrentfontxalternative \fontalternative}
+\unexpanded\def\txx{\setcurrentfontxxalternative\fontalternative}
+
+\let\normaltx \tx
+\let\normaltxx\txx
+
+%D \macros
+%D {definefontstyle}
+%D
+%D When setting of switching the overall style we can use the
+%D short identifier like rm and ss, but when defined we can
+%D also use more verbose names like roman or sansserif. Such
+%D names are defined by:
+%D
+%D \starttyping
+%D \definefontstyle [serif,rm] [rm]
+%D \definefontstyle [sansserif,ss] [ss]
+%D \stoptyping
+
+\def\dodefinefontstyle[#1][#2]%
+ {\rawdoifinsetelse{#2}{\fontstylelist}
+ {%\debuggerinfo\m!fonts{unknown style #2}%
+ }
+ {%\debuggerinfo\m!fonts8{#2\space (#1)}%
+ \addtocommalist{#2}\fontstylelist}%
+ % check kan hier
+ \def\docommand##1%
+ {\setvalue{\@shortstyle@##1}{#2}%
+ \setvalue{\@style@##1}{\csname#2\endcsname}}%
+ \processcommalist[#1]\docommand}
+
+\unexpanded\def\definefontstyle
+ {\dodoubleargument\dodefinefontstyle}
+
+\def\setfontstyle#1#2% #1:name (roman, romaan) #2:style (rm)
+ {\edef\fontstyle{#1}%
+ \checkfontnamecombinations
+ \setcurrentfontstyle\normalizedbodyfontsize}
+
+%D When asking for a complete font switch, for instance from 10
+%D to 12~points, the next macro does the job. First we
+%D normalize the size, next we define the current range of
+%D text, script and scriptscript sizes, then we set the text
+%D fonts and the math families and finally we activate the
+%D default typeface and also set the font specific parameters
+%D assigned to \type{\everybodyfont}
+
+\def\dosetbodyfontface#1#2%
+ {\edef#1{\csname\bodyfontvariable\normalizedbodyfontsize#2\endcsname}}
+
+\def\docompletefontswitch[#1]%
+ {\bodyfontsize#1\relax
+ \dimensiontocount\bodyfontsize\bodyfontpoints % rounded, still used in m-chart
+ \edef\bodyfontfactor{\withoutpt\the\bodyfontsize}%
+ \normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize
+ \dosetbodyfontface \textface \s!text
+ \dosetbodyfontface \scriptface \s!script
+ \dosetbodyfontface \scriptscriptface \s!scriptscript}
+
+\docompletefontswitch[12pt] % init
+
+%D \macros
+%D {setupbodyfont,switchtobodyfont}
+%D
+%D The next two macros are user ones. With \type{\setupbodyfont}
+%D one can set the document bodyfont size, font family, style
+%D and/or options defined in files, for example:
+%D
+%D \starttyping
+%D \setupbodyfont[modern,12pt,roman]
+%D \stoptyping
+%D
+%D This command affects the document as a whole: text, headers
+%D and footers. The second macro however affects only the text:
+%D
+%D \starttyping
+%D \switchtobodyfont[10pt]
+%D \stoptyping
+%D
+%D So we've got:
+%D
+%D \showsetup{setupbodyfont}
+%D \showsetup{switchtobodyfont}
+%D
+%D Both macros look alike. The second one also has to take
+%D all kind of keywords into account.
+
+\ifx\saveinterlinespace \undefined \let\saveinterlinespace \relax \fi
+\ifx\restoreinterlinespace\undefined \let\restoreinterlinespace\relax \fi
+
+% \newtoks \everysetupbodyfont
+% \newtoks \everyswitchtobodyfont
+
+\chardef\bodyfontsetstate=0
+
+\definecomplexorsimple\setupbodyfont
+
+\def\simplesetupbodyfont
+ {\restoreglobalbodyfont
+ \saveinterlinespace}
+
+\def\complexsetupbodyfont[#1]%
+ {\doifsomething{#1}
+ {\dosetfont1{#1}%
+ \globalbodyfontsize\localbodyfontsize
+ \normalizebodyfontsize\globalbodyfontsize\to\normalizedglobalbodyfontsize
+ \let\globalfontstyle\fontstyle
+ \ifloadingfonts\else
+ \the\everybodyfont
+ \the\everyglobalbodyfont
+ \saveinterlinespace
+ \fi
+ \the\everysetupbodyfont}}
+
+\unexpanded\def\switchtobodyfont[#1]%
+ {\doifsomething{#1}
+ {\ifcsname\??ft\normalizedbodyfontsize\interfaced{#1}\endcsname
+ \setbodyfontstep{#1}% so we have a fast [small] switch
+ \else
+ \dosetfont0{#1}%
+ \fi
+ \the\everybodyfont
+ \the\everyswitchtobodyfont}}
+
+%D The following alternative is meant for math||to||text
+%D switching and will be optimized.
+
+\def\fastswitchtobodyfont#1%
+ {\ifcsname\??ft\normalizedbodyfontsize#1\endcsname
+ \edef\futurebodyfontsize{\csname\??ft\normalizedbodyfontsize#1\endcsname}%
+ \ifcsname\@size@\futurebodyfontsize\endcsname
+ \csname\@size@\futurebodyfontsize\endcsname
+ \localbodyfontsize\futurebodyfontsize\relax
+ \fi
+ \fi
+ \csname\@style@\fontstyle\endcsname
+ \the\everybodyfont}
+
+%D \starttyping
+%D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$
+%D \stoptyping
+
+\def\setfontcharacteristics
+ {\the\everyfont}
+
+%D Predefined:
+
+% \installfontfeature[otf][tlig]
+% \installfontfeature[otf][trep]
+
+%D tricky but ok:
+
+\appendtoks\ctxlua{fonts.tfm.cleanup()}\to\everyshipout
+
+%D Todo:
+
+% \def\os{\groupedcommand{\setfontfeature{oldstyle}}{}}
+
+%D Experimental:
+
+\unexpanded\def\definefontfeature
+ {\dotripleargument\dodefinefontfeature}
+
+\def\dodefinefontfeature[#1][#2][#3]%
+ {\global\expandafter\chardef\csname\??fq=#1\endcsname % beware () needed as we get two values returned
+ \ctxlua{tex.write((fonts.define.specify.preset_context("#1","#2","#3")))}\relax}
+
+\definefontfeature
+ [default]
+ [%mode=node,
+ liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes
+
+\definefontfeature
+ [smallcaps]
+ [%mode=node,liga=yes,
+ smcp=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes
+
+\definefontfeature
+ [oldstyle]
+ [%mode=node,
+ onum=yes,liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes
+
+\definefontfeature % == default unless redefined
+ [ligatures]
+ [%mode=node,
+ liga=yes,kern=yes,tlig=yes,trep=yes]
+
+\definefontfeature % can be used for type1 fonts
+ [complete]
+ [liga=yes,kern=yes,compose=yes,tlig=yes,trep=yes]
+
+\definefontfeature
+ [arabic]
+ [mode=node,language=dflt,script=arab,ccmp=yes,
+ init=yes,medi=yes,fina=yes,isol=yes,
+ liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes,
+ mark=yes,mkmk=yes,kern=yes,curs=yes]
+
+\definefontfeature
+ [none]
+ [mode=none,features=no]
+
+\definefontfeature
+ [virtualmath]
+ [mode=base,liga=yes,kern=yes,tlig=yes,trep=yes]
+
+% for the moment here, this will change but we need it for mk.tex
+
+\definefontfeature[math-text] [virtualmath][ssty=no]
+\definefontfeature[math-script] [virtualmath][ssty=1,mathsize=yes]
+\definefontfeature[math-scriptscript][virtualmath][ssty=2,mathsize=yes]
+
+\definefontfeature [math-nostack-text] [math-text] [nostackmath=yes]
+\definefontfeature [math-nostack-script] [math-script] [nostackmath=yes]
+\definefontfeature [math-nostack-scriptscript][math-scriptscript][nostackmath=yes]
+
+% \definefontfeature[mathtext] [math-text]
+% \definefontfeature[mathscript] [math-script]
+% \definefontfeature[mathscriptscript] [math-scriptscript]
+
+%D Also new, handy for manuals:
+
+\unexpanded\def\fontchar#1{\ctxlua{fonts.char("#1")}}
+
+\let\otfchar\fontchar % will disappear, for compatibility only
+\let\afmchar\fontchar % will disappear, for compatibility only
+
+%D: We cannot yet inherit because no colors are predefined.
+
+\definecolor[font:init][r=.75]
+\definecolor[font:medi][g=.75]
+\definecolor[font:fina][b=.75]
+\definecolor[font:isol][r=.75,g=.75] % [y=.75]
+\definecolor[font:mark][r=.75,b=.75] % [m=.75]
+\definecolor[font:rest][g=.75,b=.75] % [c=.75]
+
+%D Experimental!
+
+\def\installfontfeature
+ {\dodoubleargument\doinstallfontfeature}
+
+\def\doinstallfontfeature[#1][#2]%
+ {\writestatus\m!fonts{installing font features was experimental}} % \ctxlua{fonts.install_feature("#1","#2")}}
+
+%D Not yet in \MKII.
+
+\def\fontfeatureslist
+ {\dodoubleargument\dofontfeatureslist}
+
+\def\dofontfeatureslist[#1][#2]% todo: arg voor type
+ {\ctxlua{tex.sprint(tex.ctxcatcodes,fonts.define.specify.context_tostring("#1","otf","\luaescapestring{#2}","yes","no",true,{"number"}))}}
+
+\attribute\zerocount\zerocount % first in list, so fast match
+
+\let\currentfeature\empty
+
+% ! ! ! very experimental, some test code for idris advanced features ! ! !
+%
+% \startbuffer
+% \definefontfeature[smallcaps][smallcaps][script=latn]
+% \definefontfeature[oldstyle] [oldstyle] [script=latn]
+%
+% \definedfont[name:cambria at 15pt]
+%
+% Hello there {\setff{smallcaps}capped 123 \setff{oldstyle}123!} \blank
+% Hello there {\addff{smallcaps}capped 123 \addff{oldstyle}123!} \blank
+% Hello there {\addff{smallcaps}capped \subff{smallcaps}normal} \blank
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+
+\def\featureattribute#1{\ctxlua{tex.sprint(fonts.define.specify.context_number("#1"))}}
+\def\setfontfeature #1{\edef\currentfeature{#1}\attribute\zerocount\featureattribute{#1}\relax}
+\def\resetfontfeature#1{\let\currentfeature\empty\attribute\zerocount\zerocount} % initial value
+
+\def\addfontfeaturetoset #1{\ctxlua{fonts.withset("#1", 1)}} % merge
+\def\subtractfontfeaturefromset #1{\ctxlua{fonts.withset("#1",-1)}} % merge
+\def\addfontfeaturetofont #1{\ctxlua{fonts.withfnt("#1", 2)}} % overload
+\def\subtractfontfeaturefromfont#1{\ctxlua{fonts.withfnt("#1",-2)}} % overload
+
+\let\setff\setfontfeature
+\let\addfs\addfontfeaturetoset
+\let\subfs\subtractfontfeaturefromset
+\let\addff\addfontfeaturetofont
+\let\subff\subtractfontfeaturefromfont
+
+%D The next auxilliary macro is an alternative to \type
+%D {\fontname}.
+
+\def\purefontname#1{\ctxlua{file.basename("\fontname#1"}} % will be function using id
+
+%D \macros
+%D {switchstyleonly}
+%D
+%D For switching a style but keeping the alternative, there
+%D is:
+%D
+%D \starttyping
+%D {\bf text \switchstyleonly\ss text}
+%D {\bf text \switchstyleonly[ss]text}
+%D {\sl text \switchstyleonly[sansserif]text}
+%D \stoptyping
+
+\definecomplexorsimple\switchstyleonly
+
+\def\simpleswitchstyleonly#1% stupid version
+ {\complexswitchstyleonly[\checkedstrippedcsname#1]}
+
+\def\complexswitchstyleonly[#1]% todo : check
+ {\setcurrentfontstyle{\csname\@shortstyle@#1\endcsname}%
+ \the\everybodyfont} % needed ?
+
+%D \macros
+%D {os}
+%D
+%D In good old \TEX, the old style numerals were often taken
+%D from the math fonts. No longer.
+
+\definefontfeature
+ [just-os]
+ [mode=node,onum=yes]
+
+% \def\sc{\setfontfeature{smallcaps}}
+\unexpanded\def\os{\setfontfeature{just-os}}
+
+%D Code for switching to fraktur and script has also been
+%D changed. We now have an alphabet switcher.
+
+\ifx\mathtext\undefined \let\mathtext\hbox \fi
+
+%D \macros
+%D {definebodyfontswitch}
+%D
+%D \PLAIN\ \TEX\ defines some macro's like \type{\tenpoint}
+%D to switch to a specific bodyfontsize. Just for the sake of
+%D compatibility we can define them like:
+%D
+%D \starttyping
+%D \definebodyfontswitch [twelvepoint] [12pt]
+%D \stoptyping
+%D
+%D We don't support language specific synonyms here, mainly
+%D because \PLAIN\ \TEX\ is english anyway.
+
+\def\dodefinebodyfontswitch[#1][#2]%
+ {\def\docommand##1{\setvalue{##1}{\switchtobodyfont[#2]}}%
+ \processcommalist[#1]\docommand}
+
+\unexpanded\def\definebodyfontswitch
+ {\dodoubleargument\dodefinebodyfontswitch}
+
+%D \macros
+%D {setsmallbodyfont,setmainbodyfont,setbigbodyfont}
+%D
+%D When we're typesetting at for instance 10pt, we can call for
+%D the \type{small} as well as the \type{big} alternative,
+%D related to this main size, using \type{\switchtobodyfont[small]}.
+%D The three alternatives can be activated by the next three
+%D system calls and are defined by the bodyfontenvironment.
+
+\let\fontstep\empty % we can use \fontstep for tracing purposes
+
+\def\setbodyfontstep#1%
+ {\edef\fontstep{\csname\bodyfontvariable\normalizedbodyfontsize\interfaced{#1}\endcsname}%
+ \doswitchpoints[\fontstep]%
+ \doswitchstyle[\fontstyle]}
+
+\unexpanded\def\setsmallbodyfont{\setbodyfontstep\v!small\the\everybodyfont}
+\unexpanded\def\setbigbodyfont {\setbodyfontstep\v!big \the\everybodyfont}
+
+\unexpanded\def\setmainbodyfont
+ {\doswitchpoints[\normalizedbodyfontsize]%
+ \doswitchstyle[\fontstyle]%
+ \the\everybodyfont
+ \the\everyglobalbodyfont
+ \saveinterlinespace}
+
+%D \macros
+%D {restoreglobalbodyfont}
+%D
+%D Users can set whatever font available while typesetting text.
+%D Pagenumbers, footers, headers etc. however must be typeset
+%D in the main bodyfont and style of the document. Returning to
+%D the global state can be done with the next macro:
+
+\let\globalfontstyle\c!rm
+
+\def\fullrestoreglobalbodyfont
+ {\let\fontsize\defaultfontsize
+ \let\fontbody\defaultfontbody
+ \chardef\currentxfontsize\zerocount
+ \let\fontclass\globalfontclass
+ \doswitchpoints[\normalizedglobalbodyfontsize]%
+ \doswitchstyle[\globalfontstyle]%
+ \redoconvertfont % just in case a pagebreak occurs
+ \tf
+ \the\everybodyfont
+ \the\everyglobalbodyfont
+ \saveinterlinespace}
+
+\def\partialrestoreglobalbodyfont
+ {\let\fontsize\defaultfontsize
+ \let\fontbody\defaultfontbody
+ \chardef\currentxfontsize\zerocount
+ \redoconvertfont
+ \tf
+ \the\everybodyfont % indeed needed
+ \the\everyglobalbodyfont % indeed needed
+ \saveinterlinespace}
+
+\def\restoreglobalbodyfont % ook style etc
+ {\ifx\fontclass\globalfontclass
+ \ifx\fontstyle\globalfontstyle
+ \ifx\normalizedbodyfontsize\normalizedglobalbodyfontsize
+ \partialrestoreglobalbodyfont
+ \else
+ \fullrestoreglobalbodyfont
+ \fi
+ \else
+ \fullrestoreglobalbodyfont
+ \fi
+ \else
+ \fullrestoreglobalbodyfont
+ \fi}
+
+% in case of troubles: \let\restorebodyfont\fullrestoreglobalbodyfont
+
+%D This macro has to be called when entering the pagebody
+%D handling routine as well as the footnote insert routine.
+%D Users can access this feature |<|for instance when one wants
+%D to typeset tables and alike in the main bodyfont and style
+%D while the running text is temporary set to a smaller one|>|
+%D by saying \type{\switchtobodyfont[global]}.
+
+%D \macros
+%D {rasterfont}
+%D
+%D There are (at the moment) two situations in which we want to
+%D have fast access to a particular font. When we are using
+%D \TEX\ to typeset rasters, we use small {\rasterfont.}'s
+%D (a rather small period indeed), the same as \PICTEX\ uses
+%D for drawing purposes.
+
+\definefont [rasterfont] [Serif at 5pt]
+
+%D \macros
+%D {infofont}
+%D
+%D The second situation occurs when we enable the info mode,
+%D and put all kind of status information in the margin. We
+%D don't want huge switches to the main bodyfont and style, so
+%D here too we use a direct method.
+
+\let\infofont\relax % satisfy dep checker
+
+\definefont [infofont] [Mono at 6pt] % todo \the\everybodyfont
+
+%D \macros
+%D {definealternativestyle}
+%D
+%D In the main modules we are going to implement lots of
+%D parameterized commands and one of these parameters will
+%D concern the font to use. To suit consistent use of fonts we
+%D here implement a mechanism for defining the keywords that
+%D present a particular style or alternative.
+%D
+%D \starttyping
+%D \definealternativestyle [keywords] [\style] [\nostyle]
+%D \stoptyping
+%D
+%D The first command is used in the normal textflow, while the
+%D second command takes care of headings and alike. Consider
+%D the next two definitions:
+%D
+%D \starttyping
+%D \definealternativestyle [bold] [\bf] []
+%D \definealternativestyle [cap] [\cap] [\cap]
+%D \stoptyping
+%D
+%D A change \type{\bf} in a heading which is to be set in
+%D \type{\tfd} does not look that well, so therefore we leave
+%D the second argument of \type{\definealternativestyle} empty.
+%D When we capatalize characters using the pseudo small cap
+%D command \type{\cap}, we want this to take effect in both
+%D text and headings, which is accomplished by assigning both
+%D arguments.
+
+\def\dodefinealternativestyle[#1][#2][#3]%
+ {\def\docommand##1%
+ {\ifcsname##1\endcsname\else\setuvalue{##1}{\groupedcommand{#2}{}}\fi
+ \setvalue{\@letter@ ##1}{#2}%
+ \setvalue{\@noletter@##1}{#3}}%
+ \processcommalist[#1]\docommand}
+
+\unexpanded\def\definealternativestyle
+ {\dotripleempty\dodefinealternativestyle}
+
+\unexpanded\def\definestyle{\definealternativestyle}
+
+%D Maybe too geneneric, but probably ok is the following. (Maybe one
+%D day we will use a dedicated grouped command for styles.)
+
+\appendtoks
+ \let\groupedcommand\thirdofthreearguments
+\to \simplifiedcommands
+
+%D This command also defines the keyword as command. This means
+%D that the example definition of \type{bold} we gave before,
+%D results in a command \type{\bold} which can be used as:
+%D
+%D \startbuffer
+%D He's a \bold{bold} man with a {\bold head}.
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or
+%D
+%D \startvoorbeeld
+%D \definealternativestyle[bold][\bf][]\getbuffer
+%D \stopvoorbeeld
+%D
+%D Such definitions are of course unwanted for \type{\cap}
+%D because this would result in an endless recursive call.
+%D Therefore we check on the existance of both the command and
+%D the substitution. The latter is needed because for instance
+%D \type{\type} is an entirely diferent command. That command
+%D handles verbatim, while the style command would just switch
+%D to teletype font. This is just an example of a tricky
+%D naming coincidence.
+
+%D \macros
+%D {doconvertfont,noconvertfont,
+%D dontconvertfont,redoconvertfont}
+%D
+%D After having defined such keywords, we can call for them by
+%D using
+%D
+%D \starttyping
+%D \doconvertfont{keyword}{text}
+%D \stoptyping
+%D
+%D We deliberately pass an argument. This enables us to
+%D assign converters that handle one argument, like
+%D \type{\cap}.
+%D
+%D By default the first specification is used to set the style,
+%D exept when we say \type{\dontconvertfont}, after which the
+%D second specification is used. We can also directly call for
+%D \type{\noconvertfont}. In nested calls, we can restore the
+%D conversion by saying \type{\redoconvertfont}.
+
+% subtle ... \expandafter is needed else problems with lookahead caps
+
+\def\@@dodoconvertfont{\csname\@letter@ \p!defined\expandafter\endcsname\gobbleoneargument}
+\def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname}
+\def\@@redoconvertfont{\csname \p!defined\expandafter\endcsname\gobbleoneargument}
+
+% beware: p!defined can contain crap like \edef crap {...} and such
+% so we need to pass #1 as well
+
+\unexpanded\def\dodoconvertfont#1% #2% we need the protection
+ {\edef\p!defined{#1}%
+ \ifx\p!defined\empty\else
+ \@EA\dododoconvertfont
+ \fi{#1}}
+
+\def\dododoconvertfont % #1
+ {\ifcsname\@letter@\detokenize\@EA{\p!defined}\endcsname
+ \@EA\@@dodoconvertfont
+ \else\ifcsname\detokenize\@EA{\p!defined}\endcsname
+ \@EAEAEA\@@redoconvertfont
+ \else
+ \@EAEAEA\firstofoneargument
+ \fi\fi} % {#1}
+
+\let\doconvertfont\dodoconvertfont
+
+\unexpanded\def\noconvertfont#1% #2%
+ {\edef\p!defined{#1}%
+ \ifx\p!defined\empty
+ \else
+ \@EA\nononoconvertfont
+ \fi}
+
+\def\nononoconvertfont
+ {\ifcsname\@noletter@\detokenize\@EA{\p!defined}\endcsname
+ \@EA\@@donoconvertfont
+ \fi}
+
+%D Extras:
+
+\unexpanded\def\dontconvertfont{\let\doconvertfont\noconvertfont}
+\unexpanded\def\redoconvertfont{\let\doconvertfont\dodoconvertfont}
+
+%D These commands are not grouped! Grouping is most probably
+%D done by the calling macro's and would lead to unnecessary
+%D overhead.
+
+%D \macros
+%D {em,emphasistypeface,emphasisboldface}
+%D
+%D The next macro started as a copy of Donald Arseneau's
+%D \type{\em} (\TUGNEWS\ Vol.~3, no.~1, 1994). His
+%D implementation was a bit more sophisticated version of the
+%D standard \LATEX\ one. We furter enhanced the macro, so now
+%D it also adapts itself to boldface mode. Because we favor
+%D {\sl slanted} type over {\it italic}, we made the emphasis
+%D adaptable, for instance:
+%D
+%D \starttyping
+%D \def\emphasistypeface {\it}
+%D \def\emphasisboldface {\bi}
+%D \stoptyping
+%D
+%D But we prefer:
+
+\def\emphasistypeface {\sl}
+\def\emphasisboldface {\bs}
+
+%D or even better:
+
+\def\doemphasistypeface#1#2%
+ {\edef\emphasizedtypeface{\csname\??ft\fontclass\normalizedbodyfontsize\c!em\endcsname}%
+ \ifx\emphasizedtypeface\v!slanted
+ #1%
+ \else\ifx\emphasizedtypeface\v!italic
+ #2%
+ \else\ifx\emphasizedtypeface\v!empty
+ \edef\emphasizedtypeface{\csname\??ft\normalizedbodyfontsize\c!em\endcsname}%
+ \ifx\emphasizedtypeface\v!slanted
+ #1%
+ \else\ifx\emphasizedtypeface\v!italic
+ #2%
+ \else
+ \getvalue\emphasizedtypeface
+ \fi\fi
+ \else
+ \getvalue\emphasizedtypeface
+ \fi\fi\fi}
+
+\def\emphasistypeface{\doemphasistypeface\sl\it}
+\def\emphasisboldface{\doemphasistypeface\bs\bi}
+
+%D To be set with the default body font environment: \type
+%D {em} being \type {slanted} or \type {italic}.
+
+\newconditional\emneeded
+
+\newtoks\everyemphasized
+
+\unexpanded\def\em
+ {\relax
+ \ifdim\slantperpoint>\zeropoint
+ \settrue\emneeded
+ \else
+ \setfalse\emneeded
+ \fi
+ \setemphasisboldface % new
+ \ifx\fontalternative\c!it
+ \def\emphasistypeface{\it}\tf
+ \else\ifx\fontalternative\c!sl
+ \def\emphasistypeface{\sl}\tf
+ \else\ifx\fontalternative\c!bf
+ \emphasisboldface
+ \else\ifx\fontalternative\c!bs
+ \def\emphasisboldface{\bs}\bf
+ \else\ifx\fontalternative\c!bi
+ \def\emphasisboldface{\bi}\bf
+ \else
+ \emphasistypeface
+ \fi\fi\fi\fi\fi
+ \the\everyemphasized
+ \ifconditional\emneeded\relax
+ \else
+ \expandafter\aftergroup
+ \fi
+ \emphasiscorrection}
+
+% compare ...
+%
+% \appendtoks \red \to \everyemphasized
+% \setupbodyfontenvironment [default] [em={\italic\color[red]}]
+
+%D The next feature was not present in previous versions. It
+%D takes care of \type {\em \bf ...} sitiations.
+
+\def\setemphasisboldface
+ {\let\savedemphasisboldface\bf
+ \let\setemphasisboldface\relax
+ \unexpanded\def\bf
+ {%\relax
+ \let\bf\relax % new
+ \ifx\fontalternative\c!it
+ \bi
+ \else\ifx\fontalternative\c!sl
+ \bs
+ \else
+ \savedemphasisboldface
+ \fi\fi
+ \let\bf\savedemphasisboldface}}
+
+%D Donald's (adapted) macros take the next character into
+%D account when placing italic correction. As a bonus we also
+%D look for something that looks like a dash, in which case we
+%D don't correct.
+
+\let\italiccorrection=\/ % tex primitive
+
+\def\emphasiscorrection
+ {\ifhmode
+ \expandafter\emphasislook
+ \fi}
+
+\def\emphasislook
+ {\begingroup
+ \futurelet\next\emphasistest}
+
+\def\emphasistest
+ {\ifcat\noexpand\next,% still ok?
+ \expandafter\doemphasiscorrection
+ \else
+ \expandafter\dododoemphasiscorrection
+ \fi}
+
+\def\doemphasiscorrection
+ {\futurelet\next\dodoemphasiscorrection}
+
+\def\dodoemphasiscorrection
+ {\setbox\scratchbox\hbox{\next}%
+ \ifdim\ht\scratchbox=\zeropoint % probably a space
+ \expandafter\dododoemphasiscorrection
+ \else\ifdim\ht\scratchbox<.3ex
+ \expandafter\expandafter\expandafter\endgroup
+ \else
+ \expandafter\expandafter\expandafter\dododoemphasiscorrection
+ \fi\fi}
+
+\def\dododoemphasiscorrection
+ {\scratchskip\lastskip
+ \ifdim\scratchskip=\zeropoint\relax % == \ifzeropt\scratchskip
+ \italiccorrection\relax
+ \else
+ \unskip\italiccorrection\hskip\scratchskip
+ \fi
+ \endgroup}
+
+%D We end with some examples which show the behavior when
+%D some punctuation is met. We also show how the mechanism
+%D adapts itself to bold, italic and slanted typing.
+%D
+%D \startbuffer
+%D test {test}test \par
+%D test {\sl test}test \par
+%D test {\em test}test \par
+%D test {\em test}--test \par
+%D
+%D test {test}, test \par
+%D test {\em test}, test \par
+%D
+%D test {\em test {\em test {\em test} test} test} test \par
+%D test {\bf test {\em test {\em test} test} test} test \par
+%D test {\sl test {\em test {\em test} test} test} test \par
+%D test {\it test {\em test {\em test} test} test} test \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D We get:
+%D
+%D \startvoorbeeld
+%D \startpacked
+%D \getbuffer
+%D \stoppacked
+%D \stopvoorbeeld
+
+%D \macros
+%D {emphbf,emphit,emphsl,emphtf}
+%D
+%D The next emphasis alternatives are for \THANH. They adapt
+%D their style as good as possible.
+
+\def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}}
+\def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}}
+\def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}}
+\def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}}
+
+%D \startbuffer
+%D TEXT {\emphbf text \emphit text \emphtf text \emphsl text} TEXT
+%D TEXT \emphbf{text \emphit{text} \emphtf{text} \emphsl{text}} TEXT
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+%D \macros
+%D {setfont}
+%D
+%D Every now and then we want to define a font directly, for
+%D instance when we typeset title pages. The next macro saves
+%D some typing:
+
+\def\setfont% geen \dosetfont mogelijk
+ {\def\next{\nextfont\setupinterlinespace}% hm, we need to use \setuplocalinterlinespace
+ \afterassignment\next\font\nextfont=}
+
+%D One can call this macro as:
+%D
+%D \starttyping
+%D \setfont cmr10 at 60pt
+%D \stoptyping
+%D
+%D After which the font is active and the baselines and
+%D struts are set.
+
+%D \macros
+%D {showbodyfont}
+%D
+%D One can call for a rather simple overview of a bodyfont and the
+%D relations between its alternative fonts.
+%D
+%D \showsetup{showbodyfont}
+%D
+%D The current bodyfont (here we omitted the argument) looks like:
+%D
+%D \showbodyfont
+%D
+%D The implementation is rather straightforward in using
+%D \type{\halign}.
+
+\fetchruntimecommand \showbodyfont {\f!fontprefix\s!run.mkiv}
+
+%D \macros
+%D {showfontstrip, testminimalbaseline, showminimalbaseline}
+%D
+%D The next command can come in handy when combining
+%D different fonts into a collection (typeface) and
+%D determining optimal baseline distances.
+%D
+%D \showfontstrip \blank \showminimalbaseline
+
+\fetchruntimecommand \showfontstrip {\f!fontprefix\s!run.mkiv}
+\fetchruntimecommand \testminimalbaseline {\f!fontprefix\s!run.mkiv}
+\fetchruntimecommand \showminimalbaseline {\f!fontprefix\s!run.mkiv}
+
+%D \macros
+%D {showkerning}
+%D
+%D A goody is:
+%D
+%D \showkerning{Can you guess what kerning is?}
+
+\fetchruntimecommand \showkerning {\f!fontprefix\s!run.mkiv}
+
+%D \macros
+%D {showbodyfontenvironment}
+%D
+%D The current bodyfontenvironment is:
+%D
+%D \showbodyfontenvironment
+%D
+%D This overview is generated using:
+%D
+%D \showsetup{showbodyfontenvironment}
+
+\fetchruntimecommand \showbodyfontenvironment {\f!fontprefix\s!run.mkiv}
+
+%D \macros
+%D {showfont,showfontstyle,showligatures}
+%D
+%D The following command generates a fontmap:
+%D
+%D \startbuffer
+%D \showfont[SansBold at 12pt]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \getbuffer
+
+% to be internationalized
+
+\fetchruntimecommand \showfont {\f!fontprefix\s!run.mkiv}
+\fetchruntimecommand \showfontstyle {\f!fontprefix\s!run.mkiv}
+\fetchruntimecommand \showligature {\f!fontprefix\s!run.mkiv}
+\fetchruntimecommand \showligatures {\f!fontprefix\s!run.mkiv}
+\fetchruntimecommand \showcharratio {\f!fontprefix\s!run.mkiv}
+
+%D \macros
+%D {getglyph, symbolicfont}
+%D
+%D Individual glyphs can be accessed by using
+%D
+%D \starttyping
+%D \getglyph{fontname}{character}
+%D \stoptyping
+%D
+%D This macro is used in for instance the symbol modules and
+%D as one can see, it does obey the small and even smaller
+%D sizes. The \type {\symbolicfont} macro can be used to
+%D switch to a font named \type {fontname} (see \type
+%D {cont-log} and \type {symb-eur} for examples of symbolic
+%D definitions.
+
+\def\fontstringA
+ {\ifx\fontstyle\c!rm \s!Serif \else
+ \ifx\fontstyle\c!ss \s!Sans \else
+ \ifx\fontstyle\c!tt \s!Mono \else
+ \s!Serif \fi\fi\fi}
+
+\def\fontstringB
+ {\ifx\fontstyle\c!rm \s!Regular \else
+ \ifx\fontstyle\c!ss \s!Support \else
+ \ifx\fontstyle\c!tt \s!Type \else
+ \s!Serif \fi\fi\fi}
+
+\def\fontstringC
+ {\ifx\fontalternative\c!bf \s!Bold \else
+ \ifx\fontalternative\c!sl \s!Slanted \else
+ \ifx\fontalternative\c!it \s!Italic \else
+ \ifx\fontalternative\c!bs \s!BoldSlanted \else
+ \ifx\fontalternative\c!bi \s!BoldItalic \fi\fi\fi\fi\fi}
+
+\def\fontstringD % default fontstyle
+ {\expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!rm \s!Serif \else
+ \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!ss \s!Sans \else
+ \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!tt \s!Mono \else
+ \s!Serif \fi\fi\fi}
+
+% potential generalization:
+
+% \letvalue{\??ff:t:\c!rm}\s!Serif
+% \letvalue{\??ff:t:\c!ss}\s!Sans
+% \letvalue{\??ff:t:\c!tt}\s!Mono
+%
+% \letvalue{\??ff:s:\c!bf}\s!Bold
+% \letvalue{\??ff:s:\c!sl}\s!Slanted
+% \letvalue{\??ff:s:\c!it}\s!Italic
+% \letvalue{\??ff:s:\c!bs}\s!BoldSlanted
+% \letvalue{\??ff:s:\c!bi}\s!BoldItalic
+%
+% \letvalue{\??ff:a:\c!rm}\s!Regular
+% \letvalue{\??ff:a:\c!ss}\s!Support
+% \letvalue{\??ff:a:\c!tt}\s!Type
+%
+% \def\fontstringA{\executeifdefined{\??ff:t:\fontstyle}\s!Serif}
+% \def\fontstringB{\executeifdefined{\??ff:a:\fontstyle}\s!Serif}
+% \def\fontstringC{\executeifdefined{\??ff:s:\fontstyle}\empty}
+% \def\fontstringD{\executeifdefined{\??ff:t:\csname\??tf\fontclass\s!default\endcsname}\s!Serif}
+
+\def\glyphfontfile#1%
+ {#1%
+ \ifcsname\??ff#1\fontstringA\fontstringC\endcsname
+ \fontstringA\fontstringC
+ \else\ifcsname\??ff#1\fontstringB\fontstringC\endcsname
+ \fontstringB\fontstringC
+ \else\ifcsname\??ff#1\fontstringA\endcsname
+ \fontstringA
+ \else\ifcsname\??ff#1\fontstringB\endcsname
+ \fontstringB
+ \else\ifcsname\??ff#1\fontstringC\endcsname
+ \fontstringC
+ \fi\fi\fi\fi\fi}
+
+%D The next macro can be used to make decisions based on the shape:
+
+\def\doifitalicelse#1#2%
+ {\ifx\fontalternative\c!sl#1\else
+ \ifx\fontalternative\c!it#1\else
+ \ifx\fontalternative\c!bs#1\else
+ \ifx\fontalternative\c!bi#1\else#2\fi\fi\fi\fi}
+
+%D For an example of usage of the following command,
+%D see \type {cont-log.tex}.
+%D
+%D \starttyping
+%D \def\symbolicfont#1{\definedfont[\glyphfontfile{#1} sa *]}
+%D \stoptyping
+%D
+%D Since we know what scaling it to be applied, we can
+%D implement a much faster alternative:
+
+\let\thedefinedfont\relax
+
+\def\symbolicsizedfont#1#2#3%
+ {\scaledfontsize#1%
+ \scaledfontsize#2\scaledfontsize
+ \font\thedefinedfont=\truefontname{\glyphfontfile{#3}} at \currentfontbodyscale\scaledfontsize\relax
+ \thedefinedfont}
+
+\def\symbolicscaledfont
+ {\symbolicsizedfont\fontbody}
+
+\unexpanded\def\symbolicfont
+ {\symbolicsizedfont\fontbody\plusone}
+
+\unexpanded\def\getglyph#1#2% slow, faster, much faster
+ %{{\definefont[\s!dummy][\glyphfontfile{#1} sa \currentfontscale]\dummy#2}}
+ %{{\definefont[\s!dummy][\glyphfontfile{#1} sa *]\dummy#2}}
+ %{{\symbolicfont{#1}#2}}
+ {{\symbolicfont{#1}\doifnumberelse{#2}\char\donothing#2}}
+
+\unexpanded\def\getscaledglyph#1#2#3%
+ {{\symbolicscaledfont{#1}{#2}\doifnumberelse{#3}\char\donothing#3}}
+
+\unexpanded\def\getrawglyph#1#2% for simple symbols
+ {{\scaledfontsize\fontbody
+ \font\thedefinedfont=#1 at \currentfontbodyscale\scaledfontsize\relax
+ \thedefinedfont\doifnumberelse{#2}\char\donothing#2}}
+
+%D The last implementation of \type {\getglyph} permits
+%D definitions like:
+%D
+%D \starttyping
+%D \definefontsynonym [EuroSans] [eurose]
+%D \definefontsynonym [EuroSansBold] [euroseb]
+%D \definefontsynonym [EuroSansItalic] [eurosei]
+%D \definefontsynonym [EuroSansSlanted] [eurosei]
+%D \definefontsynonym [EuroSansBoldItalic] [eurosebi]
+%D \definefontsynonym [EuroSansBoldSlanted] [eurosebi]
+%D
+%D \definesymbol [euro] [\getglyph{Euro}{\char160}]
+%D
+%D \def\euro{\symbol[euro]}
+%D \stoptyping
+%D
+%D These definitions guarantee that the next calls work okay:
+%D
+%D \starttyping
+%D \ss \tf\euro \bf\euro \sla\euro \itd\euro \bs\euro \bic\euro
+%D \stoptyping
+%D
+%D The shape as well as the size is adapted to the current
+%D environment.
+
+%D \macros
+%D {ss, SS, sz}
+%D
+%D We are going to redefine \type{\ss} but for those wo still
+%D want to have access to the german \SS, we save it's value in
+%D \type{\SS}. Ok, I should have used \type{\sf} instead of
+%D \type{\ss} in the first place.
+
+\ifx\undefined\SS \let\SS=\ss \fi
+\ifx\undefined\sz \let\sz=\ss \fi
+
+%D Personally I think that using \TEX\ macro packages is
+%D complicated by the way fonts are handled. Apart from the
+%D many encodings, we also deal with different naming schemes.
+%D Confronted with this problem, I decided to change the
+%D definitions into:
+%D
+%D \starttyping
+%D \definebodyfont [12pt] [rm] [tf=Times-Roman at 12pt]
+%D \stoptyping
+%D
+%D combined with for instance:
+%D
+%D \starttyping
+%D \definefontsynonym [Times-Roman] [tir]
+%D \stoptyping
+
+%D Now we're up to some definitions.
+
+\definebodyfontenvironment
+ [\s!default]
+ [ \s!text=1.0,
+ \s!script=0.7,
+ \s!scriptscript=0.5,
+ \c!a=1.200,
+ \c!b=1.440,
+ \c!c=1.728,
+ \c!d=2.074,
+ *=\currentfontscale, % wildcard
+ \c!x=0.8,
+ \c!xx=0.6,
+ \c!big=1.2,
+ \c!small=0.8,
+ \c!interlinespace=,
+ \c!em=\v!slanted]
+
+\definebodyfontenvironment
+ [20.7pt]
+ [ \s!text=20.7pt,
+ \s!script=\!!fourteenpointfour,
+ \s!scriptscript=\!!twelvepoint,
+ \c!x=17.3pt,
+ \c!xx=\!!fourteenpointfour,
+ \c!big=20.7pt, % !!!!
+ \c!small=17.3pt]
+
+\definebodyfontenvironment
+ [17.3pt]
+ [ \s!text=17.3pt,
+ \s!script=\!!twelvepoint,
+ \s!scriptscript=\!!tenpoint,
+ \c!x=\!!fourteenpointfour,
+ \c!xx=\!!twelvepoint,
+ \c!big=20.7pt,
+ \c!small=\!!fourteenpointfour]
+
+\definebodyfontenvironment
+ [\!!fourteenpointfour]
+ [ \s!text=\!!fourteenpointfour,
+ \s!script=\!!elevenpoint,
+ \s!scriptscript=\!!ninepoint,
+ \c!x=\!!twelvepoint,
+ \c!xx=\!!tenpoint,
+ \c!big=17.3pt,
+ \c!small=\!!twelvepoint]
+
+\definebodyfontenvironment
+ [\!!twelvepoint]
+ [ \s!text=\!!twelvepoint,
+ \s!script=\!!ninepoint,
+ \s!scriptscript=\!!sevenpoint,
+ \c!x=\!!tenpoint,
+ \c!xx=\!!eightpoint,
+ \c!big=\!!fourteenpointfour,
+ \c!small=\!!tenpoint]
+
+\definebodyfontenvironment
+ [\!!elevenpoint]
+ [ \s!text=\!!elevenpoint,
+ \s!script=\!!eightpoint,
+ \s!scriptscript=\!!sixpoint,
+ \c!x=\!!ninepoint,
+ \c!xx=\!!sevenpoint,
+ \c!big=\!!twelvepoint,
+ \c!small=\!!ninepoint]
+
+\definebodyfontenvironment
+ [\!!tenpoint]
+ [ \s!text=\!!tenpoint,
+ \s!script=\!!sevenpoint,
+ \s!scriptscript=\!!fivepoint,
+ \c!x=\!!eightpoint,
+ \c!xx=\!!sixpoint,
+ \c!big=\!!twelvepoint,
+ \c!small=\!!eightpoint]
+
+\definebodyfontenvironment
+ [\!!ninepoint]
+ [ \s!text=\!!ninepoint,
+ \s!script=\!!sevenpoint,
+ \s!scriptscript=\!!fivepoint,
+ \c!x=\!!sevenpoint,
+ \c!xx=\!!fivepoint,
+ \c!big=\!!elevenpoint,
+ \c!small=\!!sevenpoint]
+
+\definebodyfontenvironment
+ [\!!eightpoint]
+ [ \s!text=\!!eightpoint,
+ \s!script=\!!sixpoint,
+ \s!scriptscript=\!!fivepoint,
+ \c!x=\!!sixpoint,
+ \c!xx=\!!fivepoint,
+ \c!big=\!!tenpoint,
+ \c!small=\!!sixpoint]
+
+\definebodyfontenvironment
+ [\!!sevenpoint]
+ [ \s!text=\!!sevenpoint,
+ \s!script=\!!sixpoint,
+ \s!scriptscript=\!!fivepoint,
+ \c!x=\!!sixpoint,
+ \c!xx=\!!fivepoint,
+ \c!big=\!!ninepoint,
+ \c!small=\!!fivepoint]
+
+\definebodyfontenvironment
+ [\!!sixpoint]
+ [ \s!text=\!!sixpoint,
+ \s!script=\!!fivepoint,
+ \s!scriptscript=\!!fivepoint,
+ \c!x=\!!fivepoint,
+ \c!xx=\!!fivepoint,
+ \c!big=\!!eightpoint,
+ \c!small=\!!fivepoint]
+
+\definebodyfontenvironment
+ [\!!fivepoint]
+ [ \s!text=\!!fivepoint,
+ \s!script=\!!fivepoint,
+ \s!scriptscript=\!!fivepoint,
+ \c!x=\!!fivepoint,
+ \c!xx=\!!fivepoint,
+ \c!big=\!!sevenpoint,
+ \c!small=\!!fivepoint]
+
+\definebodyfontenvironment
+ [\!!fourpoint]
+ [ \s!text=\!!fourpoint,
+ \s!script=\!!fourpoint,
+ \s!scriptscript=\!!fourpoint,
+ \c!x=\!!fourpoint,
+ \c!xx=\!!fourpoint,
+ \c!big=\!!sixpoint,
+ \c!small=\!!fourpoint]
+
+\definebodyfontswitch [fourteenpointfour] [\!!fourteenpointfour]
+\definebodyfontswitch [twelvepoint] [\!!twelvepoint]
+\definebodyfontswitch [elevenpoint] [\!!elevenpoint]
+\definebodyfontswitch [tenpoint] [\!!tenpoint]
+\definebodyfontswitch [ninepoint] [\!!ninepoint]
+\definebodyfontswitch [eightpoint] [\!!eightpoint]
+\definebodyfontswitch [sevenpoint] [\!!sevenpoint]
+\definebodyfontswitch [sixpoint] [\!!sixpoint]
+\definebodyfontswitch [fivepoint] [\!!fivepoint]
+\definebodyfontswitch [fourpoint] [\!!fourpoint]
+
+% \definebodyfontswitch [xii] [\!!twelvepoint]
+% \definebodyfontswitch [xi] [\!!elevenpoint]
+% \definebodyfontswitch [x] [\!!tenpoint]
+% \definebodyfontswitch [ix] [\!!ninepoint]
+% \definebodyfontswitch [viii] [\!!eightpoint]
+% \definebodyfontswitch [vii] [\!!sevenpoint]
+% \definebodyfontswitch [vi] [\!!sixpoint]
+
+%D So far.
+
+\definefontstyle [\c!mm] [\c!mm]
+\definefontstyle [\c!rm,\v!roman,\v!serif,\v!regular] [\c!rm]
+\definefontstyle [\c!ss,\v!sansserif,\v!sans,\v!support] [\c!ss]
+\definefontstyle [\c!tt,\v!teletype,\v!type,\v!mono] [\c!tt]
+\definefontstyle [\c!hw,\v!handwritten] [\c!hw]
+\definefontstyle [\c!cg,\v!calligraphic] [\c!cg]
+
+\definefontalternative[\c!tf]
+\definefontalternative[\c!bf]
+\definefontalternative[\c!it]
+\definefontalternative[\c!sl]
+\definefontalternative[\c!bs]
+\definefontalternative[\c!bi]
+\definefontalternative[\c!sc]
+
+\definefontsize[\c!a] \definefontsize[\c!b]
+\definefontsize[\c!c] \definefontsize[\c!d]
+
+\definealternativestyle [\v!mediaeval] [\os] []
+\definealternativestyle [\v!normal] [\tf] []
+\definealternativestyle [\v!bold] [\bf] []
+\definealternativestyle [\v!type] [\tt] []
+\definealternativestyle [\v!mono] [\tt] []
+\definealternativestyle [\v!slanted] [\sl] []
+\definealternativestyle [\v!italic] [\it] []
+\definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] []
+\definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] []
+\definealternativestyle [\v!small,\v!smallnormal] [\tfx] []
+\definealternativestyle [\v!smallbold] [\bfx] []
+\definealternativestyle [\v!smalltype] [\ttx] []
+\definealternativestyle [\v!smallslanted] [\slx] []
+\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx] []
+\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\bix] []
+
+\definealternativestyle [\v!sans,\v!sansserif] [\ss] []
+\definealternativestyle [\v!sansbold] [\ss\bf] []
+
+%D Slow but handy:
+
+\definealternativestyle [\v!smallbodyfont] [\setsmallbodyfont] []
+\definealternativestyle [\v!bigbodyfont] [\setbigbodyfont] []
+
+%D We treat {\sc Small Caps} and \cap {Pseudo Caps} a bit
+%D different. We also provide an \WORD {uppercase} style.
+
+\definealternativestyle [\v!cap,\v!capital] [\smallcapped] [\smallcapped]
+\definealternativestyle [\v!smallcaps] [\sc] [\sc]
+\definealternativestyle [\v!WORD] [\WORD] [\WORD]
+
+%D \macros
+%D {fontstylesuffix}
+%D
+%D The next macro is used to map non latin fontnames on
+%D fonts. See \type {font-uni} for an example of its use.
+
+\def\fontstylesuffix% why the \s!Regular ? see \getglyph
+ {\ifx\fontalternative\c!tf \s!Regular \else
+ \ifx\fontalternative\c!bf \s!Bold \else
+ \ifx\fontalternative\c!sl \s!Slanted \else
+ \ifx\fontalternative\c!it \s!Italic \else
+ \ifx\fontalternative\c!bs \s!BoldSlanted \else
+ \ifx\fontalternative\c!bi \s!BoldItalic \else
+ \ifx\fontalternative\c!sc \s!Caps \else
+ \s!Regular \fi\fi\fi\fi\fi\fi\fi}%
+
+%D \macros
+%D {definefontvariant,fontvariant,variant}
+%D
+%D This command is obsolete in \MKIV\ as we have features. It might
+%D come back using the local features handlers.
+
+\unexpanded\def\definefontvariant{\dotripleargument\dodefinefontvariant}
+
+\def\dodefinefontvariant[#1][#2][#3]{}
+\def\variant [#1]{}
+
+\ifdefined\Var\else \let\Var\variant \fi
+
+%D By default we load the Computer Modern Roman fonts (but
+%D not yet at this moment) and activate the 12pt roman
+%D bodyfont. Sans serif and teletype are also available and
+%D can be called for by \type{\ss} and \type{\tt}. Loading
+%D takes place elsewhere.
+%D
+%D For tracing purposes we define:
+
+\definefont[tinyfont][Mono at 1ex]
+
+% \tracinglostchars=1
+
+% this needs some interfacing
+%
+% \setupfonts[check=...]
+
+\def\checkcharactersinfont {\ctxlua{fonts.checkers.enable()}}
+\def\removemissingcharacters{\ctxlua{fonts.checkers.enable(true)}}
+
+%D New commands (not yet interfaced):
+
+\def\style[#1]% for inline usage, like \color
+ {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}}
+
+\unexpanded\def\startstyle[#1]%
+ {\begingroup
+ \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}
+
+\unexpanded\def\stopstyle
+ {\endgroup}
+
+%D Still experimental (might even go away).
+
+% \definestylecollection[mine]
+
+% \definestyleinstance[mine][default][sorry]
+% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
+% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
+% \definestyleinstance[mine][bf][\sl]
+% \definestyleinstance[mine][sl][\tt]
+
+% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}
+
+\unexpanded\def\definestylecollection
+ {\dosingleargument\dodefinestylecollection}
+
+\def\dodefinestylecollection[#1]%
+ {\iffirstargument
+ \setuvalue{#1}{\styleinstance[#1]}%
+ \def\docommand##1%
+ {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}%
+ \processcommacommand[\fontalternativelist,\s!default]\dodocommand}%
+ \processcommacommand[\fontstylelist,\s!default]\docommand
+ \fi}
+
+\unexpanded\def\definestyleinstance
+ {\doquadrupleargument\dodefinestyleinstance}
+
+\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
+ {\iffirstargument
+ \ifcsname#1\endcsname\else\definestylecollection[#1]\fi
+ \fi
+ \iffourthargument
+ \setvalue{\??sx#1:#2:#3}{#4}%
+ \else\ifthirdargument
+ \setvalue{\??sx#1::#2}{#3}%
+ \else\ifsecondargument
+ \letvalue{\??sx#1::#2}\empty
+ \fi\fi\fi}
+
+\unexpanded\def\styleinstance[#1]% will be made faster
+ {%\begingroup\normalexpanded{\noexpand\infofont[#1:\fontstyle:\fontalternative]}\endgroup
+ \executeifdefined{\??sx#1:\fontstyle:\fontalternative}%
+ {\executeifdefined{\??sx#1:\fontstyle:\s!default}%
+ {\executeifdefined{\??sx#1::\fontalternative}
+ {\getvalue {\??sx#1::\s!default}}}}}
+
+% \unexpanded\def\styleinstance[#1]%
+% {\csname\??sx#1%
+% \ifcsname:\fontstyle:\fontalternative\endcsname
+% :\fontstyle:\fontalternative
+% \else\ifcsname:\fontstyle:\s!default\endcsname
+% :\fontstyle:\s!default
+% \else\ifcsname::\fontalternative\endcsname
+% ::\fontalternative
+% \else\ifcsname::\s!default\endcsname
+% ::\s!default
+% \else
+% % nothing, \relax
+% \fi\fi\fi\fi
+% \endcsname}
+
+%D goodies:
+
+\def\showchardata#1{\ctxlua{fonts.show_char_data("#1")}}
+\def\showfontdata {\ctxlua{fonts.show_font_parameters()}}
+
+%D some low level helpers
+%D
+%D \starttyping
+%D \def\TestLookup#1%
+%D {\dolookupfontbyspec{#1}
+%D pattern: #1, found: \dolookupnoffound
+%D \blank
+%D \dorecurse {\dolookupnoffound} {%
+%D \recurselevel:~\dolookupgetkeyofindex{fontname}{\recurselevel}\quad
+%D }%
+%D \blank}
+%D
+%D \TestLookup{familyname=helveticaneue}
+%D \TestLookup{familyname=helveticaneue,weight=bold}
+%D \TestLookup{familyname=helveticaneue,weight=bold,style=italic}
+%D \stoptyping
+
+% we can also move the lookups to the fonts.namespace (of commands)
+
+\def\dolookupfontbyspec #1{\ctxlua{fonts.names.lookup("#1")}}
+\def\dolookupnoffound {\ctxlua{tex.write(fonts.names.noflookups())}}
+\def\dolookupgetkeyofindex#1#2{\ctxlua{tex.write(fonts.names.getlookupkey("#1",#2))}}
+\def\dolookupgetkey #1{\ctxlua{tex.write(fonts.names.getlookupkey("#1"))}}
+\def\cleanfontname #1{\ctxlua{fonts.cleanname("#1")}}
+
+\protect \endinput
+
+% \startluacode
+% function commands.doifelsecurrentfonthasfeature(name)
+% local f = fonts.ids[font.current()]
+% f = f and f.shared
+% f = f and f.otfdata
+% f = f and f.luatex
+% f = f and f.features
+% commands.doifelse(f and (f.gpos[name] or f.gsub[name]))
+% end
+% \stopluacode
+
+% \def\doifelsecurrentfonthasfeature#1%
+% {\ctxlua{commands.doifelsecurrentfonthasfeature("#1")}}
+
+% \doifelsecurrentfonthasfeature{smcp}{YES}{NO}
+% \doifelsecurrentfonthasfeature{crap}{YES}{NO}
+% \doifelsecurrentfonthasfeature{kern}{YES}{NO}