% \iffalse meta-comment
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% lua-font-config.dtx
% Additions and changes Copyright (C) 2024-2026 Clea F. Rees.
% Code from skeleton.dtx Copyright (C) 2015-2024 Scott Pakin (see below).
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%   https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008-05-04 or later.
%
% This work has the LPPL maintenance status \muaintained'.
%
% The Current Maintainer of this work is Clea F. Rees.
%
% This work consists of all files listed in manifest.txt.
%
% The file lua-font-config.dtx is a derived work under the terms of the
% LPPL. It is based on version 2.4 of skeleton.dtx which is part of
% dtxtut by Scott Pakin. A copy of dtxtut, including the
% unmodified version of skeleton.dtx is available from
% https://www.ctan.org/pkg/dtxtut and released under the LPPL.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \fi
%
% \iffalse
%<*driver>
\directlua{
  pdf.setmajorversion(2)
  pdf.setminorversion(0)
}
\RequirePackage{svn-prov}
\ProvidesFileSVN{$Id: lua-font-config.dtx 12180 2026-11-02 02:55:44Z cfrees $}[v0.2 \revinfo][\filename: \filebase]
\DefineFileInfoSVN[lfc]
\GetFileInfoSVN*
\begingroup
\makeatletter
\def\first@of@some#1 (#2){#1}
\xdef\lfc@semanticver{%
  \expandafter\first@of@some\lfc@version\relax
}
\endgroup
% ref. ateb Max Chernoff: https://tex.stackexchange.com/a/723294/ 
\def\MyMakePrivateLetters{\makeatletter\ExplSyntaxOn\endlinechar13}
\documentclass[british,a4paper]{ltxdoc}
% ltnews42 / ateb David Carlisle: https://tex.stackexchange.com/a/754799/ (sylwad Ulrike Fischer rhywle ond alla i ddim canfod o hyd iddo fe)
\let\OrigMakePrivateLetters\MakePrivateLetters
\let\MakePrivateLetters\MyMakePrivateLetters
\partokencontext=0
\usepackage{babel}
\usepackage{lua-font-config}
\fontconfig{%
  rm    = kproman,
  sf    = kpsans,
  tt    = {%
    name  = kpmono,
    fea   = {mode=node;script=dflt;language=dflt;-tlig},
  },
  math  = kpmath,
}
\usepackage{xcolor}
\usepackage{graphicx}
\usepackage{parskip}
\usepackage{changepage}
\usepackage{array}
\usepackage{tabularx}
\usepackage{xurl}
% sicrhau hyperindex=false: llwytho CYN bookmark
\usepackage{hypdoc}% ateb Ulrike Fischer: https://tex.stackexchange.com/a/695555/
\usepackage{bookmark}
\usepackage{minted}
\usepackage{csquotes}
\MakeAutoQuote{‘}{’}
\MakeAutoQuote*{“}{”}
\usepackage{cleveref}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
%^^A \OnlyDescription
%^^A \ExplSyntaxOn
% Note that some things are here because doc gets confused and erroneously thinks them macros.
\DoNotIndex{\verb,\ProvidesPackageSVN,\NeedsTeXFormat,\ProcessKeyOptions,\ExplSyntaxOn,\ExplSyntaxOff,\RequirePackage,\DefineFileInfoSVN,\GetInfoSVN,\@ifundefined,\@ifl@t@r,\ExplLoaderFileDate,\endinput,\PackageError,\PackageWarning,\PackageInfo,\author,\title,\maketitle,\date,\revinfo,\ProcessKeysOptions,\MessageBreak,\fmtversion,\filebase,\fileversion,\fileinfo,\filebase:,\filedate,\documentclass,\begin,\end,\item,\IfFormatAtLeastTF,\msg}
%^^A \ExplSyntaxOff
\definecolor{strawberry}{rgb}{1.000,0.000,0.502}
\definecolor{blueberry}{rgb}{0.000,0.000,1.000}
\definecolor{moss}{rgb}{0.000,0.502,0.251}
\hypersetup{%
  colorlinks=true,
  citecolor={moss},
  extension=pdf,
  linkcolor={strawberry},
  linktocpage=true,
  pdfcreator={TeX},
  pdfproducer={LuaTeX},
  urlcolor={blueberry}%
}
\NewDocElement[%
  idxtype=key,
  idxgroup=keys,
  printtype=\textit{key},
]{Key}{keyname}
\NewDocElement[%
  idxtype=fn.,
  idxgroup=functions,
  printtype=\textit{fn.},
  macrolike=true,
]{Fn}{function}
\NewDocElement[%
  idxtype=var.,
  idxgroup=variables,
  printtype=\textit{var.},
  macrolike=true,
]{Var}{variable}
\NewDocumentCommand \val { m }
{%
  {\ttfamily =\,\meta{#1}}%
}
\NewDocumentCommand \mval {m} {%
  {\ttfamily=\,\marg{#1}}%
}
\ExplSyntaxOn
\NewDocumentCommand \vals { m }
{
  {
    \ttfamily = \, 
    \clist_use:nn { #1 } { \textbar }
  }
} 
\keys_define:nn { lfc / doc }
{
  unknown .code:n = {
    \cs_if_free:cT { \l_keys_key_str }
    {
      \tl_gset:cn { \l_keys_key_str } { #1 }
    }
  },
}
\NewDocumentCommand \lfcdocset { +m }
{
  \keys_set:nn { lfc / doc } { #1 }
}
\setminted     {style=sas,breaklines=true,breakafter={\,},
  frame=single,rulecolor=darkgray,
}
\newmintedfile [lfcdocfile]{latex} {
  rangestartstring={\\documentclass},
  rangestopstring={\\end\{document\}},
  frame = topline,
}
\NewDocumentCommand \lfcee { s o m} {
  \begin{figure}
    \IfBooleanT {#1} {
      \begin{adjustwidth}{-8pc}{}
    }
      \centering 
      \IfNoValueTF {#2} {
        \includegraphics{example-#3} 
        \par
      } {
        \clist_map_inline:nn {#2} {
          \includegraphics[page=##1]{example-#3}
          \par
        }
      }
      \caption{\texttt{example-#3}}\label{fig:ee-#3}
    \IfBooleanT {#1} {
      \end{adjustwidth}
    }
  \end{figure}
}
\ExplSyntaxOff
\lfcdocset{%
  bug={\href{https://codeberg.org/cfr/nfssext/issues}{\textsc{bugtracker}}},
  codeberg={\href{https://codeberg.org/cfr/nfssext}{\textsc{codeberg}}},
  github={\href{https://github.com/cfr42/nfssext}{\textsc{github}}},
  ctan={\href{https://ctan.org/}{\textsc{ctan}}},
}
\setcounter{IndexColumns}{2}
\makeatletter
\def\@xobeysp{\leavevmode\penalty100\ }
\NewCommandCopy \lfc@orig@cs \cs
\protected\def\lfc@safe@cs{%
  \begingroup
    \catcode`\_11\relax
    \lfc@safe@cs@aux
}
\protected\long\def\lfc@safe@cs@aux#1{%
    \lfc@orig@cs{#1}%
  \endgroup
}
\newcommand*\usesafecs{%
  \let\cs\lfc@safe@cs
}
\newcommand*\resetcs{%
  \let\cs\lfc@orig@cs
}
\makeatother
\begin{document}
  \DocInput{\filename}
\end{document}
%</driver>
% \fi
% \expandafter\title\expandafter{\csname lfc@base\endcsname}
% \author{Clea F. Rees\thanks{%
%     Many thanks to everyone who provided feedback on version 0.1.
%     I'd particularly like to thank Max Chernoff who is primarily responsible for cleaning up the Con\TeX{}t code, made many other suggestions and demonstrated remarkable patience in the face of my ineptitude.%
%   }%
% }%^^A\thanks{%
% \AddToHook{shipout/foreground}{%
%   \put (5mm,\dimeval{\baselineskip-\paperheight}) {%
%     \hbox to \dimeval{\paperwidth-10mm} {%
%       \footnotesize
%       Bug tracker:
%       \href{https://codeberg.org/cfr/nfssext/issues}{\url{https://codeberg.org/cfr/nfssext/issues}}
%       \textbar{} Code:
%       \href{https://codeberg.org/cfr/nfssext}{\url{https://codeberg.org/cfr/nfssext}}
%       \textbar{} Mirror:
%       \href{https://github.com/cfr42/nfssext}{\url{https://github.com/cfr42/nfssext}}% 
%       \hfill
%     }%
% }}
% \expandafter\date\expandafter{\csname lfc@semanticver\endcsname\thanks{%
%   \textsc{svn}: \UseName{lfc@rev} \UseName{lfc@date}%
% }}
% \maketitle
% \begin{abstract}
% An opentype font configuration package for Lua\LaTeXe{}.
% The aim is to provide an alternative to \pkg{fontspec} which is both faster and more powerful, by doing as much processing as possible in Lua.
% To avoid loading fonts unnecessarily, the data used is corrected during compilation and the results cached for future use.
%
% \emph{This package is experimental.}
% \end{abstract}
% 
% \section{Requirements}\label{sec:require}
%
% The package requires Lua\LaTeXe.
% It will not work with any other engine or format.
%
% Unicode maths is supported \emph{via} \pkg{lua-unicode-math}.
% It will \textbf{not} work with \pkg{unicode-math}.
%
% \section{Usage}\label{sec:pkg}
%
% \emph{The user interface is currently somewhat basic\footnote{%
%     \begin{tabular}{ll}
%       v0.1: & ‘\textbf{extremely} basic’.\\
%     \end{tabular}%
%   }%
% .}
%
% Currently documents using exclusively Latin scripts with no changes of the base font families are reasonably well supported \emph{via} key-value based configuration.
% This enables the choice of font family for the standard families --- i.e.~roman/serif, sans, typewriter/mono and (Unicode) maths (main, script and calligraphic) --- and configuration of additional fonts, again by family.
% In addition to this, scaling, ‘fake bold’, rendering mode, language choice and script selection may be configured for each family.
% A reasonable\footnote{%
%   Where ‘reasonable’ means I have some idea what they do and some, possibly merely theoretical, ability to test them.
%   This is naturally a quite unreasonable definition of ‘reasonable’ with a clear Western European bias.
%   Input from users of non-Latin scripts (initially for mono-script documents) would be particularly welcome.%
% } variety of opentype font features have key-value support.
%
% Alternatively or additionally, feature specifications may be passed more-or-less directly to the font loader.
% This enables any loader-supported specification to used and is faster, but requires knowledge of the syntax and opentype tag names.
%
% That said, the automated configuration is already quite extensive.
% By default, the package tries to configure font families which are as rich as possible, insofar as the fonts support this. 
% This includes
% \begin{itemize}
%   \item multiple widths and shapes, insofar as \textsc{nfss} supports them;
%   \item italic, oblique, upright italic, reverse italic, reverse oblique;
%   \item small-caps, italic small-caps, oblique small-caps\footnote{%
%     This should work whether small-caps are in separate fonts (e.g.~Latin Modern) or implemented by the \texttt{smcp} feature (e.g.~\TeX{}-Gyre Pagella).%
%   };
%   \item optical sizes.
% \end{itemize}
% Of course, this depends on the quality of the data the fonts provide.
% It is not always good or, even, vaguely accurate. 
% If things do not fit, some (currently minimal) effort is made to accommodate them as distinct font families, so they are still available at document level.
%
% At present, this is still a bit chaotic and probably not that easy to use, as the results are ‘hidden’ from you (in, of course, plain sight).
% Even so, you should typically need to do much less to access the fonts you want than you might otherwise expect. 
%
% The advantage of this is that if a font has several widths, you can easily adjust the one used for bold by simply redefining the relevant default.
% This is not very user friendly yet, but it is now a bit better than not completely terrible.
% 
%
% Simple usage looks like this:
% \iffalse
%<*verb>
% \fi
\begin{minted}{latex}
  \usepackage{lua-font-config}
  \fontconfig{%
    rm = texgyrepagella,
    sf = texgyreheros,
    tt = texgyrecursor,
    math = texgyrescholamath,
  }
\end{minted}
% \iffalse
%</verb>
% \fi
%
% \DescribeMacro{\fontconfig}\marg{key-val list}\par
% Specify font configuration.
% 
% \subsection{Keys}\label{subsec:keys}
% Top-level keys are described here.
% Keys for use in key-value lists are described in \cref{subsec:keys-cfg}.
%
% \DescribeKey{rm}\val{family name}\par
% \DescribeKey{rm}\mval{key-val list}\par
% Specify family to use as the main document font, typically a serif or ‘roman’ family.
%
% Available keys are listed below.
%
% \DescribeKey{sf}\val{family name}\par
% \DescribeKey{sf}\mval{key-val list}\par
% Specify family to use as the default sans family, typically a sans-serif.
%
% Available keys are listed below.
%
% \DescribeKey{tt}\val{family name}\par
% \DescribeKey{tt}\mval{key-val list}\par
% Specify family to use as the default ‘typewriter’ family, typically monowidth.
%
% Available keys are listed below.
%
% \DescribeKey{family}\val{family name}\par
% \DescribeKey{family}\mval{key-val list}\par
% Specify an additional text family.
% This will create a macro which can be used to switch to the requested family\footnote{%
%   Usually you will want to specify which macro, since otherwise you must figure out the family name the code uses, which may or may not match the one requested.
%   See \cref{subsubsec:keys-text-add}.%
% }.
%
% Available keys are listed below.
%
% \DescribeKey{math}\val{family name}\par
% \DescribeKey{math}\val{key-val list}\par
% Specify the family to use for typesetting Unicode mathematics.
% This sets the fonts used for symbols, script and calligraphic alphabets.
% It does not change the fonts used to typeset operators, since these are taken from text fonts and configured separately.
%
% Available keys are listed below.
%
% This option uses \pkg{lua-unicode-math}.
% \pkg{unicode-math} is \textbf{not} supported.
% If you wish to use \pkg{unicode-math}, do not use this option.
% Instead, load \pkg{unicode-math} and use \cs{setmathfont} as usual.
%
% \DescribeKey{debug}\mval{key-val list}\par
% This can be used to enable debugging and/or modify the logging level.
% It is primarily intended for use in debugging the package and unlikely to be of use in production.
% However, it may be useful the use this key if reporting a bug which cannot be reproduced e.g.~which is platform specific or depends on system fonts.
%
% \subsection{Keys for specifying font families}\label{subsec:keys-cfg}
%
% All keys described in \cref{subsec:keys} accept either a simple family name, as shown in the example above, or a braced key-value list.
% For example,
% \iffalse
%<*verb>
% \fi
\begin{minted}{latex}
  \usepackage{lua-font-config}
  \fontconfig{%
    rm = {%
      name = texgyrepagella, 
      fea  = {script=ltn;+tlig;+pnum},
    },
    sf = {%
      name  = texgyreheros,
      scale = 1.2,
      fea   = {script=cyrl;},
    },
    tt = {%
      name  = texgyrecursor,
      fea   = {+zero;},
      %% for completeness: false is anyway the default
      force = false,
    },
  }
\end{minted}
% \iffalse
%</verb>
% \fi
%
% This section describes these ‘inner’ keys.
%
% \subsubsection{Common keys}\label{subsubsec:common}
%
% These keys are accepted by all of \texttt{rm}, \texttt{sf}, \texttt{tt},
% \texttt{family} and \texttt{math}.
%
% \DescribeKey{name}\val{lookup name}\par
% The ‘name’ to lookup.
% This may, but need not be, the name of a font family.
% Shorter, less specific names will configure more families; longer, more specific names will configure fewer.
%
% For example, \texttt{name = texgyrepagellax,} will configure fewer than \texttt{name = texgyrepagella,} since the latter string matches both families, while the former does not.
% 
% The name is lower-cased prior to lookup. 
% The data used to generate actual font families uses a cleaned up version of the given name or, sometimes, a variation, depending on the data returned from the database.
%
% For example, \texttt{tex gyre PaGellA} yields the same results as \texttt{texgyrepagella}.
%
% Numbers are likewise removed\footnote{%
%   This is problematic for fonts which depend on digits in their names to distinguish them e.g.~Venturis ADF has four distinct ‘titling’ fonts, whose names differ by a single character, which is \texttt{1}, \texttt{2}, \texttt{3} or \texttt{4}. 
%   The algorithm used to sort the fonts into \textsc{nfss} families currently gets confused by this, leading to misleading warnings about ‘apparent duplicate’ fonts. 
%   (Something is indeed awry, but they are not duplicates.
%   Rather what should be four families appears to be only one.)%
% }.
%
%
% \DescribeKey{force}\vals{true,false}\par
% Boolean which determines whether cached data is to be regenerated on the basis of a new search of the font-loader's database.
%
% Note that this doesn't regenerate the loader's database itself. 
% It simply zaps data stored by this module for one or more font families.
%
% \DescribeKey{scale}\val{factor}\par
% Optional factor by which the font should be scaled e.g.~\texttt{20} or \texttt{0.8}.
% Ignored if a family includes distinct optical sizes.
%
% \subsubsection{Text-mode keys}\label{subsubsec:keys-text}
% These keys are accepted in all key-value specifications except for the top-level \texttt{math} key used to configure Unicode maths.
% They are used to configure font ‘features’ of various sorts.
% These include opentype features provided by the fonts, but also some additions provided by the font-loader or in other ways.
%
% There are currently two keys in this category.
% \texttt{fea} is a relatively low-level interface.
% It is fast, powerful and requires familiarity with opentype font features and the syntax supported by \pkg{luaotfload}.
% \texttt{features} is a mid-level interface which aims to provide a more user-friendly wrapper around \texttt{fea}.
%
% \textbf{If you are not sure which to use, use \texttt{features}.}
%
% The two keys may be used to configure the same family.
% If so, consistent options are combined; in case of conflicts, \texttt{features} takes precedence over \texttt{fea}.
% This means you can use the more-user friendly interface for most things and still add any unsupported specialist setup, if necessary. 
%
% \DescribeKey{features}\mval{key-value list}\par
% Optional list of font features \textbf{for text fonts only}. 
%
% {\bfseries Note that this interface is \emph{highly} experimental: it may, and very likely will, change\footnote{%
%     It is almost certain that it excludes things people need; it may also include things they don't.
%     Moreover, the groups of options are somewhat arbitrary, as are the keys' names.
%     It needs significant user input to determine what works best here, as \pkg{fontspec}'s framework is quite different.
% 
%     At some point, it also needs to be extended to permit per-font configuration e.g.~so that fake bold can be applied to create an additional weight, such as the \texttt{bf} series for a family which lacks bold.
%     And it should also be possible to specify different default weights and widths for the stand \texttt{md} and \texttt{bf} series e.g.~to use light and demi-bold, rather than regular and bold.
%     Right now, none of this is possible \emph{via} the key-value interface, though the latter is straightforward to do for users familiar with the roles of macros such as \cs{mddefault} and \cs{bfdefault}, at least in simple cases.%
%   }.%
% }
%
% The default is equivalent to \texttt{%
%   features=\{%
%     script=dflt,
%     mode=node,
%     language=dflt,
%     ligatures=tex%
%   \}%
% }.
% Unless provided in separate fonts, small-caps are enabled, if available, for upright, italic and oblique small-caps.
% 
% Features apply to \emph{all} fonts in the family specified by \texttt{name}, so you should not specify features you do not wish applied to all of them.
% 
% Currently, nine keys are supported.
% Where multiple values are listed, any combination of values is permitted in any order, but \textbf{inconsistent values should be avoided}.
%
% A \meta{key list} requires a comma-separated list of keys \emph{without values}:
%
% \texttt{\{\meta{key1},\meta{key2},\dots\}}
%
% A \meta{key-value list} requires a comma-separated list of key-values:
% \texttt{\{\meta{key1}=\meta{value1},\meta{key2}=\meta{value2},\dots\}}
%
% \DescribeKey{alternates}\mval{key/key-value list}\par
% \meta{key/key-value list} should be a comma-separated list of one or more of the following valueless keys\par
% \begin{tabularx}\linewidth{>{\ttfamily}lX}
%   contextual & enable standard contextual alternates \\
%   nocontextual & disable them \\
%   contextualswash & enable contextual ‘swash’ \\
%   linefinal & enable end-of-line forms \\
%   wordfinal & enable end-of-word forms \\
%   justification & enable forms designed to help justify text \\
%   swash & enable ‘swash’ \\
% \end{tabularx}\par
% and/or one or more of the following key-value pairs\par
% \begin{tabularx}\linewidth{>{\ttfamily}l@{\,\texttt{=}\,}lX}
%   annotation & \meta{integer} & enable ‘annotation’ form \meta{integer} \\
%   charactervariant & \meta{integer i}:\meta{integer j} & enable the \emph{i}th character mapping, selecting the \emph{j}th variant \\
%   stylistic & \meta{integer} & enable ‘stylistic’ form \meta{integer} \\
%   sset & \meta{integer} & enable the set of ‘stylistic’ forms \meta{integer} \\
% \end{tabularx}
%
% \DescribeKey{embolden}\val{factor}\par
% Add ‘fake bold’ to make the family heavier.
% Note that this applies to all fonts in the family; it is not intended to add fake bold to a family which lacks one.
%
% \DescribeKey{figures}\mval{key list}\par
% \meta{key list} should be a comma-separated list of one or more of the following valueless keys\par
% \begin{tabularx}\linewidth{>{\ttfamily}lX}
%   lining	                  & use lining digits \\
%   osf\textbar oldstyle      & use oldstyle / hanging digits \\
%   prop\textbar proportional & use proportional digits \\
%   tab\textbar tabular       & use tabular digits \\
%   zero	                    & use the slashed zero \\
% \end{tabularx}
%
% \DescribeKey{forms}\mval{key list}\par
% \meta{key list} should be a comma-separated list of one or more of the following valueless keys\par
% \begin{tabularx}\linewidth{>{\ttfamily}lX}
%   capstopetite            & map \texttt{ABC} to ‘petite’ caps \\
%   capstosc                & map \texttt{ABC} to small-caps \\
%   case                    & enable forms designed for use in capitalised contexts \\
%   nocase                  & disable them \\
%   hist\textbar historical & enable ‘historical’ forms of characters \\
%   random                  & characters vary pseudo-randomly \\
%   smalltopetite           & map \texttt{abc} to ‘petite’ caps \\
%   titling                 & enable forms intended for use in titles \\
%   unicase                 & map \texttt{ABCabc} to letters in a single-cased alphabet \\
% \end{tabularx}
%
% \DescribeKey{language}\val{language id}\par
% \meta{language id} must currently be a valid identifier, as recognised by \pkg{luaotfload}.
% \texttt{otfinfo -l }\meta{path to font file} may be used to determine identifiers supported by the font.
%
% \DescribeKey{ligatures}\mval{key list}\par
% \meta{key list} should be a comma-separated list of one or more of the following valueless keys\par
% \begin{tabularx}\linewidth{>{\ttfamily}lX}
%   contextual	          & enable ‘contextual’ ligatures \\    
%   nocontextual	        & disable them \\                    
%   discretionary	        & enable discretionary ligatures \\                   
%   hist\textbar historic & enable historical ligatures \\                            
%   required	            & enable required ligatures \\                        
%   norequired	          & disable them \\                      
%   standard	            & enable standard (‘common’) ligatures \\                        
%   nostandard	          & disable them \\    
%   tex	                  & enable \TeX{} ligatures e.g.~\texttt{--} \\           
%   notex	                & disable them \\         
% \end{tabularx}
%
% \DescribeKey{mode}\vals{base,node,harf,harfbuzz}\par
% Set the rendering mode.
%
% \DescribeKey{script}\val{script id}\par
% \meta{script id} must currently be a valid identifier, as recognised by \pkg{luaotfload}.
% \texttt{otfinfo -s }\meta{path to font file} may be used to determine identifiers supported by the font.
%
% \DescribeKey{spacing}\mval{key list}\par
% \meta{key list} should be a comma-separated list of one or more of the following valueless keys\par
% \begin{tabularx}\linewidth{>{\ttfamily}lX}
%   capsspacing   & enable spacing designed for capitalised text \\
%   kern          & enable kerning \\
%   nokern        & disable kerning \\
% \end{tabularx}
%
%
% \DescribeKey{fea}\mval{opentype feature spec.}\par
% Optional list of font features \textbf{for text fonts only}. 
% 
% Note that the specification is passed to the font loader with minimal processing, so you must use ‘raw’ feature specifications.
% \emph{If you do not know what these are, use the \texttt{features} key rather than this one; if you need an unsupported feature, file an issue on the bug tracker (link below).}
%
% The default is equivalent to \texttt{fea=\{mode=node;scrpt=dflt;language=dflt;+tlig\}}.
% Unless provided in separate fonts, \texttt{+smcp} is added, if available, for upright, italic and oblique small-caps.
% 
% Features apply to \emph{all} fonts configured as a result of the lookup, so you should not specify features you do not wish applied to all fonts to which the specification applies.
% 
% \subsubsection{Default text family keys}\label{subsubsec:keys-text-def}
% These keys are accepted by \texttt{rm}, \texttt{sf} and \texttt{tt} i.e.~when specifying the default text families for the document.
%
% These keys all do the same thing, so you may use your preferred syntactic sweetener. 
%
% \DescribeKey{math}\vals{true,false}\par
% \DescribeKey{maths}
% Should the current specification also be used for the corresponding text family in maths?
%
% For example, if you are configuring the main document family with \texttt{rm}, should that family also be used for operators, \cs{mathrm} etc.?
%
% The default is equivalent to \texttt{math = true}.
%
% \DescribeKey{nomath}
% \DescribeKey{nomaths}
% Equivalent to \texttt{math = false}.
%
% \subsubsection{Additional text family keys}\label{subsubsec:keys-text-add}
%
% \DescribeKey{command}|=\command|\par
% Use \cs{command} to switch to the font family, rather than creating a command from the family name.
% 
% By default the command to switch to the font family depends on the discovered family name i.e.~on the result of searching the database for the specified family.
% In many cases, this will be the value passed to the \texttt{name} key, but often it will not and sometimes this may not be the command name you want anyway.
% \texttt{command} allows you to override it.
%
% For example, the following would setup \cs{playfair} to switch to Playfair 
% Display, rather than the default choice of \cs{playfairdisplay}.
% \iffalse
%<*verb>
% \fi
\begin{minted}{latex}
  \usepackage{lua-font-config}
  \fontconfig{%
    family = {% setup an additional non-default family
      name = Playfair Display,
      command = \playfair,
    },
  }
\end{minted}
% \iffalse
%</verb>
% \fi
%
% \section{Compatibility}\label{sec:compat}
% 
% \subsection{\cls{ltx-talk}}\label{subsec:compat-talk}
%
% Load with \cs{RequirePackage} \emph{before} loading the class.
% The package emulates the class settings by default, so the main benefit of loading it is speed.
% If you wish to change the fonts, use \cs{fontconfig} after the class is loaded\footnote{%
%   If this turns out to be something people want to do, I can adjust things to avoid configuring fonts twice.
%   For now, this is just a good way for me to test the code and avoid the pain of watching \pkg{fontspec} load New Computer Modern.%
% }
%
% \section{Examples}\label{sec:eeiau}
%
% \Cref{fig:ee-lmr,fig:ee-ncm-math,fig:ee-ncm-complete} demonstrate simple use of the package to configure the main document font, a Unicode maths font (\emph{via} \pkg{lua-unicode-math} and a complete font configuration (roman/serif, sans, typewriter and maths).
% These examples use the default configurations for text and maths fonts, so the configurations are extremely simple.
%
% \Cref{fig:ee-features,fig:ee-fea,fig:ee-add} demonstrate slightly more complex setups.
%
% \Cref{fig:ee-talk} demonstrates how to use \pkg{lua-font-config} to speed up the compilation of presentations created with \cls{ltx-talk}.
%
% \lfcdocfile [label=example-lmr -- \cref{fig:ee-lmr}] {example-lmr}
% \lfcee{lmr}
%
% \lfcdocfile [label=example-ncm-math -- \cref{fig:ee-ncm-math}] {example-ncm-math}
% \lfcee{ncm-math}
%
% \lfcdocfile [label=example-ncm-complete -- \cref{fig:ee-ncm-complete}] 
%   {example-ncm-complete}
% \lfcee{ncm-complete}
%
% Note that \cref{fig:ee-features,fig:ee-fea} give exactly the same output; the only difference is that one uses \texttt{features} and the other \texttt{fea} to configure features for the configured families.
% See \cref{subsubsec:keys-text}.
% 
% \lfcdocfile [label=example-features -- \cref{fig:ee-features}] {example-features}
% \lfcee{features}
%
% \lfcdocfile [label=example-fea -- \cref{fig:ee-fea}] {example-fea}
% \lfcee{fea}
%
% \Cref{fig:ee-add} demonstrates usage of the \texttt{fam} key to configure an additional family and a custom font switch to access it.
%
% \lfcdocfile [label=example-add -- \cref{fig:ee-add}] {example-add}
% \lfcee{add}
%
% \Cref{fig:ee-talk} demonstrates the default configuration for \cls{ltx-talk}.
% This is approximately equivalent to the default setup if \pkg{lua-font-config} is not loaded.
% Note the way the package is loaded \emph{before} \cs{documentclass}.
% If we used \cs{usepackage} after the class was loaded, we would not benefit from the faster compilation our Lua-based approach provides\footnote{%
%   In fact, although \pkg{lua-font-config} \emph{is} faster generally and although this is likely due to greater use of Lua, the size of the difference in this particular case suggests some additional factor is involved.
%   However, I've not tried to confirm this or to identify the cause.%
% }.
% See \cref{subsec:compat-talk}.
%
% \lfcdocfile [label=example-talk -- \cref{fig:ee-talk},
%   rangestartstring={\\DocumentMetadata}]{example-talk}
% \lfcee*[1,2]{talk}
%
% \section{TO DOs}\label{sec:todo}
%
% These are not in any particular order, though there is some tendency for higher priority items to be earlier.
% \begin{enumerate}
%   \item Conceptual
%     \begin{itemize}
%       \item Abandon the whole thing since packages are not supposed to meddle with fonts?
%     \end{itemize}
%   \item \textsc{nfss}
%     \begin{itemize}
%       \item Support multiple font configurations e.g.~for multiple languages with multiple scripts.
%         \begin{itemize}
%           \item Support for \pkg{babel}?
%             This!!!
%           \item[] \pkg{babel} provides e.g. \cs{babelfont}, which uses \cs{fontspec}.
%             Should \pkg{lua-font-config} provide this?
%         \end{itemize}
%      \end{itemize}
%   \item Interface
%     \begin{itemize}
%       \item Provide a proper user interface (more similar to Con\TeX{}t, since we're using the same (\textsc{mkiv}) sorting?
%         The interface is now not too dissimilar to a \LaTeX-ified version of this, I suppose, except there are no goodies or typefaces and our families are a bit richer and more flexible.
%       \item Information for user - a bit better now, hopefully, as we use the standard mechanisms, except for debug messages.
%       \item Accommodate \texttt{.ttc}. 
%       \begin{itemize}
%         \item The basis is done, but not sure what, if any, interface is needed?
%         \item How to test this??
%       \end{itemize}
%     \end{itemize}
%   \item Loader
%     \begin{itemize}
%       \item Test with \texttt{.ttf}. 
%         \begin{itemize}
%           \item What needs testing exactly??
%             Or is this all on the loader?
%         \end{itemize}
%       \item Variable fonts.
%         \begin{itemize}
%           \item How to do or test??
%         \end{itemize}
%       \item Colour. 
%         Do??
%         \begin{itemize}
%           \item What does ‘Do??’ refer to?
%         \end{itemize}
%       \item Cope with (text) symbol fonts?
%         Not sure is that really needed?
%       \item Combo, fallback \& all that.
%     \end{itemize}
%   \item Cache
%     \begin{itemize}
%       \item Cached data should depend on db/fnt versions.
%         \begin{itemize}
%           \item Or is this automatic?
%           \item Or maybe it shouldn't?
%         \end{itemize}
%     \end{itemize}
%   \item Documentation
%     \begin{itemize}
%       \item Not everything implemented in terms of the \textsc{ui} is in the user doc.
%       \item The Lua code has some comments, but these don't always amount to documentation.
%       \item The overall infrastructure isn't really documented, except for a partially accurate \textsc{ascii} database schema included inline.
%       \item Registered Lua functions mapped to \pkg{expl3} names are not documented.
%       \item Use of callbacks, hooks etc.\ is more-or-less undocumented.
%     \end{itemize}
%   \item Code
%     \begin{itemize}
%       \item Should be cleaned up -- I cannot need 2,500 lines to load a font!
%       \item[Unnumbered Gripe] The code is too long, too complex, too clunky and too simplistic.
%          (Yes, of course, it can be both.)
%       \item Some remaining cleanup in the ConTeXt file, though this is much better than it was.
%       \item Improve performance.
%         \begin{itemize}
%           \item There is some duplication and too many pre-definitions for my taste.
%         \end{itemize}
%       \item Possibly modify database creation to avoid correcting the data again??
%     \end{itemize}
%   \item Test suite
%     \begin{itemize}
%       \item There are no unit tests (cf.\ \pkg{nfssext-cfr}, where the tests are much more focused).
%         I don't know how to implement this for (non-public) Lua functions.
%     \end{itemize}
% \end{enumerate}
%
% \changes{v0.1}{2026-10-15}{First public release.}
% \changes{v0.2}{2026-10-29}{Bug fixes, code cleanup, somewhat better UI, doc improvements.}
%
% \MaybeStop{%
%   \usesafecs
%   \PrintChanges
%   \resetcs
%   \PrintIndex
% }
% 
% \section{Implementation}
%
% There is very little here, because almost everything is done in Lua.
%
%<*sty>
%<@@=lfc>
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[2021-11-15]
\RequirePackage{svn-prov}
\ProvidesPackageSVN[\filebase.sty]{$Id: lua-font-config.dtx 12180 2026-11-02 02:55:44Z cfrees $}[v0.2 \revinfo][\filebase: Font configuration for LuaLaTeX]
% This is needed only because l3doc overwrites \fileversion and \filedate.
% Neither ltxdoc nor doc does this.
% But it seems better to do it this way on the basis of the general precautionary principle.
\DefineFileInfoSVN[lfc]
%    \end{macrocode}
% \iffalse
% ^^A Paid â defnyddio \GetFileInfoSVN*/\GetFileInfoSVN{} yn y fan hon!!
% \fi
%    \begin{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% copied verbatim, excepting format from Joseph Wright's' siunitx.sty under LPPL
\@ifundefined{directlua}{%
  \PackageError{lua-font-config}{Package requires LuaLaTeX}
  {To use lua-font-config, you must compile your document with LuaLaTeX.}%
}{}
\@ifundefined{ExplLoaderFileDate}{%
  \RequirePackage{expl3}%
}{}
%% almost verbatim from siunitx.sty
\@ifl@t@r\ExplLoaderFileDate{2022-02-24}{%
}{%
  \PackageError{lua-font-config}{Support package expl3 too old}
  {%
    You need to update your installation of the bundles 'l3kernel' and
    'l3packages'.\MessageBreak
    Loading~lua-font-config~will~abort!%
  }%
  \endinput
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOn
\prop_gput:NnV \g_msg_module_name_prop {lfc} \lfc@base
%    \end{macrocode}
% %^^A Switch cat codes to protect \verb|~|.
% \let\MakePrivateLetters\OrigMakePrivateLetters
% Messages.
% 
% Note that \verb|\msg_*| are not recognised in the indexing; \cs{msg} appears instead.
% This is a limitation of the \pkg{doc} package, as far as I know.
%    \begin{macrocode}
\msg_new:nnnn {lfc} {needs-luatex} {
  \msg_critical_text:n {lfc} :: ~requires~LuaLaTeX~\msg_line_context:
} { \msg_see_documentation_text:n {lfc} }
%    \end{macrocode}
% %^^A Switch temporarily back to catch the next \pkg{expl3} function.
% \let\MakePrivateLetters\MyMakePrivateLetters
%    \begin{macrocode}
\sys_if_engine_luatex:F { \msg_critical:nn {lfc} {needs-luatex} }
%    \end{macrocode}
% %^^A Switch cat codes to protect \verb|~|.
% \let\MakePrivateLetters\OrigMakePrivateLetters
%    \begin{macrocode}
\msg_new:nnnn {lfc} {math-needs-lum} {
  \msg_error_text:n {lfc} :: ~math~config~requires~lua-unicode-math,~but~
  you've~loaded~unicode-math.~This~cannot~work~\msg_line_context:
} { To~configure~Unicode~maths~fonts~with~this~package,~we~need~to~load~
  lua-unicode-math,~but~unicode-math,~which~is~incompatible~has~already~
  been~loaded,~so~I'm~going~to~ignore~this~part~of~your~settings.~
  \msg_see_documentation_text:n {lfc}
}
\msg_new:nnnn {lfc} {loading} {
  \msg_info_text:n {lfc} :: ~loading~#1~for~maths~support~
  \msg_line_context:
} { \msg_see_documentation_text:n {lfc} }
%    \end{macrocode}
% %^^A Switch back now we're done with message setup.
% \let\MakePrivateLetters\MyMakePrivateLetters
% 
% \begin{variable}{\l_@@_features_seq,\l_@@_tmpa_bool,\l_@@_tmpa_tl,\l_@@_tmpb_tl}
%   Custom ephemeral variables.
%   \changes{v0.2}{2026-10-29}{Added \cs{l_@@_features_seq}, \cs{l_@@_tmpb_tl}.}
%    \begin{macrocode}
\bool_new:N \l_@@_tmpa_bool
\seq_new:N \l_@@_features_seq
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
%    \end{macrocode}
% \end{variable}
% \begin{keyname}{rm,sf,tt}
% Top-level keys for default text families.
%    \begin{macrocode}
\clist_map_inline:nn {rm, sf, tt} {
  \keys_define:nn {lfc} {
    #1 .code:n            = { 
      \tl_clear:N \l_@@_tmpa_tl
      \tl_clear:N \l_@@_tmpb_tl
      \keys_set_exclude_groups:nnnN {lfc/#1} {config} {##1} \l_@@_tmpa_tl
      \keys_set_groups:nnVN {lfc/#1} {config}     \l_@@_tmpa_tl \l_@@_tmpb_tl
      \keys_set_groups:nnV  {lfc/#1} {lateconfig} \l_@@_tmpb_tl
      \bool_set_true:N \l_@@_tmpa_bool
    },
    #1 .value_required:n  = true,
    #1 .usage:n           = preamble,
  }
%    \end{macrocode}
% \begin{keyname}{rm/name,rm/fea,rm/force,rm/scale,rm/maths,rm/math,rm/nomaths,rm/nomath}
% \begin{keyname}{sf/name,sf/fea,sf/force,sf/scale,sf/maths,sf/math,sf/nomaths,sf/nomath}
% \begin{keyname}{tt/name,tt/fea,tt/force,tt/scale,tt/maths,tt/math,tt/nomaths,tt/nomath}
% Configure keys for default text families.
%    \begin{macrocode}
  \keys_define:nn {lfc/#1} {
    name      .code:n = { \use:c {_@@_set_#1:n} {##1} },
    fea       .code:n = { \keys_set:nn {lfc/fam} {fea      = {##1}} },
    features  .code:n = { \keys_set:nn {lfc/fam} {features = {##1}} },
    force     .code:n = { \keys_set:nn {lfc/fam} {force    = {##1}} },
    scale     .code:n = { \keys_set:nn {lfc/fam} {scale    = {##1}} },
    maths     .code:n = { \_@@_set_fam_cfg:nn   {maths}{##1} },
    math      .meta:n = { maths = {##1} },
    nomaths   .meta:n = { maths = false },
    nomath    .meta:n = { nomaths },
    unknown   .code:n = {
      \exp_args:NnV \use:c {__@@_set_#1:n} \l_keys_key_str
    },
    name      .value_required:n   = true,
    math      .default:n          = true,
    maths     .default:n          = true,
    nomath    .value_forbidden:n  = true,
    nomaths   .value_forbidden:n  = true,
    unknown   .value_forbidden:n  = true,
    fea       .groups:n           = config,
    features  .groups:n           = lateconfig,
    force     .groups:n           = config,
    maths     .groups:n           = config,
    math      .groups:n           = config,
    nomath    .groups:n           = config,
    nomaths   .groups:n           = config,
    scale     .groups:n           = config,
  }
}
%    \end{macrocode}
% \end{keyname}
% \end{keyname}
% \end{keyname}
% \end{keyname}
% \begin{keyname}{debug,math}
% \begin{keyname}{family}
% Top-level keys for additional families, Unicode maths and debugging.
% \changes{v0.2}{2026-10-29}{Adjusted to support addition of \texttt{features} interface.}
%    \begin{macrocode}
\keys_define:nn {lfc} {
  debug   .code:n           = { 
    \tl_clear:N \l_@@_tmpa_tl
    \keys_set_groups:nnnN
      {lfc/debug} {toggle} {state = true, #1} \l_@@_tmpa_tl
    \keys_set:nV {lfc/debug} \l_@@_tmpa_tl
  },
  debug   .usage:n          = general,
  family  .code:n           = { 
    \tl_clear:N \l_@@_tmpa_tl
    \tl_clear:N \l_@@_tmpb_tl
    \keys_set_exclude_groups:nnnN 
                          {lfc/fam} {config,lateconfig} {#1} \l_@@_tmpa_tl
    \keys_set_groups:nnVN {lfc/fam} {config}      \l_@@_tmpa_tl \l_@@_tmpb_tl
    \keys_set_groups:nnV  {lfc/fam} {lateconfig}  \l_@@_tmpb_tl
    \bool_set_true:N \l_@@_tmpa_bool
  },
  family  .value_required:n = true,
  family  .usage:n          = general,
  math    .code:n           = { 
    \IfPackageLoadedTF {unicode-math} {
      \msg_error:nn {lfc} {math-needs-lum}
    } {
      \msg_info:nnn {lfc} {loading} {lua-unicode-math} 
      \RequirePackage{lua-unicode-math}
      \tl_clear:N \l_@@_tmpa_tl
      \keys_set_exclude_groups:nnnN {lfc/math} {config} {#1} \l_@@_tmpa_tl
      \keys_set:nV {lfc/math} \l_@@_tmpa_tl
      \bool_set_true:N \l_@@_tmpa_bool
    }
  },
  math    .value_required:n = true,
  math    .usage:n          = preamble,
}
%    \end{macrocode}
% \end{keyname}
% \end{keyname}
% \begin{keyname}{fam}
% Configure keys for families.
% \changes{v0.2}{2026-10-29}{Add \texttt{fea} user-interface wrapper: \texttt{features} provides a key-value interface for configuration.}
% \begin{keyname}{fam/name,fam/fea,fam/features,fam/force,fam/scale}
% Configure keys for families.
%    \begin{macrocode}
\keys_define:nn {lfc/fam} {
  name      .code:n = { \__@@_set_fam_name:n {#1} },
  command   .code:n = { 
    \exp_args:Nne \__@@_set_fam_cfg:nn {csname}{ \cs_to_str:N #1 }
  },
  fea       .code:n = { \__@@_set_fam_cfg:nn {fea}{#1} },
  features  .code:n = { 
    \seq_clear:N \l_@@_features_seq
    \keys_set:nn {lfc/features} {#1} 
    \seq_if_empty:NF \l_@@_features_seq {
      \exp_args:Nne \__@@_set_fam_cfg:nn {fea} {
        \seq_use:Nn \l_@@_features_seq {;}
      }
    }
  },
  force     .code:n = { \__@@_set_fam_cfg:nn {force}{#1} },
  scale     .code:n = { \__@@_set_fam_cfg:nn {scale}{#1} },
  unknown   .code:n = {
    \exp_args:NV \__@@_set_fam_name:n \l_keys_key_str 
  },
  name      .value_required:n   = true,
  fea       .value_required:n   = true,
  features  .value_required:n   = true,
  force     .default:n          = true,
  scale     .value_required:n   = true,
  unknown   .value_forbidden:n  = true,
  name      .usage:n            = general,
  command   .usage:n            = general,
  fea       .usage:n            = general,
  features  .usage:n            = general,
  force     .usage:n            = general,
  scale     .usage:n            = general,
  unknown   .usage:n            = general,
  command   .groups:n           = config,
  fea       .groups:n           = config,
  features  .groups:n           = lateconfig,
  force     .groups:n           = config,
  scale     .groups:n           = config,
}
%    \end{macrocode}
% \end{keyname}
% \end{keyname}
% \begin{keyname}{math/name,math/force,math/scale}
% Configure keys for Unicode maths.
%    \begin{macrocode}
\IfPackageLoadedF {unicode-math} {
  \keys_define:nn {lfc/math} {
    name      .code:n = { \use:c {_@@_set_math:n} {#1} },
    force     .code:n = { \keys_set:nn {lfc/fam} {force    = {#1}} },
    scale     .code:n = { \keys_set:nn {lfc/fam} {scale    = {#1}} },
    unknown   .code:n = {
      \exp_args:NnV \use:c {_@@_set_math:n} \l_keys_key_str
    },
    name      .value_required:n   = true,
    force     .default:n          = true,
    scale     .value_required:n   = true,
    unknown   .value_forbidden:n  = true,
    name      .usage:n            = preamble,
    force     .usage:n            = preamble,
    scale     .usage:n            = preamble,
    unknown   .usage:n            = preamble,
    force     .groups:n           = config,
    scale     .groups:n           = config,
  }
}
%    \end{macrocode}
% \end{keyname}
% \begin{keyname}{features}
% \changes{v0.2}{2026-10-29}{Initial \texttt{features} keys: \texttt{alternates}, \texttt{embolden}, \texttt{figures}, \texttt{forms}, \texttt{language}, \texttt{ligatures}, \texttt{node}, \texttt{script}, \texttt{spacing}.}
% \begin{keyname}{features/alternates,
%   features/embolden,
%   features/figures,
%   features/forms,
%   features/language,
%   features/ligatures,
%   features/mode,
%   features/script,
%   features/spacing,
% }
% Trying to be a more user-friendly wrapper around \texttt{fam/fea}.
%    \begin{macrocode}
\keys_define:nn {lfc/features} {
  alternates  .code:n = {
    \_@@_set_fam_features:nn {alternates} {#1}
  },
  embolden    .code:n = {
    %% \_@@_set_fam_features:nn {}{embolden=#1}
    \seq_put_right:Nn \l_@@_features_seq {embolden=#1}
  },
  figures     .code:n = {
    \_@@_set_fam_features:nn {figures} {#1}
  },
  forms         .code:n = {
    \_@@_set_fam_features:nn {forms} {#1}
  },
  language      .code:n = {
    %% \_@@_set_fam_features:nn {}{language=#1}
    \seq_put_right:Nn \l_@@_features_seq {language=#1}
  },
  ligatures     .code:n = {
    \_@@_set_fam_features:nn {ligatures} {#1}
  },
  mode          .choices:nn = {base,node,harf}{
    %% \_@@_set_fam_features:nn {mode}{#1}
    \seq_put_right:Ne \l_@@_features_seq {mode=\l_keys_choice_str}
  },
  script        .code:n = {
    %% \_@@_set_fam_features:nn {}{script=#1}
    \seq_put_right:Nn \l_@@_features_seq {script=#1}
  },
  spacing       .code:n = {
    \_@@_set_fam_features:nn {spacings} {#1}
  },
  alternates  .value_required:n = true,
  embolden    .value_required:n = true,
  figures     .value_required:n = true,
  forms       .value_required:n = true,
  language    .value_required:n = true,
  ligatures   .value_required:n = true,
  mode        .value_required:n = true,
  script      .value_required:n = true,
  spacing     .value_required:n = true,
}
%    \end{macrocode}
%% ^^A ital?
%% ^^A ordn? ornm? sinf? subs? sups?
% \end{keyname}
% \end{keyname}
% \begin{keyname}{debug/state,debug/categories}
% Configure keys for debugging.
%    \begin{macrocode}
\keys_define:nn {lfc/debug} {
  categories  .code:n             = { \_@@_debug_set_cats_scanner:n {#1} },
  state       .choice:,
  state/false .code:n             = { \_@@_debug_set_false: },
  state/true  .code:n             = { \_@@_debug_set_true: },
  categories  .usage:n            = general,
  state       .usage:n            = general,
  categories  .value_required:n   = true,
  state       .default:n          = true,
  state       .groups:n           = toggle,
}
%    \end{macrocode}
% \end{keyname}
% \begin{macro}{\fontconfig}
%   The main (and currently(?) only) public macro.
%   \changes{v0.2}{2026-10-30}{Forbid \cs{par} in input.}
%    \begin{macrocode}
\NewDocumentCommand\fontconfig { m }{
  \bool_set_false:N \l_@@_tmpa_bool
  \keys_set:nn {lfc} {#1}
  \bool_if:NT \l_@@_tmpa_bool {
    \_@@_configure_doc_families:
  }
}
%    \end{macrocode}
% \end{macro}
% \begin{function}{\_@@_set_mathrm:,\_@@_set_mathsf:,\_@@_set_mathtt:}
% TODO: move to hooks if module gets support for switching the families out e.g.~for language changes.
% Currently, the code is too simple-minded for this to arise \dots.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \_@@_set_mathrm: {
  \SetMathAlphabet \mathrm {normal} {TU} \rmdefault {\mdseries@rm} \shapedefault
  \SetMathAlphabet \mathit {normal} {TU} \rmdefault {\mdseries@rm} \itdefault
  \SetMathAlphabet \mathbf {normal} {TU} \rmdefault {\bfseries@rm} \shapedefault
  \SetMathAlphabet \mathrm {bold}   {TU} \rmdefault {\bfseries@rm} \shapedefault
  \SetMathAlphabet \mathit {bold}   {TU} \rmdefault {\bfseries@rm} \itdefault
  \SetMathAlphabet \mathbf {bold}   {TU} \rmdefault {\bfseries@rm} \shapedefault
  \SetSymbolFont{operators}{normal} {TU} \rmdefault {\mdseries@rm} \shapedefault
  \SetSymbolFont{operators}{bold}   {TU} \rmdefault {\bfseries@rm} \shapedefault
}
\cs_new_protected_nopar:Npn \_@@_set_mathsf: {
  \SetMathAlphabet \mathsf {normal} {TU} \sfdefault {\mdseries@sf} \shapedefault
  \SetMathAlphabet \mathsf {bold}   {TU} \sfdefault {\bfseries@sf} \shapedefault
}
\cs_new_protected_nopar:Npn \_@@_set_mathtt: {
  \SetMathAlphabet \mathtt {normal} {TU} \ttdefault {\mdseries@tt} \shapedefault
  \SetMathAlphabet \mathtt {bold}   {TU} \ttdefault {\bfseries@tt} \shapedefault
}
%    \end{macrocode}
% \end{function}
% \begin{function}{\_@@_declare_lum_symbol_fonts:nn}
% Maths setup function.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \_@@_declare_lum_symbol_fonts:nn #1#2 {
  \DeclareSymbolFont{lummain}{TU}{#1}{m}{n}
  \SetSymbolFont{lummain}{bold}{TU}{#2}{b}{n}
}
%    \end{macrocode}
% \end{function}
% Compatibility code for \pkg{ltx-talk}.
%
% This should be equivalent to the default setup, modulo any differences between emulating the package and using \cs{setmathfont} for \pkg{lua-unicode-math}.
%    \begin{macrocode}
\hook_gput_code:nnn {class/ltx-talk/before} {.} {
  \hook_gput_code:nnn {package/mathtools/after} {.} {
    \RequirePackage{lua-unicode-math}
    \fontconfig{
      rm      = {newcomputermodernsans},
      sf      = {newcomputermodernsans},
      math    = {newcomputermodernsansmath},
    }
    \tagpdfsetup { math / mathml / luamml / load = true }
  }
}
%    \end{macrocode}
% \begin{function}{%
%   \_@@_set_fam_cfg:nn,
%   \_@@_set_fam_features:nn,
%   \_@@_set_fam_name:n,
%   \_@@_set_mathrm:,
%   \_@@_set_mathsf:,
%   \_@@_set_mathtt:,
%   \_@@_configure_doc_families:,
%   \_@@_debug_set_cats_scanner:n,
%   \_@@_debug_set_false:,
%   \_@@_debug_set_true:%
% }
% The Lua modules do the actual work.
%    \begin{macrocode}
\lua_load_module:n {lua-font-config}
\ExplSyntaxOff
%    \end{macrocode}
% \end{function}
%</sty>
%
% \iffalse
%
%<*ee-lmr>
\documentclass{article}
\usepackage{lua-font-config}
\fontconfig{rm = latinmodernroman}
\begin{document}
This is Latin Modern Roman.
It features \textit{italics} and \textsl{oblique}.
\textsc{Small-caps are implemented as distinct fonts, as are \textsl{oblique small-caps}.}
{\fontshape{ui}\selectfont Upright italics are less commonly used.}

\normalfont\bfseries
This is the bold expanded weight.
It features \textit{italics} and \textsl{oblique}.

\normalfont\fontseries{db}\selectfont
The ‘demi-bold’ is of regular width, with \textsl{oblique}.

\normalfont
\Huge
Where optical sizes are available, these provide higher quality output than simple scaling.

\LARGE
Where optical sizes are available, these provide higher quality output than simple scaling.

\Large
Where optical sizes are available, these provide higher quality output than simple scaling.

\large
Where optical sizes are available, these provide higher quality output than simple scaling.

\normalsize
Where optical sizes are available, these provide higher quality output than simple scaling.

\small
Where optical sizes are available, these provide higher quality output than simple scaling.

\footnotesize
Where optical sizes are available, these provide higher quality output than simple scaling.

\scriptsize
Where optical sizes are available, these provide higher quality output than simple scaling.

\tiny
Where optical sizes are available, these provide higher quality output than simple scaling.

\normalsize
\footnotesize
This is footnote-sized Latin Modern Roman.
It features \textit{italics} and \textsl{oblique}.
\textsc{Small-caps are implemented as distinct fonts, as are \textsl{oblique small-caps}.}
{\fontshape{ui}\selectfont Upright italics is less commonly used.}

\normalfont\bfseries
This is the bold expanded weight.
It features \textit{italics} and \textsl{oblique}.

\normalfont\fontseries{db}\selectfont
The ‘demi-bold’ is of regular width, with upright and \textsl{oblique} shapes.

\normalfont
The output should look very much as if ‘lua-font-config’ had not been loaded!
\end{document}
%</ee-lmr>
%
%<*ee-fea>
%% $Id: lua-font-config.dtx 12180 2026-11-02 02:55:44Z cfrees $
\documentclass{article}
\parindent=0pt
\usepackage{lua-font-config}
\fontconfig{%
  rm = {% serif uses oldstyle, proportional figures
    name = TeX Gyre Pagella,
    fea = {+ONUM;+PNUM},
  },
  sf = {% sans uses proportional lining figures
    name = texgyreheros,
    fea = {+pnum;+lnum},
  },
  tt = {% typewriter uses tabular lining figures and no ligatures
    name = texgyrecursor,
    fea = {-TLIG;+tnum;+lnum;-liga},
  },
}
\begin{document}
{%
  \TeX-Gyre Pagella: 0123456789
}

{%
  \sffamily
  \TeX-Gyre Heros: 0123456789
}

{%
  \ttfamily
  \TeX-Gyre Cursor 0123456789
  -- --- outfitted officials affluently affiliate fish finials flagranty, first
  finalising infinite floral affinities of fish-filled fingers
}

% No maths font is configured, so Computer Modern is used.
% But the ‘text’ fonts in maths matches the text by default.
\[
    \sin\quad
    \mathrm{rm}\quad
    \mathsf{sf}\quad
    \mathtt{tt}\quad
    \mathit{it}\quad
    \mathbf{bf}
\]
\mathversion{bold}
\[
    \sin\quad
    \mathrm{rm}\quad
    \mathsf{sf}\quad
    \mathtt{tt}\quad
    \mathit{it}\quad
    \mathbf{bf}
\]
\end{document}
%</ee-fea>
%
%<*ee-features>
%% $Id: lua-font-config.dtx 12180 2026-11-02 02:55:44Z cfrees $
\documentclass{article}
\parindent=0pt
\usepackage{lua-font-config}
\fontconfig{%
  rm = {% serif uses oldstyle, proportional figures
    name = TeX Gyre Pagella,
    features = {%
      figures = {oldstyle, proportional},
    },
  },
  sf = {% sans uses proportional lining figures
    name = texgyreheros,
    features = {%
      figures = {lining, proportional},
    },
  },
  tt = {% typewriter uses tabular lining figures and no ligatures
    name = texgyrecursor,
    features = {%
      figures = {lining, tabular},
      ligatures = {notex, nostandard},
    },
  },
}
\begin{document}
{%
  \TeX-Gyre Pagella: 0123456789
}

{%
  \sffamily
  \TeX-Gyre Heros: 0123456789
}

{%
  \ttfamily
  \TeX-Gyre Cursor 0123456789
  -- --- outfitted officials affluently affiliate fish finials flagranty, first
  finalising infinite floral affinities of fish-filled fingers
}

% No maths font is configured, so Computer Modern is used.
% But the ‘text’ fonts in maths matches the text by default.
\[
    \sin\quad
    \mathrm{rm}\quad
    \mathsf{sf}\quad
    \mathtt{tt}\quad
    \mathit{it}\quad
    \mathbf{bf}
\]
\mathversion{bold}
\[
    \sin\quad
    \mathrm{rm}\quad
    \mathsf{sf}\quad
    \mathtt{tt}\quad
    \mathit{it}\quad
    \mathbf{bf}
\]
\end{document}
%</ee-features>
% 
%<*ee-ncm-complete>
\documentclass{article}
\usepackage{lua-font-config}
\fontconfig{%
  rm    = New Computer Modern,
  sf    = New Computer Modern Sans,
  tt    = New Computer Modern Mono,
  math  = New Computer Modern Math,
}
\begin{document}
New Computer \textsl{Modern} \textit{with} \textsc{\textit{default} settings}.

\sffamily
New Computer \textsl{Modern} \textit{with} \textsc{\textit{default} settings}.

\ttfamily
New Computer \textsl{Modern} \textit{with} \textsc{\textit{default} settings}.

\normalfont
New Computer Modern Math with text fonts as above:
\[
    \sin^2\theta + \cos^2\theta = 1
\]
\[
    \mathscr{ABC abc} \mathcal{ABC abc}
\]
\mathversion{bold}
\[
    \sin^2\theta + \cos^2\theta = 1
\]
\[
    \mathscr{ABC abc} \mathcal{ABC abc}
\]
\end{document}
%</ee-ncm-complete>
%
%<*ee-ncm-math>
\documentclass{article}
\usepackage{lua-font-config}
\fontconfig{%
  rm = newcomputermodern,
  sf = newcomputermodernsans,
  tt = newcomputermodernmono,
  math = newcomputermodernmath,
}
\parindent=0pt
\begin{document}
\[
    \sin^2\theta + \cos^2\theta = 1
\]
$\mathsf{x} \mathtt{x} \mathbf{x}$

\mathversion{bold}
\[
    \sin^2\theta + \cos^2\theta = 1
\]
$\mathsf{x} \mathtt{x} \mathbf{x}$
\end{document}
%</ee-ncm-math>
%
%<*ee-talk>
\DocumentMetadata{tagging=on,pdfstandard=ua-2,pdfversion=2.0,lang=en-GB}
\RequirePackage{lua-font-config}% MUST precede class.
\documentclass{ltx-talk}

\title{Some Title}
\author{A. U. Thor}
\institute{Pantheon, Greece}
\date{Ancient}
\begin{document}
\begin{frame}
  \maketitle
\end{frame}
\begin{frame}
  \frametitle{Frame}
  Some text\footnote{With a footnote.} on a slide.

  \textsc{Small-Caps \textsl{italics \textbf{bold}} \textbf{bold}.}

  Regular, \fontseries{k}\selectfont Book and \bfseries Bold.
  \normalfont
  \begin{equation}
    v = ut + \frac{1}{2}at^2
  \end{equation}
  \begin{equation}
    \sin^2\theta + \cos^2\theta = 1
  \end{equation}
  Script $\mathscr{ABC abc}$ and calligraphic $\mathcal{ABC abc}$.

  Bold maths:
  \mathversion{bold}
  \begin{equation}
    v = ut + \frac{1}{2}at^2
  \end{equation}
  \begin{equation}
    \sin^2\theta + \cos^2\theta = 1
  \end{equation}
  Script $\mathscr{ABC abc}$ and calligraphic $\mathcal{ABC abc}$.
\end{frame}
\end{document}
%</ee-talk>
% 
%<*ee-add>
\documentclass{article}
\usepackage{lua-font-config}
\fontconfig{%
  family  = {
    name    = Lobster Two,
    scale   = 2,
    command = \lobster,
  },
}
\begin{document}
This is some ordinary text in the default \LaTeXe{} font.

{\lobster This is Lobster Two.
  \textit{Italics but no \textsc{small-caps}} \textsc{even in upright}.
  We do have \textbf{bold and \textit{bold italics}}, but there is no, 
  \textsl{oblique, so here we get italics, too.}\par
}

Back to the default.
\end{document}
%</ee-add>
%
% \fi
% 
%\Finale
