summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/fonts-select.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/optex/base/fonts-select.opm')
-rw-r--r--macros/luatex/optex/base/fonts-select.opm670
1 files changed, 670 insertions, 0 deletions
diff --git a/macros/luatex/optex/base/fonts-select.opm b/macros/luatex/optex/base/fonts-select.opm
new file mode 100644
index 0000000000..83ded2f35b
--- /dev/null
+++ b/macros/luatex/optex/base/fonts-select.opm
@@ -0,0 +1,670 @@
+%% This is part of OpTeX project, see http://petr.olsak.net/optex
+
+\_codedecl \fontfam {Fonts selection system <2020-03-18>} % preloaded in format
+
+ \_doc -----------------------------
+ The \`\initunifonts` initializes extended `\font` primitive
+ (to be able to load Unicode fonts). Unfortunately, this part of
+ \OpTeX/ depends on \LaTeX/ lua codes `ltluatex.lua` and
+ `luaotfload-main.lua`. And this code need to be declared a
+ control sequence `\e@alloc@attribute@count` by `\countdef` primitive.
+ Moreover, the `\initunifont` switches with
+ the \^`\_doresizefont` macro to OTF mode which is represented by the
+ macro \`\_doresizeunifont`. This mode includes
+ a fallback to TFM mode if \^`\_fontnamegen` is not defined.
+ Finally, the `\initunifnt` sets itself to relax because we need not to do
+ this work twice.
+ \_cod -----------------------------
+
+\_def\_initunifonts {%
+ \_ea\_newcount \_csname e@alloc@attribute@count\_endcsname
+ \_global \_csname e@alloc@attribute@count\_endcsname=-1
+ \_directlua{%
+ require("ltluatex")
+ require('luaotfload-main') local _void = luaotfload.main ()
+ }%
+ \_gdef\_rfskipatX ##1" ##2\_relax{"##1"}%
+ \_global\_let \_doresizefont=\_doresizeunifont
+ \_gdef\_tryloadtt {\_fontdef\_tentt{\_def\_fontnamegen{[lmmono10-regular]}\_rm}}%
+ \_global\_let \_initunifonts=\_relax % we need not to do this work twice
+ \_global\_let \initunifonts=\_relax
+}
+\_gdef\_doresizeunifont #1{\_logfont{#1}%
+ \_ifx\_fontnamegen\_undefined \_doresizetfmfont#1\_else
+ \_font#1={\_fontnamegen} \_sizespec \_relax \_setwsp#1\_relax
+ \_fi
+}
+\_public \initunifonts ;
+
+ \_doc -----------------------------
+ The \`\_famdecl` `[<Family Name>] \<Famselector> {<comment>} {<modifiers>} {<variants>} {<math>}`\nl
+ `{<font for testing>} {\def`\^`\_fontnamegen``{<data>}}` runs \^`\initunifonts`, then
+ checks if `\<Famselector>` is defined. If it is true, then closes the file by
+ `\endinput`. Else it defines `\<Famselector>` and saves it to the \`\_mainfamcommand`
+ macro because the \`\_initfontfamily` needs it. The \`\_currfamily` is set
+ to the `<Famselector>` because the following \^`\moddef` commands need to
+ be in the right font family context. The `\_currfamily` is set to the
+ `<Famselector>` by the `\<Famselector>` too, because `\<Famselector>`
+ must set the right faily context. The font family context is given by the current
+ `\_currfamily` value and by the actual meaning of the \^`\_fontnamegen` macro.
+ \_cod -----------------------------
+
+\_def\_famdecl [#1]#2#3#4#5#6#7#8{%
+ \_initunifonts \_uniaccents
+ \_ifx #2\_undefined
+ \_isfont{#7}\_iffalse
+ \_opwarning{Family [#1] skipped, font "#7" not found}\_ea\_ea\_ea\_endinput \_else
+ \_edef\_currfamily {\_csstring #2}%
+ \_def\_mainfamcommand{#2}\_def\_mathfaminfo{#6}%
+ \_protected\_edef#2{\_def\_noexpand\_currfamily{\_csstring #2}\_unexpanded{#8\_resetmod}}%
+ \_wterm {FONT: [#1] -- \_string#2 \_detokenize{(#3)^^J mods:{#4} vars:{#5} math:{#6}}}%
+ \_fi
+ \_else \_ea #2\_ea\_endinput \_fi
+}
+\_def\_initfontfamily{%
+ \_mainfamcommand \_reloading \_rm
+}
+
+ \_doc -----------------------------
+ \`\_regoptsizes` `<internal-template> <left-output>?<right-output> <resizing-data>`
+ prepares data for using by the \`\_optname` `<internal-template>` macro.
+ The data are saved to the `\_oz:<internal-template>` macro.
+ When the `\_optname` is expanded then the data are scanned by the macro
+ \`\_optnameA` `<left-output>?<right-output> <mid-output> `\code{<}`<size>`
+ in the loop.\nl
+ \`\_optfontalias` `{<template A>}{<template B>}` is defined as
+ `\let\_oz:<templateA>=\_oz:<templateB>`.
+ \_cod -----------------------------
+
+\_def\_regoptsizes #1 #2?#3 #4*{\_sdef{_oz:#1}{#2?#3 #4* }}
+\_def\_optname #1{\_ifcsname _oz:#1\_endcsname
+ \_ea\_ea\_ea \_optnameA \_csname _oz:#1\_ea\_endcsname
+ \_else \_failedoptname{#1}\_fi
+}
+\_def\_failedoptname #1{optname-fails:(#1)}
+\_def\_optnameA #1?#2 #3 <#4 {\_ifx*#4#1#3#2\_else
+ \_ifdim\_optsize<#4pt #1#3#2\_optnameC
+ \_else \_afterfifi \_optnameA #1?#2 \_fi\_fi
+}
+\_def\_optnameC #1* {\_fi\_fi}
+\_def\_afterfifi #1\_fi\_fi{\_fi\_fi #1}
+\_def\_optfontalias #1#2{\_slet{_oz:#1}{_oz:#2}}
+
+ \_doc -----------------------------
+ \`\_fvars` `<rm-template> <bf-template> <it-template> <bi-template>`
+ saves data for usage by the `\_currV` macro. If a template is only dot
+ then previous template is used (it can be used if the font family doesn't
+ dispose with all standard variants).
+ \nl
+ \`\_currV` expands to a template declared by `\_fvars` depending on the
+ `<variant name>`. Usable only of standard four variants. Next variants
+ can be declared by the \^`\famvardef` macro.
+ \nl
+ \`\_fset` `<key>=<value>,...,<key>=<value>` expands to
+ `\def\_<key>V{<value>}` in the loop.
+ \nl
+ \`\_onlyif` `<key>=<value-a>,<value-b>...,<value-z>: {<what>}`
+ runs <what> only if the `\_<key>V` is defined as `<value-a>` or
+ `<value-b>` or ... or `<value-z>`.
+ \_cod -----------------------------
+
+\_def\_fvars #1 #2 #3 #4 {%
+ \_sdef{_fvar:rm}{#1}%
+ \_sdef{_fvar:bf}{#2}%
+ \_ifx.#2\_slet{_fvar:bf}{_fvar:rm}\_fi
+ \_sdef{_fvar:it}{#3}%
+ \_ifx.#3\_slet{_fvar:it}{_fvar:rm}\_fi
+ \_sdef{_fvar:bi}{#4}%
+ \_ifx.#4\_slet{_fvar:bi}{_fvar:it}\_fi
+}
+\_def\_currV{\_cs{_fvar:\_whatresize}}
+\_def\_V{ }
+\_def \_fsetV #1 {\_fsetVa #1,=,}
+\_def \_fsetVa #1=#2,{\_isempty{#1}\_iffalse
+ \_ifx,#1\_else\_sdef{_#1V}{#2}\_ea\_ea\_ea\_fsetVa\_fi\_fi
+}
+\_def \_onlyif #1=#2:#3{%
+ \_edef\_act{\_noexpand\_isinlist{,#2,}{,\_cs{_#1V},}}\_act
+ \_iftrue #3\_fi
+}
+
+ \_doc -----------------------------
+ The \`\moddef` `\<modifier> {<data>}` simply speaking does
+ `\def\<modifier>{<data>}`, but we need to respect
+ the family context. In fact, `\protected\def\_f:<current family>:<modifier>{<data>}` is
+ performed and the `\<modifier>` is defined as
+ \`\_famdepend``\<modifier>{_f:\_currfamily:<modifier>}`. It expands to
+ `\_f:\_currfamily:<modifier>` value if it is defined or it prints
+ warning. When the `\_currfamily` value is
+ changed then we can declare the same `\<modifier>` with different meaning.
+
+ When user declare a prefixed variant of the `\<modifier>` then unprefixed
+ modifier name is used in internal macros, this is reason why we are using
+ the \`\_remifirstunderscore``\_tmp` (where `\_tmp` expands to
+ `_<something>` or to `<something>`. The `\_remifirstunderscore`
+ redefines `\_tmp` in the way that it
+ expands only to `<something>` without the first `_`.
+ \_cod -----------------------------
+
+\_def \_moddef #1#2{\_edef\_tmp{\_csstring#1}\_remfirstunderscore\_tmp
+ \_sdef{_f:\_currfamily:\_tmp}{#2\_reloading}%
+ \_protected \_edef #1{\noexpand\_famdepend\noexpand#1{_f:\noexpand\_currfamily:\_tmp}}%
+ \_ea \_ifx \_csname\_tmp\_endcsname #1\_else
+ \_ea \_public \_csname\_tmp\_endcsname ;\_fi
+}
+\_def\_remfirstunderscore#1{\_ea\_remfirstunderscoreA#1\_relax#1}
+\_def\_remfirstunderscoreA#1#2\_relax#3{\_if _#1\_def#3{#2}\_fi}
+
+\_protected \_def\_resetmod {\_cs{_f:\_currfamily:resetmod}} % private variant of \resetmod
+\_def\_currfamily{} % default current family is empty
+
+\_def\_famdepend#1#2{\_ifcsname#2\_endcsname \_csname#2\_ea\_endcsname \_else
+ \_opwarning{\_string#1 is undeclared in current family "\_currfamily", ignored}\_fi
+}
+\_public \moddef ;
+
+ \_doc -----------------------------
+ The \`\famvardef` `\<XX> {<data>}`
+ uses analogical trick like \^`\moddef` with
+ the \^`\_famdepend` macro. The auxiliary
+ \`\_famvardefA` `\<XX> \_ten<XX> \_tryload<XX> {<data>}` is used.
+ It does:
+ \begitems
+ * `\protected\def \<XX> {\_famdepend \<XX> {_f:\_currfamily:<XX>}}`,
+ * `\def \_f:<current family>:<XX> {\_tryload<XX>\_ten<XX>}` keeps family dependent definition,
+ * `\def \_tryload<XX> {`\^`\fontdef`` \_ten<XX> {<data>}}` loads actually the font `\_ten<XX>`,
+ * `\def \_currvar:_ten<XX> {\<XX>}` in ordef to the \^`\currvar` macro
+ work correctly.
+ \enditems
+ \_cod -----------------------------
+
+\_def\_famvardef#1{\_edef\_tmp{\_csstring#1}\_remfirstunderscore\_tmp
+ \_ea\_famvardefA \_ea#1\_csname _ten\_tmp\_ea\_endcsname
+ \_csname _tryload:\_tmp\_endcsname
+}
+\_def\_famvardefA #1#2#3#4{% #1=\_XX #2=\_tenXX #3=\_tryloadXX #4=data
+ \_isinlist{.\_rm\_bf\_it\_bi\currvar\_currvar}#1\_iftrue
+ \_opwarning{\_string\famvardef:
+ You cannot re-declare private standard variant selector \_string#1}%
+ \_else
+ \_protected\_edef #1{\_noexpand\_famdepend\_noexpand#1{_f:\_noexpand\_currfamily:\_tmp}}%
+ \_sdef{_f:\_currfamily:\_tmp}{#3#2}%
+ \_def#3{\_fontdef#2{#4}}%
+ \_ifx#1\tt \_addto#1{\_fam\_ttfam}\_fi
+ \_sdef{_currvar:\_csstring#2}{#1}%
+ \_fi
+}
+\_public \famvardef ;
+
+ \_doc -----------------------------
+ The \`\fontfam` `[<Font Family>]` does:
+ \begitems
+ * Convert its parameter to lower case and without spaces, e.g.\ `<fontfamily>`.
+ * If the file `f-<fontfamily>.opm` exists read it and finish.
+ * Try to load user defined `fams-local.opm`.
+ * If the `<fontfamily>` is declared in `fams-local.opm` or `fams-ini.opm`
+ read relevant file and finish.
+ * Print the list of declared families.
+ \enditems
+ The `fams-local.opm` is read by the \`\_tryloadfamslocal` macro. It sets
+ itself to `\_relax` because we need not to load this file twice.
+ The \`\_listfamnames` macro prints registered font families to the
+ terminal and to the log file.
+ \_cod -----------------------------
+
+\_def\_fontfam[#1]{%
+ \_lowercase{\_edef\_famname{\_ea\_removespaces #1 {} }}%
+ \_isfile {f-\_famname.opm}\_iftrue \_opinput {f-\_famname.opm}%
+ \_else
+ \_tryloadfamslocal
+ \_edef\_famfile{\_trycs{_famf:\_famname}{}}%
+ \_ifx\_famfile\_empty \_listfamnames
+ \_else \_opinput {\_famfile.opm}%
+ \_fi\_fi
+}
+\_def\_tryloadfamslocal{%
+ \_isfile {fams-local.opm}\_iftrue
+ \_opinput {fams-local.opm}
+ \_fi
+ \_let \_tryloadfamslocal=\_relax % need not to load fams-local.opm twice
+}
+\_def\_listfamnames {%
+ \_wterm{===== List of font families ======}
+ \_begingroup
+ \_let\_famtext=\_wterm
+ \_def\_faminfo [##1]##2##3##4{%
+ \_wterm{ \_space\_noexpand\fontfam [##1] -- ##2}%
+ \_let\_famalias=\_famaliasA}%
+ \_opinput {fams-ini.opm}
+ \_isfile {fams-local.opm}\_iftrue \_opinput {fams-local.opm}\_fi
+ \_message{^^J}%
+ \_endgroup
+}
+\_def\_famaliasA{\_message{ \_space\_space\_space\_space -- alias:}
+ \_def\_famalias[##1]{\_message{[##1]}}\_famalias
+}
+\_public \fontfam ;
+
+ \_doc -----------------------------
+ When the `fams-ini.opm` or `fams-loca.opm` files are read then we need
+ to save ony a mapping from family names or alias names to the font family file
+ names. All other information is ignored in this case. But if these files
+ are read by the `\_listfamnames` macro or when printing a catalog then
+ more infrormation is used and printed.\nl
+ \`\_famtext` does nothing or prints the text on the terminal.
+ \nl
+ \`\_faminfo` `[<Family Name>] {<comments>} {<file-name>} {<mod-plus-vars>}`
+ does\nl `\_def \_famf:<familyname> {<file-name>}` or prints information on
+ the terminal.
+ \nl
+ \`\_famalias` `[<Family Alias>]` does `\def \_famf:<familyalias> {<file-name>}`
+ where `<file-name>` is stored from the previous `\_faminfo` command. Or
+ prints information on the terminal.
+ \_cod -----------------------------
+
+\_def\_famtext #1{}
+\_def\_faminfo [#1]#2#3#4{%
+ \_lowercase{\_edef\_tmp{\_ea\_removespaces #1 {} }}%
+ \_sdef{_famf:\_tmp}{#3}%
+ \_def\_famfile{#3}%
+}
+\_def\_famalias [#1]{%
+ \_lowercase{\_edef\_famname{\_ea\_removespaces #1 {} }}%
+ \_sdef{_famf:\_famname\_ea}\_ea{\_famfile}%
+}
+\_input fams-ini.opm
+\_let\_famfile=\_undefined
+
+ \_doc -----------------------------
+ When the \^`\fontfam``[catalog]` is used then the file
+ `fonts-tatalog.opm` is read. The macro \^`\_faminfo` is redefined here
+ in order to print catalog samples of all declared modifiers/variant
+ pairs. The user can declare different samples and different behavior of
+ the catalog, see the end of catalog listing for more information.
+ The default parameters
+ \`\catalogsample`, \`\catalogmathsample`, \`\catalogonly` and
+ \`\catalogexclude` of the catalog are declared here.
+ \_cod -----------------------------
+
+\_newtoks \_catalogsample
+\_newtoks \_catalogmathsample
+\_newtoks \_catalogonly
+\_newtoks \_catalogexclude
+\_catalogsample={ABCDabcd Qsty fi fl áéíóúüů řžč ÁÉÍÓÚ ŘŽČ 0123456789}
+
+\_public \catalogonly \catalogexclude \catalogsample \catalogmathsample ;
+
+ \_doc -----------------------------
+ The font features are managed in the \`\_fontfeatures` macro.
+ They have their implicit values saved in the \`\_defaultfontfeatures`
+ and the \`\setff` `{<features>}`
+ can add next font features. If there is the same font feature as the newly
+ added one then the old value is removed from the `\_fontfeatures` list.
+ \_cod -----------------------------
+
+\_def \_defaultfontfeatures {+tlig;}
+\_def \_setff #1{%
+ \_ifx^#1^\_let \_fontfeatures=\_defaultfontfeatures
+ \_else \_edef\_fontfeatures{\_fontfeatures #1;}\_fi
+ \_reloading
+}
+\_setff {} % default font features: +tlig;
+\_def\_removefeature #1{%
+ \_isinlist\_fontfeatures{#1}\_iftrue
+ \_def\_tmp ##1#1##2;##3\_relax{\_def\_fontfeatures{##1##3}}%
+ \_ea \_tmp \_fontfeatures \_relax
+ \_fi
+}
+\_public \setff ;
+
+ \_doc -----------------------------
+ The \`\setfontcolor` and \`\setletterspace` are macros based on the
+ special font features provided by \LuaTeX/ (and by \XeTeX/ too but it is not
+ our business). The \`\setwordspace` recalulates the `\fontdimen2,3,4`
+ of the font using the \`\setwsp` macro which is used by the
+ \^`\_doresizeunifont` macro. It activates a dummy font feature `+Ws` too in
+ order the font is reloded by the `\font` primitive (with independent
+ `\fontdimen` registers).
+ \_cod -----------------------------
+
+\_def\_savedfontcolor{}
+\_def\_savedletterspace{}
+\_def\_savedwsp{}
+
+\_def \_setfontcolor #1{\_removefeature{color=}%
+ \_edef\_tmp{\_calculatefontcolor{#1}}%
+ \_ifx\_tmp\_empty \_else \_edef\_fontfeatures{\_fontfeatures color=\_tmp;}\_fi
+ \_reloading
+}
+\_def \_setletterspace #1{\_removefeature{letterspace=}%
+ \_if^#1^\_else \_edef\_fontfeatures{\_fontfeatures letterspace=#1;}\_fi
+ \_reloading
+}
+\_def \_setwordspace #1{%
+ \_if^#1^\_def\_setwsp##1{}\_removefeature{+Ws}%
+ \_else \_def\_setwsp{\_setwspA{#1}}\_setff{+Ws}\_fi
+ \_reloading
+}
+\_def\_setwsp #1{}
+\_def\_setwspA #1#2{\_fontdimen2#2=#1\_fontdimen2#2%
+ \_fontdimen3#2=#1\_fontdimen3#2\_fontdimen4#2=#1\_fontdimen4#2}
+
+\_def\_calculatefontcolor#1{\_trycs{_fc:#1}{#1}} % you can define more smart macro ...
+\_sdef{_fc:red}{FF0000FF} \_sdef{_fc:green}{00FF00FF} \_sdef{_fc:blue}{0000FFFF}
+\_sdef{_fc:yellow}{FFFF00FF} \_sdef{_fc:cyan}{00FFFFFF} \_sdef{_fc:magenta}{FF00FFFF}
+\_sdef{_fc:white}{FFFFFFFF} \_sdef{_fc:grey}{00000080} \_sdef{_fc:lgrey}{00000025}
+\_sdef{_fc:black}{} % ... you can declare more colors...
+
+\_public \setfontcolor \setletterspace \setwordspace ;
+
+\_endcode %---------------------------------------------------
+
+
+\sec[fontsystem] The Font Selection System
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The basic principles of the Font Selection System used in \OpTeX/
+was documented in the section~\ref[fontfam].
+
+\secc Terminology
+
+We distinguish between
+\begitems
+* {\em font switchers}, they are declared by the `\font` primitive or by
+ \^`\fontlet` or \^`\fontdef` macros,
+* {\em variant selectors}, there are four basic variant selectors
+ `\rm`, `\bf`, `\it`, `\bi`, there is a special selector `\currvar`
+ and more variant selectors can be declared by the \^`\famvardef` macro.
+* {\em font modifiers} (for example `\cond`, `\caps`, \^`\setfontsize``{<size spec>}`),
+ they are in two types: bulid in (like \^`\setfontsize`) or
+ declared modifiers (by by the \^`\moddef` macro).
+* {\em family selectors} (for example `\Termes`, `\LMfonts`),
+ they are declared typically in the {\em font family files}.
+\enditems
+
+These selectors / switchers sets its values locally. When the \TeX/ group is
+leaved then selected font and the {\em font context} are returned back to the values
+used when the group was opened. They have the following features:
+
+\begitems
+* The {\em font switchers} select fonts independent on the font context.
+* The {\em variant selectors} select the font depending on the font context and on
+ the specified variant.
+* The {\em font modifiers} create a change in the font context but they
+ don't select the font itself.
+* The {\em family selectors} set a family in the font context and resets all
+ font modifiers. They dont't select the font itself.
+\enditems
+
+The variant selectors and declared font modifiers are
+defined in the family context. They can behave differently in different
+families.
+
+The fonts registered in \OpTeX/ have their macros in the {\em font family files},
+each family is declared in one font family file with the name `f-famname.opm`.
+All families are collected in `fams-ini.opm` and user can give more
+declarations in the file `fams-local.opm`.
+
+\secc Font families, selecting fonts
+
+The \^`\fontfam` `[<Font Family>]` opens the relevant font family file where
+the `<Font Family>` is declared. The family selector is defined here by rules
+described in the section~\ref[fontfamfiles]. Font modifiers and variant
+selectors may be declared here. Their definitions depends on given family.
+The family is set as active in the font context and `\rm` variant selector is run.
+
+The available declared font modifiers and declared variant selectors are
+listed in the log file when font family is load. Or you can print
+`\fontfam[catalog]` to show available font modifiers and variant selectors.
+
+The font modifiers can be independent, like `\cond` and `\light`. They can
+be arbitrary combined (in arbitrary order) and if the font family disposes
+with all such sub-variants then the desired font is selected (after variant
+selector is used). On the other hand there are font modifiers which negates
+the previous font modifier, for example `\cond`, `\extend`. You can reset
+all modifiers to their initial value by the \^`\resetmod` command.
+
+You can open more font families by more \^`\fontfam` commands. Then the
+general method to selecting the individual font is:
+
+\begtt \catcode`\<=13
+<family selector> <font modifiers> <variant selector>
+\endtt
+For example:
+\begtt
+\fontfam [Heros] % Heros family is active here, default \rm variant.
+\fontfam [Termes] % Termes family is active here, default \rm variant.
+{\Heros \caps \cond \it The caps+condensed italics in Heros family is here.}
+The Termes roman is here.
+\endtt
+
+There is one special command \^`\currvar` which acts as variant selector.
+It keeps the current variant and the font of such variant is
+reloaded with respect to the current font context by previously given family
+selector and font modifiers.
+
+You can use the \^`\setfontsize` `{<sizespec>}` command in the same sense as
+other font modifiers. It saves only information about font size to the font
+context. See section~\ref[setfontsize]. Example:
+
+\begtt
+\rm default size \setfontsize{at14pt}\rm here is 14pt size \it italic is
+in 14pt size too \bf bold too.
+\endtt
+
+Much more comfortable way to resize fonts is using OPmac-like command
+`\typosize`, `\typoscale`.
+These commands prepare the right sizes for math
+fonts too and re-calculates many internal parameters like `\baselineskip`.
+See section~\ref[opmac-fonts] for more information.
+
+
+\secc Math Fonts
+%---------------
+
+Most font families are connected with a preferred Unicode-math font. This
+Unicode-math is activated when the font family is loaded. If you don't prefer
+this and you are satisfied with 8bit math CM+AMS fonts preloaded in the
+\OpTeX/ format then you can use command \^`\noloadmath` before you load a first
+font family.
+
+If you want to use your specially selected Unicode-math font then use
+\^`\loadmath` `{[<font_file>]}` or \^`\loadmath` `{<font_name>}` before first
+`\fontfam` is used.
+
+
+\secc Declaring font commands
+%----------------------------
+
+The font switches can be declared by `\font` primitive or by \^`\fontdef` or
+\^`\fontlet` macros. See the sections~\ref[fontdef] and~\ref[fontlet]
+for more details. The general format for \^`\fontdef` is
+\begtt \catcode`\<=13
+\fontdef\<font switch> {\<family selector> <font modifiers> \<variant selector>}
+\endtt
+
+Such font switches should be used in `\output` routine (headers, footers) for
+example. We need fixed sizes here. But they are less usable in common
+text. For example the document includes notices in smaller font.
+When the notice is started then we want
+to do all variants smaller: `\rm`, `\it`, `\bf`, etc.
+It means that the smaller font for notices should be initialized by
+`\setfontsize{at9pt}\rm` for example. If you want a \"notices font selector"
+then you can do `\def\noticefont{\setfontsize{at9pt}\rm}`. This font
+selector does not change the `\baselineskip`. If you want to do this then
+put different `\baselineskip` setting to your definition. But you must not
+forget that the end of group before `\par` is a typical mistake of \TeX/
+users: the last paragraph is in smaller font but in normal baselineskip,
+because `\baselineskip` setting is taken into account when `\par`
+command is processed.
+
+Somewhat more complicated task is the \"title font selector", because titles are
+not only bigger but they are typically in bold variant. When the user puts
+`{\it...}` into the title then he/she expects bold italic here, no normal
+italic. You can remember the great song by John Lennon \"Let It Be" and
+define:
+
+\begtt
+\def\titlefont{\setfontsize{at14pt}\bf \let\it\bi}
+...
+{\titlefont here we have bold 14pt font and {\it here} was bold 14pt italics}
+\endtt
+
+You can declare a new variant slector by the \^`\famvardef` macro. This
+macro has similar syntax as \^`\fontdef`:
+\begtt \catcode`\<=13
+\famvardef\<new variant selector> {<font modifiers> \<variant selector>}
+\endtt
+%
+The `\<new variant selector>` should be used in the same sense as `\rm`,
+`\bf` etc. It can be used as the final command in the
+`\fontdef` or `\famvardef` declarators
+too. When the `\<new variant selector>` is used in normal text then it does
+following steps: pushes current font context to a stack, modifies font
+context by declared `<font modifiers>`, runs following `\<variant selector>`.
+It selects a font. Then pops the stack. The font context have its original
+values but new font is selected.
+
+The \^`\famvardef` creates the `\<new variant selector>` family dependent.
+When the selector is used in another family than it is defined then warning is
+printed on the terminal \"<var selector> is undeclared in current family"
+and nothing happens. But you can declare the same variant selector by
+\^`\famvardef` macro in the context of new family. Then the same command
+will be do different work depending on the current font family.
+
+Suppose that the selected font family provides the font modifier `\medium` for
+mediate weight of fonts but supports only basic variant selectors `\rm`, `\bf`, `\it`,
+and `\bi`. Then you can declare:
+\begtt
+\famvardef \mr {\medium\rm}
+\famvardef \mi {\medium\it}
+\endtt
+Now, you can use six independent variant selectors `\rm`, `\bf`, `\it`,
+`\bi`, `\mr` and `\mi` in the selected font family.
+
+A `\<family selector>` can be written before `<font modifiers>` in the
+`\famvardef` parameter. Then the `\<new variant selector>` is declared in
+the current family but it can use fonts from another family represented by
+the `\<family selector>`.
+
+When you are mixing fonts from more families then you probably run
+into problem with incompatible ex-heights. This problem can be solved using
+\^`\setfontsize` and \^`\famvardef` macros:
+\begtt
+\fontfam[Heros] \fontfam[Termes]
+
+\def\exhcorr{\setfontsize{mag.88}}
+\famvardef\rmsans{\Heros\exhcorr\rm}
+\famvardef\itsans{\Heros\exhcorr\it}
+
+Compare ex-height of Termes \rmsans with Heros \rm and Termes.
+\endtt
+
+There exists analogical declarator `\moddef` for declaration family dependent
+font modifiers. It is described in detail the section~\ref[fontfamfiles].
+
+
+\secc Modifying font features
+%----------------------------
+
+Each OTF font provides \"font features". You can list these font features
+by `otfinfo -f font.otf`. For example LinLibertine fonts provide `frac` font
+feature. If it is active then fractions like 1/2 are printed in a special
+form.
+
+The font features are part of the font context data.
+The macro \^`\setff` `{<feature>}` acts like family independent font modifier and
+prepares a new <feature>. You must use a variant selector in order to
+reinitialize the font with the new font feature. For example
+\^`\setff``{+frac}\rm` or \^`\setff``{+frac}`\^`\currvar`. You can declare a new variant
+selector too:
+
+\begtt
+ \fontfam[LinLibertine]
+ \famvardef \fraclig {\setff{+frac}\currvar}
+ Compare 1/2 or 1/10 \fraclig to 1/2 or 1/10.
+\endtt
+
+If the used font does not supports given font feature then font is realoaded
+without warning nor error, silently. The font feature is not activated.
+
+The `onum` font feature (old style digits) is connected to `\caps` macro for
+Caps+SmallCaps variant in \OpTeX/ font family files. So you need not to
+create a new modifier, just use `{\caps`\^`\currvar`` 012345}`.
+
+
+\secc Special font modifiers
+%---------------------------
+
+Despite the font modifiers declared in the font family file (and dependent on
+the font family), we have following font modifiers (independent of font
+family):
+
+\begtt \catcode`\<=13
+\setfontsize{<sizespec>} % sets the font size
+\setff{<font feature>} % adds the font feature
+\setfontcolor{<color>} % sets font color
+\setletterspace{<number>} % sets letter spacing
+\setwordspace{<scaling>} % modifies word spacing
+\endtt
+
+The \^`\setfontsize` command is described in the section \ref[setfontsize].
+The \^`\setff` command was described in previous subsection.
+
+\^`\setfontcolor` `{<color>}` specifies the color and the opacity of the text.
+The <color> parameter should be in hexadecimal format of four bytes
+`<red><green><blue><opacity>`, for example `FF0080FF` means full red, zero
+green, half blue and full opacity. You can use names `red`, `green`, `blue`,
+`yellow`, `cyan`, `magenta`, `white`, `grey`, `lgrey` (without backslash)
+instead of the hexadecimal specification.
+The empty parameter `<color>` means default black color.
+
+That colors of fonts are implemented using \LuaTeX/ internal font feature. This
+is different approach than using colors in section \ref[colors].
+
+\^`\setletterspace` `{<number>}` specifies letter spacing of the font. The
+`<number>` is decimal number without unit. The unit is supposed as 1/100 of
+the font size. I.e. `2.5` means 0.25 pt when the font is at 10 pt size. The
+empty parameter `<number>` means no letter spacing which is default.
+
+\^`\setwordspace` `{<scaling>}` scales the default inter word space (defined in the
+font) and its stretching and shrinking parameters by given `<scaling>`
+factor. For example `\setwordspace{2.5}` multiplies inter word space by 2.5.
+
+If you need another font transformations, you can use `\setff`
+with following font features provided by Lua\TeX/:
+
+\begtt
+\setff{embolden=1.5}\rm % font is bolder because outline has nonzero width
+\setff{slant=0.2}\rm % font is slanted by a linear transformation
+\setff{extend=1.2}\rm % font is extended by a linear transformation.
+\setff{colr=yes}\rm % if the font includes colored characters, use colors
+\endtt
+
+Use font transformations mentioned above and \^`\setletterspace`,
+\^`\setwordspace` with care. The best setting of these values is default
+setting in every font, of course. If you really needs to set a different
+letter spacing then it is strongly recommended to add `\setff{-liga}` in
+order to disable ligatures. And setting a positive letter spacing probably
+needs to scale inter word spacing too.
+
+All mentioned font modifiers (with the exception of `\setfontsize`) work only
+with Unicode fonts loaded by \^`\fontfam`.
+
+\secc[fontfamfiles] How to create the font family file
+%------------------------------------------------------
+
+\printdoctail f-heros.opm
+
+\printdoctail f-lmfonts.opm
+
+\secc How to register the font family in the Font Selection System
+%---------------------------------------------------------------
+
+\printdoctail fams-ini.opm
+
+\endinput
+
+2020-04-18 \_tryloadfamslocal introduced
+ \_fontdecl -> \_famdecl with different concept
+2020-03-18 released