%D \module
%D   [     file=font-sel,
%D      version=2016.08.28,
%D        title=\CONTEXT\ User Module,
%D     subtitle=Selectfont,
%D       author=Wolfgang Schuster,
%D         date=\currentdate,
%D    copyright=Wolfgang Schuster,
%D      license=GNU General Public License]

\writestatus{loading}{ConTeXt User Module / Selectfont}

\registerctxluafile{font-sel}{}

\unprotect

\installcorenamespace                      {selectfont}
\installsimplecommandhandler \??selectfont {selectfont}

\unexpanded\def\selectfont_register[#style][#settings]%
  {\begingroup
   \edef\currentselectfont{\expandnamespacevalue\??fontshortstyle{#style}\s!rm}%
   \checkselectfontparent
   \setupcurrentselectfont[#settings]%
   \edef\p_selectfont_preset{\selectfontparameter\c!preset}%
   \ifx\p_selectfont_preset\empty \else
     \processcommacommand[\p_selectfont_preset]\selectfont_preset_process
     \setupcurrentselectfont[#settings]%
   \fi
   \font_helpers_process_alternative_list\clf_registerfontalternative
   \setexpandedselectfontparameter\c!style{\expandnamespaceparameter\??fontshortstyle\selectfontparameter\c!style\s!rm}%
   \xdef\selectfont_index{\clf_registerfontfamily
        metadata {%
            typeface    {\selectfontparameter\c!label}%
            style       {\selectfontparameter\c!style}%
            family      {\selectfontparameter\c!name}%
        }
        options {%
            designsize  {\selectfontparameter\s!designsize}%
            rscale      {\selectfontparameter\s!rscale}%
            goodies     {\selectfontparameter\c!goodies}%
            extras      {\selectfontparameter\c!extras}%
            features    {\selectfontparameter\c!features}%
            preset      {\selectfontparameter\c!preset}%
            range       {\selectfontparameter\c!range}%  fallback only
            offset      {\selectfontparameter\c!offset}% fallback only
            check       {\selectfontparameter\c!check}%  fallback only
            force       {\selectfontparameter\c!force}%  fallback only
        }
        userdata {%
            \luaexpanded{#settings}%
        }}%
   \endgroup}

%D \macros
%D   {definefontfamilypreset}

\installcorenamespace {selectfontpreset}

\unexpanded\def\definefontfamilypreset
  {\dodoubleargument\selectfont_preset_define}

\def\selectfont_preset_define[#name][#settings]%
  {\doifelseassignment{#settings}
     {\setvalue{\??selectfontpreset#name}{\setupcurrentselectfont[#settings]}}
     {\setvalue{\??selectfontpreset#name}{\csname\??selectfontpreset#settings\endcsname}}}

\def\selectfont_preset_process#name%
  {\ifcsname\??selectfontpreset#name\endcsname
     \lastnamedcs
   \else
     % unknown preset
   \fi}

\def\selectfont_preset_define[#name][#settings]%
  {\setvalue{\??selectfontpreset#name}{\setupcurrentselectfont[#settings]}%
   \clf_definefontfamilypreset{#name}{\luaexpanded{#settings}}}

\definefontfamilypreset
  [range:chinese]
  [\c!range={cjkcompatibilityforms,
             cjkcompatibilityideographs,
             cjkcompatibilityideographssupplement,
             cjkradicalssupplement,
             cjkstrokes,
             cjksymbolsandpunctuation,
             cjkunifiedideographs,
             cjkunifiedideographsextensiona,
             cjkunifiedideographsextensionb,
             halfwidthandfullwidthforms,
             verticalforms,
             bopomofo,
             bopomofoextended}]

\definefontfamilypreset
  [range:japanese]
  [\c!range={cjkcompatibilityforms,
             cjkcompatibilityideographs,
             cjkcompatibilityideographssupplement,
             cjkradicalssupplement,
             cjkstrokes,
             cjksymbolsandpunctuation,
             cjkunifiedideographs,
             cjkunifiedideographsextensiona,
             cjkunifiedideographsextensionb,
             halfwidthandfullwidthforms,
             verticalforms,
             hiragana,
             katakana}]

\definefontfamilypreset
  [range:korean]
  [\c!range={cjkcompatibilityforms,
             cjkcompatibilityideographs,
             cjkcompatibilityideographssupplement,
             cjkradicalssupplement,
             cjkstrokes,
             cjksymbolsandpunctuation,
             cjkunifiedideographs,
             cjkunifiedideographsextensiona,
             cjkunifiedideographsextensionb,
             halfwidthandfullwidthforms,
             verticalforms,
             hangulcompatibilityjamo,
             hanguljamo,
             hanguljamoextendeda,
             hanguljamoextendedb,
             hangulsyllables}]

\definefontfamilypreset
  [range:cyrillic]
  [\c!range={cyrillic,
             cyrillicextendeda,
             cyrillicextendedb,
             cyrillicsupplement}]

\definefontfamilypreset
  [range:greek]
  [\c!range={greekandcoptic,
             greekextended,
             ancientgreeknumbers}]

\definefontfamilypreset
  [range:hebrew]
  [\c!range={hebrew,
             alphabeticpresentationforms}]

\definefontfamilypreset [math:digitsnormal]             [\c!range=digitsnormal]
\definefontfamilypreset [math:digitsbold]               [\c!range=digitsnormal,\c!offset=digitsbold,\s!tf=style:bold]

\definefontfamilypreset [math:uppercasenormal]          [\c!range=uppercasenormal]
\definefontfamilypreset [math:uppercaseitalic]          [\c!range=uppercasenormal,\c!offset=uppercaseitalic,    \s!tf=style:italic]
\definefontfamilypreset [math:uppercasebold]            [\c!range=uppercasenormal,\c!offset=uppercasebold,      \s!tf=style:bold]
\definefontfamilypreset [math:uppercasebolditalic]      [\c!range=uppercasenormal,\c!offset=uppercasebolditalic,\s!tf=style:bolditalic]

\definefontfamilypreset [math:lowercasenormal]          [\c!range=lowercasenormal]
\definefontfamilypreset [math:lowercaseitalic]          [\c!range=lowercasenormal,\c!offset=lowercaseitalic,    \s!tf=style:italic]
\definefontfamilypreset [math:lowercasebold]            [\c!range=lowercasenormal,\c!offset=lowercasebold,      \s!tf=style:bold]
\definefontfamilypreset [math:lowercasebolditalic]      [\c!range=lowercasenormal,\c!offset=lowercasebolditalic,\s!tf=style:bolditalic]

\definefontfamilypreset [math:mathematicaloperators]    [\c!range=mathematicaloperators]

\definefontfamilypreset [math:lowercasegreeknormal]     [\c!range=lowercasegreeknormal]
\definefontfamilypreset [math:lowercasegreekitalic]     [\c!range=lowercasegreeknormal,\c!offset=lowercasegreekitalic,    \s!tf=style:italic]
\definefontfamilypreset [math:lowercasegreekbold]       [\c!range=lowercasegreeknormal,\c!offset=lowercasegreekbold,      \s!tf=style:bold]
\definefontfamilypreset [math:lowercasegreekbolditalic] [\c!range=lowercasegreeknormal,\c!offset=lowercasegreekbolditalic,\s!tf=style:bolditalic]

\definefontfamilypreset [math:uppercasegreeknormal]     [\c!range=uppercasegreeknormal]
\definefontfamilypreset [math:uppercasegreekitalic]     [\c!range=uppercasegreeknormal,\c!offset=uppercasegreekitalic,    \s!tf=style:italic]
\definefontfamilypreset [math:uppercasegreekbold]       [\c!range=uppercasegreeknormal,\c!offset=uppercasegreekbold,      \s!tf=style:bold]
\definefontfamilypreset [math:uppercasegreekbolditalic] [\c!range=uppercasegreeknormal,\c!offset=uppercasegreekbolditalic,\s!tf=style:bolditalic]

%D \macros
%D   {definefontfamily,definefallbackfamily}
%D
%D The \tex{definefontfamily} creates like \tex{definetypeface} a collection of font
%D with different styles which can be later called with the \tex{setupbodyfont} command.
%D
%D The command takes three mandatory commands which are (a) the name of the fontclass,
%D (b) the styles of the font and (c) the name of the font.
%D
%D \starttyping
%D \definefontfamily [dejavu] [serif] [DejaVu Serif]
%D \definefontfamily [dejavu] [sans]  [DejaVu Sans]
%D \definefontfamily [dejavu] [mono]  [DejaVu Sans Mono]
%D \definefontfamily [dejavu] [math]  [XITS Math] [rscale=1.1]
%D
%D \definefontfamily [office] [serif] [Times New Roman]
%D \definefontfamily [office] [sans]  [Arial] [rscale=0.9]
%D \definefontfamily [office] [mono]  [Courier]
%D \definefontfamily [office] [math]  [TeX Gyre Termes Math]
%D
%D \definefontfamily [linux] [serif] [Linux Libertine O]
%D \definefontfamily [linux] [sans]  [Linux Biolinum O]
%D \definefontfamily [linux] [mono]  [Latin Modern Mono]
%D \definefontfamily [linux] [math]  [TeX Gyre Pagella Math] [rscale=0.9]
%D
%D \setupbodyfont[dejavu]
%D
%D \starttext
%D
%D \rm Serif \ss Sans \tt Mono \m{1+2=3}
%D
%D \switchtobodyfont[office]
%D
%D \rm Serif 123 \ss Sans \tt Mono \m{1+2=3}
%D
%D \switchtobodyfont[linux]
%D
%D \rm Serif 123 \ss Sans \tt Mono \m{1+2=3}
%D
%D \stoptext
%D \stoptyping
%D
%D When a document contains different languages and the global font lacks some characters
%D for one language, one could set a different font where these charcters are taken from.
%D This fallback font (there can be more than one for a certain style) could be set with
%D the \tex{definefallbackfamily} command which takes the same argument as
%D the \tex{definefontfamily} command.
%D
%D \starttyping
%D \definefallbackfamily [mainface] [serif] [DejaVu Serif] [range=cyrillic]
%D \definefontfamily     [mainface] [serif] [TeX Gyre Pagella]
%D
%D \setupbodyfont[mainface]
%D
%D \setuplanguage[en][patterns={us,ru}]
%D
%D \starttext
%D
%D \input knuth
%D
%D Традиционная систематика лишайников оказывается во многом условна и
%D
%D \stoptext
%D \stoptyping
%D
%D Another feature of the module is the \type{designsize} key which allows one to enable
%D optical sizes when they are a feature of the requested font.
%D
%D \starttyping
%D \definefontfamily[mainface][serif][Latin Modern Roman][designsize=auto]
%D
%D \setupbodyfont[mainface]
%D
%D \starttext
%D \scale[width=\textwidth]{\switchtobodyfont   [6pt]\tf Regular, \it Italic \bf Bold and \bi BoldItalic}
%D \scale[width=\textwidth]{\switchtobodyfont   [8pt]\tf Regular, \it Italic \bf Bold and \bi BoldItalic}
%D \scale[width=\textwidth]{\switchtobodyfont  [10pt]\tf Regular, \it Italic \bf Bold and \bi BoldItalic}
%D \scale[width=\textwidth]{\switchtobodyfont  [12pt]\tf Regular, \it Italic \bf Bold and \bi BoldItalic}
%D \scale[width=\textwidth]{\switchtobodyfont[17.3pt]\tf Regular, \it Italic \bf Bold and \bi BoldItalic}
%D \stoptext
%D \stoptyping

% tf = … | * … | name:… | name:* … | file:… | file:* … | style:medium

\unexpanded\def\definefontfamily
  {\doquadrupleempty\selectfont_family_define}

\def\selectfont_family_define[#typeface][#style][#family][#settings]%
  {\doifelseassignment{#settings}
     {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]}
     {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}%
   \clf_definefontfamily\selectfont_index\relax}

\unexpanded\def\definefallbackfamily
  {\doquadrupleempty\selectfont_fallback_define}

\def\selectfont_fallback_define[#typeface][#style][#family][#settings]%
  {\doifelseassignment{#settings}
     {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]}
     {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}%
   \clf_definefallbackfamily\selectfont_index\relax}

\unexpanded\def\setupfontfamily
  {\dodoubleargument\selectfont_family_setup}

\def\selectfont_family_setup[#style][#settings]%
  {\ifsecondargument
     \edef\currentselectfont{\expandnamespacevalue\??fontshortstyle{#style}\s!rm}%
     \setupcurrentselectfont[#settings]%
   \else
     \let\currentselectfont\empty
     \setupcurrentselectfont[#style]%
   \fi}

\setupselectfont
  [  \c!features=\s!default,
   \s!designsize=\s!default,
       \s!rscale=\selectfontparameter\c!scale,
        \c!scale=1]

\protect
