summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--luaotfload.dtx414
-rw-r--r--luaotfload.lua416
-rwxr-xr-xmkluatexfontdb.lua184
-rw-r--r--otfl-font-nms.lua75
4 files changed, 903 insertions, 186 deletions
diff --git a/luaotfload.dtx b/luaotfload.dtx
index 595a9fa..3685083 100644
--- a/luaotfload.dtx
+++ b/luaotfload.dtx
@@ -130,13 +130,14 @@ and the derived files
\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
%setmathfont{XITS Math}
-\newcommand\TEX {\TeX\xspace}
-\newcommand\LUA {Lua\xspace}
-\newcommand\PDFTEX {pdf\TeX\xspace}
-\newcommand\LUATEX {Lua\TeX\xspace}
-\newcommand\XETEX {\XeTeX\xspace}
-\newcommand\LATEX {\LaTeX\xspace}
-\newcommand\CONTEXT{Con\TeX t\xspace}
+\newcommand\TEX {\TeX\xspace}
+\newcommand\LUA {Lua\xspace}
+\newcommand\PDFTEX {pdf\TeX\xspace}
+\newcommand\LUATEX {Lua\TeX\xspace}
+\newcommand\XETEX {\XeTeX\xspace}
+\newcommand\LATEX {\LaTeX\xspace}
+\newcommand\CONTEXT {Con\TeX t\xspace}
+\newcommand\OpenType{\identifier{Open\kern-.25ex Type}\xspace}
\def\definehighlight[#1][#2]%
{\ifcsname #1\endcsname\else
@@ -192,24 +193,26 @@ and the derived files
% \maketitle
%
% \begin{abstract}
-% This package is an adaptation of the \CONTEXT font loading system, providing
-% the ability to load \identifier{OpenType} fonts with extended font loading syntax
-% supporting a large selection of \identifier{OpenType} font features.
+% This package is an adaptation of the \CONTEXT font loading system.
+% It allows for loading \OpenType fonts with an extended syntax and adds
+% support for a variety of font features.
% \end{abstract}
%
% \tableofcontents
%
+% \part{Package Description}
+%
% \section{Introduction}
%
% Font management and installation has always been painful with \TEX. A lot of
% files are needed for one font (\abbrev{tfm}, \abbrev{pfb}, \abbrev{map},
-% \abbrev{fd}, \abbrev{vf}), and as \TEX is 8-bit each font is limited to 256
-% characters.
+% \abbrev{fd}, \abbrev{vf}), and due to the 8-Bit encoding each font is limited
+% to 256 characters.
% But the font world has evolved since the original
% \TEX, and new typographic systems have appeared, most notably the so
-% called \emphasis{smart font} technologies like \identifier{OpenType}
-% (\abbrev{otf}) fonts.
-% These fonts can contain a lot of characters and additional
+% called \emphasis{smart font} technologies like \OpenType
+% fonts (\abbrev{otf}).
+% These fonts can contain many more characters than \TEX fonts, as well as additional
% functionality like ligatures, old-style numbers, small capitals,
% etc., and support more complex writing systems like Arabic and
% Indic\footnote{%
@@ -219,7 +222,7 @@ and the derived files
% appreciated.
% }
% scripts.
-% \identifier{OpenType} fonts are widely deployed and available for all
+% \OpenType fonts are widely deployed and available for all
% modern operating systems.
% As of 2013 they have become the de facto standard for advanced text
% layout.
@@ -227,12 +230,17 @@ and the derived files
% world was with the \XETEX engine.
%
% Unlike \XETEX, \LUATEX has no built-in support for
-% \identifier{OpenType} or other technologies.
-% Instead, it provides hooks for executing Lua during the \TEX run
+% \OpenType or technologies other than the original \TEX fonts.
+% Instead, it provides hooks for executing \LUA code during the \TEX run
% that allow implementing extensions for loading fonts and manipulating
% how input text is processed without modifying the underlying engine.
+% This is where \identifier{luaotfload} comes into play:
+% Based on code from \CONTEXT, it extends \LUATEX with functionality necessary
+% for handling \OpenType fonts.
+% Additionally, it provides means for accessing fonts known to the operating
+% system conveniently by indexing the metadata.
%
-% \section{Loading fonts}
+% \section{Loading Fonts}
%
% \identifier{luaotfload} supports an extended font loading syntax:
%
@@ -252,7 +260,7 @@ and the derived files
% \paragraph{Prefix}
%
% The \meta{prefix} is either |file:| or |name:|.
-% It determines whether font loader should interpret the request as a
+% It determines whether the font loader should interpret the request as a
% file name or font name, respectively, which again influences how it
% will attempt to locate the font.
% The prefix can be omitted, in which case |name:| is assumed.
@@ -266,30 +274,89 @@ and the derived files
%% For compatibility with \XETEX, surrounding the \meta{font name} with
%% square brackets is synonymous to using the |file:| prefix.
%
-% Accessing fonts by fontname allows loading system installed fonts as
-% well as \fileent{texmf} ones, and requires a font names database; see
-% Section~\ref{sec:fontdb} for more information.
+% In order for fonts installed both in system locations and in your
+% \fileent{texmf} to be accessible by font name, \identifier{luaotfload} must
+% first collect the metadata included in the files.
+% Please refer to section ~\ref{sec:fontdb} below for instructions on how to
+% create the database.
%
% \paragraph{Font name}
%
% The \meta{font name} can be either a font filename or actual font
% name based on the \meta{prefix} as mentioned above.
%
-% Fonts loaded by filename may either include their absolute path in
-% the filesystem or consist of just the filename without a path. If no
-% path is specified, then \identifier{kpathsea} is used to locate the
+% A filename request may optionally include the absolute path to the font file,
+% allowing for fonts outside the standard locations to be loaded as well.
+% If no path is specified, then \identifier{kpathsea} is used to locate the
% font (which will typically be in the \fileent{texmf} tree or the
% current directory).
%
-% For example,
+% \subparagraph{Examples for loading by file name}
+%
+% For example, conventional \abbrev{type1} font can be loaded with a \verb|file:|
+% request like so:
+%
% \begin{quote}
-% \begin{verbatim}
-% \font\1={file:ec-lmr10} at 10pt
-% \font\2={/Users/Shared/Fonts/aldus.otf} at 11pt
-% \font\3={name:TeX Gyre Pagella} at 9pt
-% \end{verbatim}
+% \begin{verbatim}
+% \font\lmromanten={file:ec-lmr10} at 10pt
+% \end{verbatim}
% \end{quote}
%
+% The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa
+% Półtawskiego} (in \TEX Live) in its condensed variant can be loaded as
+% follows:
+%
+% \begin{quote}
+% \begin{verbatim}
+% \font\apcregular=file:antpoltltcond-regular.otf at 42pt
+% \end{verbatim}
+% \end{quote}
+%
+% The next example shows how to load the \emphasis{Porson} font digitized by
+% the Greek Font Society using \XETEX-style syntax and an absolute path from a
+% non-standard directory:
+%
+% \begin{quote}
+% \begin{verbatim}
+% \font\gfsporson="[/tmp/GFSPorson.otf]" at 12pt
+% \end{verbatim}
+% \end{quote}
+%
+% \subparagraph{Examples for loading by font name}
+%
+% The \verb|name:| lookup does not depend on cryptic filenames:
+%
+% \begin{quote}
+% \begin{verbatim}
+% \font\pagellaregular={name:TeX Gyre Pagella} at 9pt
+% \end{verbatim}
+% \end{quote}
+%
+% A bit more specific but essentially the same lookup would be:
+%
+% \begin{quote}
+% \begin{verbatim}
+% \font\pagellaregular={name:TeX Gyre Pagella Regular} at 9pt
+% \end{verbatim}
+% \end{quote}
+%
+% Which fits nicely with the whole set:
+%
+% \begin{quote}
+% \begin{verbatim}
+% \font\pagellaregular ={name:TeX Gyre Pagella Regular} at 9pt
+% \font\pagellaitalic ={name:TeX Gyre Pagella Italic} at 9pt
+% \font\pagellabold ={name:TeX Gyre Pagella Bold} at 9pt
+% \font\pagellabolditalic={name:TeX Gyre Pagella Bolditalic} at 9pt
+%
+% {\pagellaregular foo bar baz\endgraf}
+% {\pagellaitalic foo bar baz\endgraf}
+% {\pagellabold foo bar baz\endgraf}
+% {\pagellabolditalic foo bar baz\endgraf}
+%
+% ...
+% \end{verbatim}
+% \end{quote}
%
% \paragraph{Font features}
%
@@ -298,10 +365,14 @@ and the derived files
% Cf. \url{http://www.microsoft.com/typography/otspec/featurelist.htm}.
% }
% and font options.
-% Prepending a font feature with a |+|-sign enables it, while
-% a |-| disables it. For instance, the request
+% Prepending a font feature with a |+| (plus sign) enables it, whereas
+% a |-| (minus) disables it. For instance, the request
%
-% |\font\test=Latin Modern Roman:+clig;-kern|
+% \begin{quote}
+% \begin{verbatim}
+% \font\test=LatinModernRoman:+clig;-kern
+% \end{verbatim}
+% \end{quote}
%
% \noindent activates contextual ligatures (|clig|) and disables
% kerning (|kern|).
@@ -309,35 +380,45 @@ and the derived files
% the feature in a key/value expression.
% The following request has the same meaning as the last one:
%
-% |\font\test=Latin Modern Roman:clig=true;kern=false|
+% \begin{quote}
+% \begin{verbatim}
+% \font\test=LatinModernRoman:clig=true;kern=false
+% \end{verbatim}
+% \end{quote}
%
% \noindent
-% Furthermore, this second syntax is required if a font feature
-% accepts options besides its activation state.
-% For example, \emphasis{stylistic alternates} (|salt|) provide a set
-% of variants to given glyphs.
-% These can be selected either explicitly by supplying the variant
-% index (starting from 1), or randomly by setting the value to,
-% obviously, |random|:
-%
-% |\font\test=Latin Modern Roman:salt=1|
+% Furthermore, this second syntax is required should a font feature
+% accept other options besides a true/false switch.
+% For example, \emphasis{stylistic alternates} (|salt|) are variants of given
+% glyphs.
+% They can be selected either explicitly by supplying the variant
+% index (starting from one), or randomly by setting the value to,
+% obviously, |random|.
+%
+% \iffalse TODO verify that this actually works with a font that supports
+% the salt/random feature!\fi
+% \begin{quote}
+% \begin{verbatim}
+% \font\librmsaltfirst=LatinModernRoman:salt=1
+% \end{verbatim}
+% \end{quote}
%
% \noindent Other font options include:
%
% \begin{description}
%
% \item [mode] \hfill \\
-% \identifier{luaotfload} has two \identifier{OpenType} processing
+% \identifier{luaotfload} has two \OpenType processing
% \emphasis{modes}:
% \identifier{base} and \identifier{node}.
%
-% \identifier{base} mode works by mapping \identifier{OpenType}
-% features to traditional \TEX ligature and kerning mechanisms,
-% thus supporting only non-contextual substitutions and kerning
-% pairs, but is the slightly faster variant.
-% \identifier{node} mode works by processing \TEX’s internal
+% \identifier{base} mode works by mapping \OpenType
+% features to traditional \TEX ligature and kerning mechanisms.
+% Supporting only non-contextual substitutions and kerning
+% pairs, it is the slightly faster, albeit somewhat limited, variant.
+% \identifier{node} mode works by processing \TeX’s internal
% node list directly at the \LUA end and supports
-% a wider range of \identifier{OpenType} features.
+% a wider range of \OpenType features.
% The downside is that the intricate operations required for
% \identifier{node} mode may slow down typesetting especially
% with complex fonts and it does not work in math mode.
@@ -346,19 +427,20 @@ and the derived files
% mode, and \identifier{base} mode has to be requested where needed,
% e.~g. for math fonts.
%
-% \item [script] \ref{script-tag} \hfill \\
-% An \identifier{OpenType} script tag;\footnote{%
+% \item [script] \label{script-tag} \hfill \\
+% An \OpenType script tag;\footnote{%
% See \url{http://www.microsoft.com/typography/otspec/scripttags.htm}
% for a list of valid values.
% For scripts derived from the Latin alphabet the value
% |latn| is good choice.
% }
% the default value is |dlft|.
-% Some fonts do not assign features to the |dflt| script, in
+% Some fonts, including very popular ones by foundries like Adobe,
+% do not assign features to the |dflt| script, in
% which case the script needs to be set explicitly.
%
% \item [language] \hfill \\
-% An \identifier{OpenType} language system identifier,\footnote{%
+% An \OpenType language system identifier,\footnote{%
% Cf. \url{http://www.microsoft.com/typography/otspec/languagetags.htm}.
% }
% defaulting to |dflt|.
@@ -367,13 +449,13 @@ and the derived files
% A comma-separated list of feature files to be applied to the
% font.
% Feature files contain a textual representation of
-% \identifier{OpenType} tables and extend the features of a font
+% \OpenType tables and extend the features of a font
% on fly.
% After they are applied to a font, features defined in a
% feature file can be enabled or disabled just like any
% other font feature.
% The syntax is documented in \identifier{Adobe}’s
-% \identifier{OpenType} Feature File Specification.\footnote{%
+% \OpenType Feature File Specification.\footnote{%
% Cf. \url{http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html}.
% }
%
@@ -391,13 +473,17 @@ and the derived files
%
% For example, in order to set text in semitransparent red:
%
-% |\font\test=Latin Modern Roman:color=FF0000BB|
+% \begin{quote}
+% \begin{verbatim}
+% \font\test={Latin Modern Roman}:color=FF0000BB
+% \end{verbatim}
+% \end{quote}
%
% \item [protrusion \& expansion] \hfill \\
-% These keys both control microtypographic features of the font,
+% These keys control microtypographic features of the font,
% namely \emphasis{character protrusion} and \emphasis{font
% expansion}.
-% They accept names of predefined \LUA tables that contain
+% Their arguments are names of \LUA tables that contain
% values for the respective features.\footnote{%
% For examples of the table layout please refer to the
% section of the file \fileent{otfl-fonts-ext.lua} where the
@@ -423,12 +509,16 @@ and the derived files
% for details.
% }:
%
-% |\font\test=Latin Modern Roman:protrusion=default|
+% \begin{quote}
+% \begin{verbatim}
+% \font\test=LatinModernRoman:protrusion=default
+% \end{verbatim}
+% \end{quote}
% \end{description}
%
% \paragraph{Non-standard font features}
-% \identifier{luaotfload} add a number of features that are not defined
-% in the original \identifier{OpenType} specification, most of them
+% \identifier{luaotfload} adds a number of features that are not defined
+% in the original \OpenType specification, most of them
% aiming at emulating the behavior familiar from other \TEX engines.
% Currently (2013) there are three of them:
%
@@ -441,7 +531,15 @@ and the derived files
%
% \item [tlig]
% Applies legacy \TEX ligatures:
-% |``|, |''|, |`|, |'|, |"|, |--|, |---|, |!`| and |?`|.%
+%
+% \begin{tabular}{rlrl}
+% `` & \verb|``| & '' & \verb|''| \\
+% ` & \verb|`| & ' & \verb|'| \\
+% " & \verb|"| & -- & \verb|--| \\
+% --- & \verb|---| & !` & \verb|!`| \\
+% ?` & \verb|?`| & & \\
+% \end{tabular}
+%
% \footnote{%
% These contain the feature set \verb|trep| of earlier
% versions of \identifier{luaotfload}.
@@ -463,16 +561,16 @@ and the derived files
%
% As mentioned above, \identifier{luaotfload} keeps track of which
% fonts are available to \LUATEX by means of a \emphasis{database}.
-% This allows loading not only by explicit filenames but also by the
-% proper names contained in the metadata which is often more accessible
-% to humans.\footnote{%
+% This allows referring to fonts not only by explicit filenames but
+% also by the proper names contained in the metadata which is often
+% more accessible to humans.\footnote{%
% The tool \href{http://www.lcdf.org/type/}{\fileent{otfinfo}} (comes
-% with \TEX Live), when invoked on a font file with the \verb|-o|
+% with \TEX Live), when invoked on a font file with the \verb|-i|
% option, lists the variety of name fields defined for it.
% }
%
-% When \identifier{luaotfload} is asked to load a font by font name, it
-% will check if the database exists and load it or else generate a
+% When \identifier{luaotfload} is asked to load a font by a font name,
+% it will check if the database exists and load it, or else generate a
% fresh one.
% Should it then fail to locate the font, an update to the database is
% performed in case the font has been added to the system only
@@ -482,16 +580,22 @@ and the derived files
% behave as unobtrusively as possible, while providing a convenient
% interface to the fonts installed on the system.
%
-% \subsection[mkluatexfontdb.lua]%
-% {\fileent{mkluatexfontdb.lua}\footnote{%
+% Generating the database for the first time may take a while since it
+% inspects every font file on your computer.
+% This is particularly noticeable if it occurs during a typesetting run.
+% In any case, subsequent updates to the database will be quite fast.
+%
+% \subsection[fontdbutil / mkluatexfontdb.lua]%
+% {\fileent{fontdbutil} /
+% \fileent{mkluatexfontdb.lua}\footnote{%
% The script may be named just \fileent{mkluatexfontdb} in your
% distribution.
% }}
%
-% However, it can be desirable at times to do some of these steps
-% manually.
+% It can still be desirable at times to do some of these steps
+% manually, and without having to compile a document.
% To this end, \identifier{luaotfload} comes with the utility
-% \fileent{mkluatexfontdb} that offers an interface to the database
+% \fileent{fontdbutil} that offers an interface to the database
% functionality.
% Being a \LUA script, there are two ways to run it:
% either make it executable (\verb|chmod +x| on unixoid systems) or
@@ -499,27 +603,39 @@ and the derived files
% Tests by the maintainer show only marginal performance gain by
% running with Luigi Scarso’s
% \href{https://foundry.supelec.fr/projects/luajittex/}%
-% {\LUA jit\TEX},
+% {\identifier{Luajit\kern-.25ex\TEX}},
% which is probably due to the fact that most of the time is spent
% on file system operations.
%
% \emphasis{Note}:
% On \abbrev{MS} \identifier{Windows} systems, the script can be run
% either by calling the wrapper application
-% \fileent{mkluatexfontdb.exe} or as
-% \verb|texlua.exe mkluatexfontdb.lua|.
+% \fileent{fontdbutil.exe} or as
+% \verb|texlua.exe fontdbutil|.
% }
-% Invoke it from the command line with the \verb|--force| switch to
-% initiate a complete rebuild of the database.
+% Invoked with the argument \verb|--update| it will perform a database
+% update, scanning for fonts not indexed.
%
-% \begin{verbatim}
-% mkluatexfontdb --force
-% \end{verbatim}
+% \begin{quote}
+% \begin{verbatim}
+% fontdbutil --update
+% \end{verbatim}
+% \end{quote}
%
-% Generating the database for the first time may take a while since it
-% inspects every font file on your computer.
-% This is particularly noticeable if it occurs during a typesetting run.
-% In any case, subsequent updates to the database will be quite fast.
+% Adding the \verb|--force| switch will initiate a complete
+% rebuild of the database.
+%
+% \begin{quote}
+% \begin{verbatim}
+% fontdbutil --update --force
+% \end{verbatim}
+% \end{quote}
+%
+% For sake of backwards compatibility, \fileent{fontdbutil} may be
+% renamed or symlinked to \fileent{mkluatexfontdb}.
+% Whenever it is run under this name, it will update the database
+% first, mimicking the behavior of earlier versions of
+% \identifier{luaotfload}.
%
% \subsection{Search Paths}
%
@@ -548,9 +664,9 @@ and the derived files
% Windows & \verb|%WINDIR%\Fonts|
% \\
% Linux & \fileent{/usr/local/etc/fonts/fonts.conf} and\hfill\break
-% \fileent{/etc/fonts/fonts.conf"}
+% \fileent{/etc/fonts/fonts.conf}
% \\
-% Mac & \fileent{~/Library/Fonts},\break
+% Mac & \fileent{\textasciitilde/Library/Fonts},\break
% \fileent{/Library/Fonts},\break
% \fileent{/System/Library/Fonts}, and\hfill\break
% \fileent{/Network/Library/Fonts}
@@ -561,49 +677,70 @@ and the derived files
% \hrule
% \end{table}
%
-% \subsection{Querying from outside}
+% \subsection{Querying from Outside}
%
-% \fileent{mkluatexfontdb.lua} also provides rudimentary means of
-% accessing the font database.
-% If the option \verb|--find=name| is given, the script will try and search
-% the fonts indexed by \identifier{luaotfload} for a matching name.
+% \fileent{fontdbutil} also provides rudimentary means of
+% accessing the information collected in the font database.
+% If the option \verb|--find=|\emphasis{name} is given, the script will
+% try and search the fonts indexed by \identifier{luaotfload} for a
+% matching name.
% For instance, the invocation
%
-% \begin{verbatim}
-% mkluatexfontdb.lua --find="Iwona Regular"
-% \end{verbatim}
+% \begin{quote}
+% \begin{verbatim}
+% fontdbutil --find="Iwona Regular"
+% \end{verbatim}
+% \end{quote}
%
+% \noindent
% will verify if “Iwona Regular” is found in the database and can be
% readily requested in a document.
%
-% If you are unsure about the actual font name, then you can add the
-% \verb|-F| switch to the command line to enable approximate matching.
+% If you are unsure about the actual font name, then add the
+% \verb|-F| (or \verb|--fuzzy|) switch to the command line to enable
+% approximate matching.
% Suppose you cannot precisely remember if the variant of
% \identifier{Iwona} you are looking for was “Bright” or “Light”.
% The query
%
-% \begin{verbatim}
-% mkluatexfontdb.lua -F --find="Iwona Bright"
-% \end{verbatim}
+% \begin{quote}
+% \begin{verbatim}
+% fontdbutil -F --find="Iwona Bright"
+% \end{verbatim}
+% \end{quote}
%
+% \noindent
% will tell you that indeed the latter name is correct.
%
-% \verb|mkluatexfontdb.lua --help| will list the available command line
-% switches, including some that will not be discussed in detail here.
+% Basic information about fonts in the database can be displayed
+% using the \verb|-i| option (\verb|--info|).
+% \begin{quote}
+% \begin{verbatim}
+% fontdbutil -F --find="Iwona Light Italic"
+% \end{verbatim}
+% \end{quote}
+% \noindent
+% The meaning of the printed values is described in section 4.4 of the
+% \LUATEX reference manual.\footnote{%
+% In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}.
+% }
+%
+% \verb|fontdbutil --help| will list the available command line
+% switches, including some not discussed in detail here.
%
-% \subsection{Blacklisting fonts}
+% \subsection{Blacklisting Fonts}
% \label{font-blacklist}
%
% Some fonts are problematic in general, or just in \LUATEX.
% If you find that compiling your document takes far too long or eats
% away all your system’s memory, you can track down the culprit by
-% running \verb|mkluatexfontdb -v| to increase verbosity.
+% running \verb|fontdbutil -v| to increase verbosity.
% Take a note of the \emphasis{filename} of the font that database
% creation fails with and append it to the file
% \fileent{otfl-blacklist.cnf}.
%
% A blacklist file is a list of font filenames, one per line.
-% Specifying the full path where the file is located is optional, the
+% Specifying the full path to where the file is located is optional, the
% plain filename should suffice.
% File extensions (\fileent{.otf}, \fileent{.ttf}, etc.) may be omitted.
% Anything after a percent (|%|) character until the end of the line
@@ -634,13 +771,13 @@ and the derived files
%
% \section{Files from \CONTEXT and \LUATEX-Fonts}
%
-% This package relies on code originally written by Hans
+% \identifier{luaotfload} relies on code originally written by Hans
% Hagen\footnote{%
% The creator of the \href{http://wiki.contextgarden.net}{\CONTEXT}
% format.
% }
% for and tested with \CONTEXT.
-% \identifier{luaotfload} integrates the font loader as distributed in
+% It integrates the font loader as distributed in
% the \identifier{\LUATEX-Fonts} package.
% The original \LUA source files have been combined using the
% \fileent{mtx-package} script into a single, self-contained blob.
@@ -653,7 +790,7 @@ and the derived files
% The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of
% the implementation, and update the imported code from time to time.
% As maintainers, we aim at importing files from upstream essentially
-% \emphasis{unmodified}, except for renaming the files to prevent name
+% \emphasis{unmodified}, except for renaming them to prevent name
% clashes.
% This job has been greatly alleviated since the advent of
% \LUATEX-Fonts, prior to which the individual dependencies had to be
@@ -714,10 +851,10 @@ and the derived files
% \end{itemize}
% \end{multicols}
%
-% \normalitem The \emphasis{Font Loader} itself.
+% \normalitem The \emphasis{font loader} itself.
% These files have been written for
-% \LUATEX-Fonts and are distributed along with
-% \identifier{luaotfload}.
+% \LUATEX-Fonts and they are distributed along
+% with \identifier{luaotfload}.
% \begin{multicols}{2}
% \begin{itemize}
% \incitem{luatex-basics-gen.lua}
@@ -748,6 +885,16 @@ and the derived files
% \end{multicols}
% \end{itemize}
%
+% Note that if \identifier{luaotfload} cannot locate the
+% merged file, it will load the individual \LUA libraries
+% instead.
+% Their names remain the same as in \CONTEXT (without the
+% \verb|otfl|-prefix) since they are hard-coded in
+% \fileent{otfl-fonts.lua}.
+% Thus if you prefer running bleeding edge code from the
+% \CONTEXT beta, all you have to do is remove
+% \fileent{otfl-fonts-merged.lua} from the search path.
+%
% \end{itemize}
%
% In addition to these, \identifier{luaotfload} requires a number of
@@ -766,9 +913,9 @@ and the derived files
% \ouritem {otfl-lib-dir.lua} \fileent{l-dir} from \CONTEXT;
% contains functionality required
% by \fileent{otfl-font-nms.lua}.
-% \ouritem {otfl-luat-ovr.lua} overrides for the \CONTEXT logging
+% \ouritem {otfl-luat-ovr.lua} overrides the \CONTEXT logging
% functionality.
-% \ouritem {otfl-font-pfb.lua} registers the \identifier{OpenType}
+% \ouritem {otfl-font-pfb.lua} registers the \OpenType
% font reader as handler for
% Postscript fonts.
% \ouritem {otfl-font-nms.lua} font database.
@@ -790,11 +937,12 @@ and the derived files
% version of this package before reporting a bug, as
% \identifier{luaotfload} is under active development and still a
% moving target.
+%
% Errors during database generation can be traced by increasing
% verbosity levels and redirecting log output to \fileent{stdout}:
%
% \begin{verbatim}
-% mkluatexfontdb.lua -F -vvv --log=stdout
+% fontdbutil -fuvvv --log=stdout
% \end{verbatim}
%
% If this fails, the font last printed to the terminal is likely to be
@@ -803,20 +951,40 @@ and the derived files
% being (see above, page \pageref{font-blacklist}).
%
% A common problem is the lack of features for some
-% \identifier{OpenType} fonts even when specified.
+% \OpenType fonts even when specified.
% This can be related to the fact that some fonts do not provide
-% features for the |dflt| script (see above on page
+% features for the \verb|dflt| script (see above on page
% \pageref{script-tag}),
% which is the default one in this package.
-% If this happens, assigning a script when the font is defined should
+% If this happens, assigning a noth script when the font is defined should
% fix it.
-% For example with the |latn| script:
+% For example with \verb|latn|:
%
% \begin{verbatim}
% \font\test=file:MyFont.otf:script=latn;+liga;
% \end{verbatim}
%
-% \part{\fileent{luaotfload.lua}}
+% \part{Implementation}
+%
+% \section{\fileent{luaotfload.lua}}
+%
+% This file initializes the system and loads the font loader.
+% To minimize potential conflicts between other packages and the
+% code imported from \CONTEXT, several precautions are in order.
+% Some of the functionality that the font loader expects to be present,
+% like raw access to callbacks, are assumed to have been disabled by
+% \identifier{luatexbase} when this file is processed.
+% In some cases it is possible to trick it by putting dummies into
+% place and restoring the behavior from \identifier{luatexbase} after
+% initilization.
+% Other cases such as attribute allocation require that we hook the
+% functionality from \identifier{luatexbase} into locations where they
+% normally wouldn’t be.
+%
+% Anyways we can import the code base without modifications, which is
+% due mostly to the extra effort by
+% Hans Hagen to make \LUATEX-Fonts self-contained and encapsulate it,
+% and especially due to his willingness to incorporate our suggestions.
%
% \iffalse
%<*lua>
@@ -1322,7 +1490,7 @@ loadmodule"features.lua"
%</lua>
% \fi
%
-% \part{\fileent{luaotfload.sty}}
+% \section{\fileent{luaotfload.sty}}
%
% \iffalse
%<*package>
diff --git a/luaotfload.lua b/luaotfload.lua
new file mode 100644
index 0000000..c85041b
--- /dev/null
+++ b/luaotfload.lua
@@ -0,0 +1,416 @@
+module("luaotfload", package.seeall)
+
+luaotfload.module = {
+ name = "luaotfload",
+ version = 2.2,
+ date = "2013/04/15",
+ description = "OpenType layout system.",
+ author = "Elie Roux & Hans Hagen",
+ copyright = "Elie Roux",
+ license = "CC0"
+}
+
+local luatexbase = luatexbase
+
+local type, next = type, next
+local stringfind = string.find
+local stringsub = string.sub
+local stringmatch = string.match
+local find_file = kpse.find_file
+
+local add_to_callback, create_callback =
+ luatexbase.add_to_callback, luatexbase.create_callback
+local reset_callback, call_callback =
+ luatexbase.reset_callback, luatexbase.call_callback
+
+local dummy_function = function () end
+
+_G.luaotfload = _G.luaotfload or { }
+local luaotfload = _G.luaotfload
+
+--[[doc--
+No final decision has been made on how to handle font definition. At
+the moment, there are three candidates: The \identifier{generic}
+callback as hard-coded in the font loader, the \identifier{old}
+wrapper, and a simplified version of the latter (\identifier{patch})
+that does nothing besides applying font patches.
+--doc]]--
+
+luaotfload.font_definer = "patch" --- | “generic” | “old”
+
+local error, warning, info, log =
+ luatexbase.provides_module(luaotfload.module)
+
+--[[doc--
+This is a necessary initalization in order not to rebuild an existing
+font.
+Maybe 600 should be replaced by \texmacro{pdfpkresolution} %% (why?)
+or \luafunction{texconfig.pk_dpi} (and it should be replaced
+dynamically), but we don't have access (yet) to the
+\identifier{texconfig} table, so we let it be 600.
+Anyway, it does still work fine even if \texmacro{pdfpkresolution} is
+changed.
+--doc]]--
+
+kpse.init_prog("", 600, "/")
+
+--[[doc--
+We set the minimum version requirement for \LUATEX to v0.74, as it was
+the first version to include version 5.2 of the \LUA interpreter.
+--doc]]--
+
+local luatex_version = 74
+
+if tex.luatexversion < luatex_version then
+ warning("LuaTeX v%.2f is old, v%.2f is recommended.",
+ tex.luatexversion/100,
+ luatex_version /100)
+end
+
+--[[doc--
+\subsection{Module loading}
+
+We load the files imported from \CONTEXT with this function.
+It automatically prepends the prefix \fileent{otfl-} to its argument,
+so we can refer to the files with their actual \CONTEXT name.
+--doc]]--
+
+local fl_prefix = "otfl" -- “luatex” for luatex-plain
+local loadmodule = function (name)
+ local tofind = fl_prefix .."-"..name
+ local found = find_file(tofind,"tex")
+ if found then
+ log("loading file %s.", found)
+ dofile(found)
+ else
+ error("file %s not found.", tofind)
+ end
+end
+
+--[[doc--
+Virtual fonts are resolved via a callback.
+\luafunction{find_vf_file} derives the name of the virtual font file
+from the filename.
+(NB: \CONTEXT handles this likewise in \fileent{font-vf.lua}.)
+--doc]]--
+local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match
+
+local p_dot, p_slash = P".", P"/"
+local p_suffix = (p_dot * (1 - p_dot - p_slash)^1 * P(-1)) / ""
+local p_removesuffix = Cs((p_suffix + 1)^1)
+
+local find_vf_file = function (name)
+ local fullname = find_file(name, "ovf")
+ if not fullname then
+ --fullname = find_file(file.removesuffix(name), "ovf")
+ fullname = find_file(lpegmatch(p_removesuffix, name), "ovf")
+ end
+ if fullname then
+ log("loading virtual font file %s.", fullname)
+ end
+ return fullname
+end
+
+--[[doc--
+
+\subsection{Preparing the Font Loader}
+We treat the fontloader as a black box so behavior is consistent
+between formats.
+The wrapper file is \fileent{otfl-fonts.lua} which we imported from
+\href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}.
+It has roughly two purposes:
+
+\begin{enumerate}
+
+ \item insert the functionality required for fontloader; and
+
+ \item put it in place via the respective callbacks.
+
+\end{enumerate}
+
+How the first step is executed depends on the presence on the
+\emphasis{merged font loader code}.
+In \identifier{luaotfload} this is contained in the file
+\fileent{otfl-fonts-merged.lua}.
+If this file cannot be found, the original libraries from \CONTEXT of
+which the merged code was composed are loaded instead.
+
+Hans provides two global tables to control the font loader:
+
+ \begin{itemize}
+ \item \luafunction{generic_context}:
+ encapsulation mechanism, callback functions
+ \item \luafunction{non generic_context}:
+ customized code insertion
+ \end{itemize}
+
+
+With \luafunction{non_generic_context} we can tailor the font loader
+insertion to our file naming habits (key \luafunction{load_before}).
+Additionally, \luafunction{skip_loading} can be unset to force loading
+of the original libraries as though the merged code was absent.
+Another key, \luafunction{load_after} is called at the time when the
+font loader is actually inserted.
+In combination with the option \luafunction{no_callbacks_yet} in
+\luafunction{generic_context}, we can insert our own,
+\identifier{luatexbase}-style callback handling here.
+--doc]]--
+if not _G. generic_context then _G. generic_context = { } end
+if not _G.non_generic_context then _G.non_generic_context = { } end
+
+local generic_context = generic_context
+local non_generic_context =non_generic_context
+
+generic_context.no_callbacks_yet = true
+
+_G.non_generic_context = { luatex_fonts = {
+ load_before = "otfl-fonts-merged.lua",
+ -- load_after = nil, --- TODO, this is meant for callbacks
+ skip_loading = true,
+}}
+
+--[[doc--
+The imported font loader will call \luafunction{callback.register} once
+while reading \fileent{font-def.lua}.
+This is unavoidable unless we modify the imported files, but harmless
+if we make it call a dummy instead.
+--doc]]--
+
+local trapped_register = callback.register
+callback.register = dummy_function
+
+--[[doc--
+Now that things are sorted out we can finally load the fontloader.
+--doc]]--
+
+loadmodule"fonts.lua"
+
+--[[doc--
+By default, the fontloader requires a number of \emphasis{private
+attributes} for internal use.
+These must be kept consistent with the attribute handling methods as
+provided by \identifier{luatexbase}.
+Our strategy is to override the function that allocates new attributes
+before we initialize the font loader, making it a wrapper around
+\luafunction{luatexbase.new_attribute}.\footnote{%
+ Many thanks, again, to Hans Hagen for making this part
+ configurable!
+}
+The attribute identifiers are prefixed “\fileent{otfl@}” to
+avoid name clashes.
+--doc]]--
+
+do
+ local new_attribute = luatexbase.new_attribute
+ local the_attributes = luatexbase.attributes
+
+ _G.attributes = _G.attributes or { }
+
+ _G.attributes.private = function (name)
+ local attr = "otfl@" .. name
+ local number = the_attributes[attr]
+ if not number then
+ number = new_attribute(attr)
+ end
+ return number
+ end
+end
+
+--[[doc--
+
+\subsection{Callbacks}
+
+After the fontloader is ready we can restore the callback trap from
+\identifier{luatexbase}.
+--doc]]--
+
+callback.register = trapped_register
+
+--[[doc--
+We do our own callback handling with the means provided by luatexbase.
+
+Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter}
+are coupled in \CONTEXT in the concept of \emphasis{node processor}.
+--doc]]--
+
+add_to_callback("pre_linebreak_filter",
+ generic_context.callback_pre_linebreak_filter,
+ "luaotfload.node_processor",
+ 1)
+add_to_callback("hpack_filter",
+ generic_context.callback_hpack_filter,
+ "luaotfload.node_processor",
+ 1)
+add_to_callback("find_vf_file",
+ find_vf_file, "luaotfload.find_vf_file")
+
+loadmodule"font-otc.lua" -- TODO check what we can drop from otfl-features
+loadmodule"lib-dir.lua" -- required by font-nms
+loadmodule"luat-ovr.lua"
+
+if fonts and fonts.readers.tfm then
+ --------------------------------------------------------------------
+ --- OFM; read this first
+ --------------------------------------------------------------------
+ --- I can’t quite make out whether this is still relevant
+ --- as those ofm fonts always fail, even in the 2011 version
+ --- (mktexpk: don't know how to create bitmap font for omarabb.ofm)
+ --- the font loader appears to read ofm like tfm so if this
+ --- hack was supposed achieve that, we should excise it anyways
+ fonts.readers.ofm = fonts.readers.tfm
+ fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways
+ fonts.formats.ofm = fonts.formats.tfm --- “type1”
+ --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm"
+ --------------------------------------------------------------------
+end
+
+--[[doc--
+
+Now we load the modules written for \identifier{luaotfload}.
+
+--doc]]--
+loadmodule"font-pfb.lua" --- new in 2.0, added 2011
+loadmodule"font-nms.lua"
+loadmodule"font-clr.lua"
+loadmodule"font-ltx.lua" --- new in 2.0, added 2011
+
+--[[doc--
+
+We create a callback for patching fonts on the fly, to be used by other
+packages.
+It initially contains the empty function that we are going to override
+below.
+
+--doc]]--
+
+create_callback("luaotfload.patch_font", "simple", dummy_function)
+
+--[[doc--
+
+This is a wrapper for the imported font loader.
+As of 2013, everything it does appear to be redundand, so we won’t use
+it unless somebody points out a cogent reason.
+Nevertheless, it has been adapted to work with the current structure of
+font data objects and will stay here for reference / until breakage is
+reported.
+
+\emphasis{TODO}
+This one also enables patching fonts.
+The current fontloader apparently comes with a dedicated mechanism for
+that already: enhancers.
+How those work remains to be figured out.
+
+--doc]]--
+local define_font_wrapper = function (...)
+ --- we use “tfmdata” (not “fontdata”) for consistency with the
+ --- font loader
+ local tfmdata = fonts.definers.read(...)
+ if type(tfmdata) == "table" and tfmdata.shared then
+ local metadata = tfmdata.shared.rawdata.metadata
+ local mathdata = metadata.math --- do all fonts have this field?
+ if mathdata then
+ local mathconstants = { } --- why new hash, not modify in place?
+ local units_per_em = metadata.units_per_em
+ local size = tfmdata.size
+ for k,v in next, mathdata do
+ --- afaics this is alread taken care of by
+ --- definers.read
+ if stringfind(k, "Percent") then
+ -- keep percent values as is
+ print(k,v)
+ mathconstants[k] = v
+ else
+ mathconstants[k] = v / units_per_em * size
+ end
+ end
+ --- for \overwithdelims
+ --- done by definers.read as well
+ mathconstants.FractionDelimiterSize = 1.01 * size
+ --- fontloader has 2.4 × size
+ mathconstants.FractionDelimiterDisplayStyleSize = 2.39 * size
+ tfmdata.MathConstants = mathconstants
+ end
+ call_callback("luaotfload.patch_font", tfmdata)
+ end
+ return tfmdata
+end
+
+--[[doc--
+
+\subsection{\CONTEXT override}
+
+We provide a simplified version of the original font definition
+callback.
+
+--doc]]--
+
+local read_font_file = fonts.definers.read
+local patch_defined_font = function (...)
+ local tfmdata = read_font_file(...)-- spec -> size -> id -> tmfdata
+ if type(tfmdata) == "table" then
+ call_callback("luaotfload.patch_font", tfmdata)
+ end
+ -- inspect(table.keys(tfmdata))
+ return tfmdata
+end
+
+caches.compilemethod = "both"
+
+reset_callback("define_font")
+
+--[[doc--
+Finally we register the callbacks
+--doc]]--
+
+if luaotfload.font_definer == "old" then
+ add_to_callback("define_font",
+ define_font_wrapper,
+ "luaotfload.define_font",
+ 1)
+elseif luaotfload.font_definer == "generic" then
+ add_to_callback("define_font",
+ generic_context.callback_define_font,
+ "luaotfload.define_font",
+ 1)
+elseif luaotfload.font_definer == "patch" then
+ add_to_callback("define_font",
+ patch_defined_font,
+ "luaotfload.define_font",
+ 1)
+end
+
+--[[todo--
+--- The manual promises coercion of the file: lookup if
+--- the asked name is enclosed in brackets.
+--- A couple things make me doubt that this is the case:
+---
+--- 1) there doesn’t appear to be code for these cases
+--- 2) the brackets remain part of the file name
+--- 3) we still get calls to names.resolve which
+--- ignores the “lookup” field of the spec it gets
+---
+--- For this reason here is some code that a) coerces
+--- file: lookups in these cases and b) strips the brackets
+--- from the file name. As we *still* get name: lookups even
+--- though this code is active I’ll just leave it here
+--- for reference, ineffective as it is.
+do
+ local getspecification, makespecification =
+ fonts.definers.getspecification, fonts.definers.makespecification
+
+ local analyze = function (specification, size)
+ local lookup, name, sub, method, detail = getspecification(specification or "")
+ local filename = stringmatch(name, "^%[(.*)%]$")
+ if filename then
+ lookup = "file" --> coerce file:
+ name = filename --> remove brackets
+ end
+ return makespecification(specification, lookup, name, sub, method, detail, size)
+ end
+ fonts.definers.analyze = analyze
+end
+--]]--
+
+loadmodule"features.lua"
+
+-- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/mkluatexfontdb.lua b/mkluatexfontdb.lua
index e7796db..776fbb3 100755
--- a/mkluatexfontdb.lua
+++ b/mkluatexfontdb.lua
@@ -11,6 +11,8 @@ kpse.set_program_name"luatex"
local stringformat = string.format
local texiowrite_nl = texio.write_nl
+local stringfind = string.find
+local stringlower = string.lower
-- First we need to be able to load module (code copied from
-- luatexbase-loader.sty):
@@ -21,11 +23,49 @@ local loader_path = assert(kpse.find_file(loader_file, "lua"),
--texiowrite_nl("("..loader_path..")")
dofile(loader_path) -- FIXME this pollutes stdout with filenames
-_G.config = _G.config or { }
-local config = _G.config
+--[[doc--
+Depending on how the script is called we change its behavior.
+For backwards compatibility, moving or symlinking the script to a
+file name starting with \fileent{mkluatexfontdb} will cause it to
+trigger a database update on every run.
+Running as \fileent{fontdbutil} -- the new name -- will do this upon
+request only.
+
+There are two naming conventions followed here: firstly that of
+utilities such as \fileent{mktexpk}, \fileent{mktexlsr} and the likes,
+and secondly that of \fileent{fmtutil}.
+After support for querying the database was added, the latter appeared
+to be the more appropriate.
+--doc]]--
+
+config = config or { }
+local config = config
+config.luaotfload = config.luaotfload or { }
+
+do -- we don’t have file.basename and the likes yet, so inline parser ftw
+ local C, P = lpeg.C, lpeg.P
+ local lpegmatch = lpeg.match
+ local slash = P"/"
+ local dot = P"."
+ local noslash = 1 - slash
+ local slashes = slash^1
+ local path = slashes^-1 * (noslash^1 * slashes)^1
+ local thename = (1 - slash - dot)^1
+ local extension = dot * (1 - slash - dot)^1
+ local p_basename = path^-1 * C(thename) * extension^-1 * P(-1)
+
+ -- if stringfind(stringlower(arg[0]), "^fontdbutil") then
+ local self = lpegmatch(p_basename, stringlower(arg[0]))
+ if self == "fontdbutil" then
+ config.luaotfload.self = "fontdbutil"
+ else
+ config.luaotfload.self = "mkluatexfontdb"
+ end
+end
config.lualibs = config.lualibs or { }
-config.lualibs.prefer_merged = false
+config.lualibs.verbose = false
+config.lualibs.prefer_merged = true
config.lualibs.load_extended = false
require"lualibs"
@@ -34,29 +74,42 @@ require"otfl-luat-ovr.lua" --- this populates the logs.* namespace
require"otfl-font-nms"
require"alt_getopt"
-local name = "mkluatexfontdb"
local version = "2.2" -- same version number as luaotfload
local names = fonts.names
local db_src_out = names.path.dir.."/"..names.path.basename
local db_bin_out = file.replacesuffix(db_src_out, "luc")
-local function help_msg()
- texiowrite_nl(stringformat([[
+
+local help_messages = {
+ fontdbutil = [[
Usage: %s [OPTION]...
-Rebuild the LuaTeX font database.
+Operations on the LuaTeX font database.
+
+This tool is part of the luaotfload package. Valid options are:
+
+-------------------------------------------------------------------------------
+ VERBOSITY AND LOGGING
-Valid options:
- -f --force force re-indexing all fonts
-q --quiet don't output anything
-v --verbose=LEVEL be more verbose (print the searched directories)
-vv print the loaded fonts
-vvv print all steps of directory searching
-V --version print version and exit
-h --help print this message
+
+-------------------------------------------------------------------------------
+ DATABASE
+
+ -u --update update the database
+ -f --force force re-indexing all fonts
+
--find="font name" query the database for a font name
-F --fuzzy look for approximate matches if --find fails
+ --limit=n limit display of fuzzy matches to <n>
+ (default: n = 1)
+ -i --info display font metadata
--log=stdout redirect log output to stdout
@@ -64,13 +117,70 @@ The font database will be saved to
%s
%s
-]], name, db_src_out, db_bin_out))
+]],
+ mkluatexfontdb = [[
+
+Usage: %s [OPTION]...
+
+Rebuild the LuaTeX font database.
+
+Valid options:
+ -f --force force re-indexing all fonts
+ -q --quiet don't output anything
+ -v --verbose=LEVEL be more verbose (print the searched directories)
+ -vv print the loaded fonts
+ -vvv print all steps of directory searching
+ -V --version print version and exit
+ -h --help print this message
+
+The font database will be saved to
+ %s
+ %s
+
+]],
+}
+
+local help_msg = function ( )
+ local template = help_messages[config.luaotfload.self]
+ or help.messages.fontdbutil
+ texiowrite_nl(stringformat(template, config.luaotfload.self, db_src_out, db_bin_out))
end
-local function version_msg()
+local version_msg = function ( )
texiowrite_nl(stringformat(
"%s version %s, database version %s.\n",
- name, version, names.version))
+ config.luaotfload.self, version, names.version))
+end
+
+local show_info_items = function (fontinfo)
+ local items = table.sortedkeys(fontinfo)
+ for n = 1, #items do
+ local item = items[n]
+ texiowrite_nl(stringformat(
+ [[ %11s: %s]], item, fontinfo[item]))
+ end
+end
+
+local show_font_info = function (filename)
+ local fullname = resolvers.findfile(filename)
+ if fullname then
+ local fontinfo = fontloader.info(fullname)
+ local nfonts = #fontinfo
+ if nfonts > 0 then -- true type collection
+ logs.names_report(true, 0, "resolve",
+ [[%s is a font collection]], filename)
+ for n = 1, nfonts do
+ logs.names_report(true, 0, "resolve",
+ [[showing info for font no. %d]], n)
+ show_info_items(fontinfo[n])
+ end
+ else
+ show_info_items(fontinfo)
+ end
+ else
+ logs.names_report(true, 0, "resolve",
+ "font %s not found", filename)
+ end
end
--[[--
@@ -79,17 +189,19 @@ executed in the correct order. To avoid duplication we track them in a
set.
--]]--
-local action_sequence = { "loglevel", "help", "version", "generate", "query" }
+local action_sequence = {
+ "loglevel", "help", "version", "generate", "query"
+}
local action_pending = table.tohash(action_sequence, false)
-action_pending.loglevel = true --- always set the loglevel
-action_pending.generate = true --- this is the default action
+action_pending.loglevel = true --- always set the loglevel
+action_pending.generate = false --- this is the default action
local actions = { } --- (jobspec -> (bool * bool)) list
actions.loglevel = function (job)
logs.set_loglevel(job.log_level)
- logs.names_report("log", 2,
+ logs.names_report("log", 2, "util",
"setting log level", "%d", job.log_level)
return true, true
end
@@ -107,8 +219,8 @@ end
actions.generate = function (job)
local fontnames, savedname
fontnames = names.update(fontnames, job.force_reload)
- logs.names_report("log", 0, "fonts in the database",
- "%i", #fontnames.mappings)
+ logs.names_report("log", 0, "db",
+ "fonts in the database", "%i", #fontnames.mappings)
savedname = names.save(fontnames)
if savedname then --- FIXME have names.save return bool
return true, true
@@ -134,6 +246,9 @@ actions.query = function (job)
"resolve", "Font “%s” found!", query)
logs.names_report(false, 0,
"resolve", "Resolved file name “%s”:", foundname)
+ if job.show_info then
+ show_font_info(foundname)
+ end
else
logs.names_report(false, 0,
"resolve", "Cannot find “%s”.", query)
@@ -163,19 +278,25 @@ local process_cmdline = function ( ) -- unit -> jobspec
log_level = 1,
}
+ if config.luaotfload.self == "mkluatexfontdb" then
+ action_pending["generate"] = true
+ end
+
local long_options = {
+ find = 1,
force = "f",
+ fuzzy = "F",
help = "h",
+ info = "i",
+ limit = 1,
log = 1,
quiet = "q",
+ update = "u",
verbose = 1 ,
version = "V",
- find = 1,
- fuzzy = "F",
- limit = 1,
}
- local short_options = "fFqvVh"
+ local short_options = "fFiquvVh"
local options, _, optarg =
alt_getopt.get_ordered_opts (arg, short_options, long_options)
@@ -185,6 +306,8 @@ local process_cmdline = function ( ) -- unit -> jobspec
local v = options[n]
if v == "q" then
result.log_level = 0
+ elseif v == "u" then
+ action_pending["generate"] = true
elseif v == "v" then
if result.log_level > 0 then
result.log_level = result.log_level + 1
@@ -196,6 +319,7 @@ local process_cmdline = function ( ) -- unit -> jobspec
elseif v == "h" then
action_pending["help"] = true
elseif v == "f" then
+ result.update = true
result.force_reload = 1
elseif v == "verbose" then
local lvl = optarg[n]
@@ -217,6 +341,8 @@ local process_cmdline = function ( ) -- unit -> jobspec
if lim then
result.fuzzy_limit = tonumber(lim)
end
+ elseif v == "i" then
+ result.show_info = true
end
end
return result
@@ -233,24 +359,24 @@ local main = function ( ) -- unit -> int
local actionname = action_sequence[i]
local exit = false
if action_pending[actionname] then
- logs.names_report("log", 3, "preparing for task",
+ logs.names_report("log", 3, "util", "preparing for task",
"%s", actionname)
local action = actions[actionname]
local success, continue = action(job)
if not success then
- logs.names_report(false, 0, "could not finish task",
- "%s", actionname)
+ logs.names_report(false, 0, "util",
+ "could not finish task", "%s", actionname)
retval = -1
exit = true
elseif not continue then
- logs.names_report(false, 3, "task completed, exiting",
- "%s", actionname)
+ logs.names_report(false, 3, "util",
+ "task completed, exiting", "%s", actionname)
exit = true
else
- logs.names_report(false, 3, "task completed successfully",
- "%s", actionname)
+ logs.names_report(false, 3, "util",
+ "task completed successfully", "%s", actionname)
end
end
if exit then break end
diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua
index 2e54028..cec2a54 100644
--- a/otfl-font-nms.lua
+++ b/otfl-font-nms.lua
@@ -21,6 +21,9 @@ local tonumber = tonumber
local iolines = io.lines
local ioopen = io.open
local kpseexpand_path = kpse.expand_path
+local kpseexpand_var = kpse.expand_var
+local kpselookup = kpse.lookup
+local kpsereadable_file = kpse.readable_file
local mathabs = math.abs
local mathmin = math.min
local stringfind = string.find
@@ -40,10 +43,11 @@ local utf8lower = unicode.utf8.lower
--- these come from Lualibs/Context
local dirglob = dir.glob
-local dirmkdirs = dir.mkdirds
+local dirmkdirs = dir.mkdirs
local filebasename = file.basename
local filecollapsepath = file.collapsepath
local fileextname = file.extname
+local fileiswritable = file.iswritable
local filejoin = file.join
local filereplacesuffix = file.replacesuffix
local filesplitpath = file.splitpath
@@ -180,15 +184,15 @@ load_names = function ( )
local foundname, data = load_lua_file(names.path.path)
if data then
- report("info", 0, "Font names database loaded", "%s", foundname)
+ report("info", 1, "db",
+ "Font names database loaded", "%s", foundname)
else
- report("info", 0,
+ report("info", 0, "db",
[[Font names database not found, generating new one.
This can take several minutes; please be patient.]])
data = update_names(fontnames_init())
save_names(data)
end
- texiowrite_nl""
return data
end
@@ -251,7 +255,7 @@ font database created by the mkluatexfontdb script.
---
--- the return value of “resolve” is the file name of the requested
--- font
----
+---
--- 'a -> 'a -> table -> (string * string | bool * bool)
---
--- note by phg: I added a third return value that indicates a
@@ -358,8 +362,8 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con
end
end
if #found == 1 then
- if kpse.lookup(found[1].filename[1]) then
- report("log", 0, "load font",
+ if kpselookup(found[1].filename[1]) then
+ report("log", 0, "resolve",
"font family='%s', subfamily='%s' found: %s",
name, style, found[1].filename[1]
)
@@ -379,8 +383,8 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con
least = difference
end
end
- if kpse.lookup(closest.filename[1]) then
- report("log", 0, "load font",
+ if kpselookup(closest.filename[1]) then
+ report("log", 0, "resolve",
"font family='%s', subfamily='%s' found: %s",
name, style, closest.filename[1]
)
@@ -396,7 +400,7 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con
else
--- else, fallback to requested name
--- specification.name is empty with absolute paths, looks
- --- like a bug in the specification parser << is it still
+ --- like a bug in the specification parser <TODO< is it still
--- relevant? looks not...
return specification.name, false, false
end
@@ -569,7 +573,7 @@ font_fullinfo = function (filename, subfont, texmf)
end
else
-- no names table, propably a broken font
- report("log", 1, "broken font rejected", "%s", basefile)
+ report("log", 1, "db", "broken font rejected", "%s", basefile)
return
end
tfmdata.fontname = metadata.fontname
@@ -601,7 +605,7 @@ local load_font = function (filename, fontnames, newfontnames, texmf)
if filename then
if names.blacklist[filename] or
names.blacklist[basename] then
- report("log", 2, "ignoring font", "%s", filename)
+ report("log", 2, "db", "ignoring font", "%s", filename)
return
end
local timestamp, db_timestamp
@@ -624,7 +628,7 @@ local load_font = function (filename, fontnames, newfontnames, texmf)
newmappings[#newmappings+1] = mappings[v]
newstatus[basefile].index[index+1] = #newmappings
end
- report("log", 1, "font already indexed", "%s", basefile)
+ report("log", 1, "db", "font already indexed", "%s", basefile)
return
end
local info = fontloader.info(filename)
@@ -659,7 +663,7 @@ local load_font = function (filename, fontnames, newfontnames, texmf)
newstatus[basefile].index[1] = index
end
else
- report("log", 1, "failed to load", "%s", basefile)
+ report("log", 1, "db", "failed to load", "%s", basefile)
end
end
end
@@ -681,9 +685,9 @@ local function path_normalize(path)
if os.type ~= "windows" and os.type ~= "msdos" then
local dest = lfs.readlink(path)
if dest then
- if kpse.readable_file(dest) then
+ if kpsereadable_file(dest) then
path = dest
- elseif kpse.readable_file(filejoin(file.dirname(path), dest)) then
+ elseif kpsereadable_file(filejoin(file.dirname(path), dest)) then
path = filejoin(file.dirname(path), dest)
else
-- broken symlink?
@@ -700,7 +704,7 @@ names.blacklist = { }
local function read_blacklist()
local files = {
- kpse.lookup("otfl-blacklist.cnf", {all=true, format="tex"})
+ kpselookup("otfl-blacklist.cnf", {all=true, format="tex"})
}
local blacklist = names.blacklist
local whitelist = { }
@@ -719,7 +723,7 @@ local function read_blacklist()
if stringsub(line, 1, 1) == "-" then
whitelist[stringsub(line, 2, -1)] = true
else
- report("log", 2, "blacklisted file", "%s", line)
+ report("log", 2, "db", "blacklisted file", "%s", line)
blacklist[line] = true
end
end
@@ -776,22 +780,25 @@ local function scan_dir(dirname, fontnames, newfontnames, texmf)
]]
local list, found = { }, { }
local nbfound = 0
- report("log", 2, "scanning", "%s", dirname)
+ report("log", 2, "db", "scanning", "%s", dirname)
for _,i in next, font_extensions do
for _,ext in next, { i, stringupper(i) } do
found = dirglob(stringformat("%s/**.%s$", dirname, ext))
-- note that glob fails silently on broken symlinks, which happens
-- sometimes in TeX Live.
- report("log", 2, "fonts found", "%s '%s' fonts found", #found, ext)
+ report("log", 2, "db",
+ "fonts found", "%s '%s' fonts found", #found, ext)
nbfound = nbfound + #found
tableappend(list, found)
end
end
- report("log", 2, "fonts found", "%d fonts found in '%s'", nbfound, dirname)
+ report("log", 2, "db",
+ "fonts found", "%d fonts found in '%s'", nbfound, dirname)
for _,file in next, list do
file = path_normalize(file)
- report("log", 1, "loading font", "%s", file)
+ report("log", 1, "db",
+ "loading font", "%s", file)
load_font(file, fontnames, newfontnames, texmf)
end
end
@@ -802,9 +809,9 @@ local function scan_texmf_fonts(fontnames, newfontnames)
variables OPENTYPEFONTS and TTFONTS of texmf.cnf
]]
if stringis_empty(kpseexpand_path("$OSFONTDIR")) then
- report("info", 0, "Scanning TEXMF fonts...")
+ report("info", 1, "db", "Scanning TEXMF fonts...")
else
- report("info", 0, "Scanning TEXMF and OS fonts...")
+ report("info", 1, "db", "Scanning TEXMF and OS fonts...")
end
local fontdirs = stringgsub(kpseexpand_path("$OPENTYPEFONTS"), "^%.", "")
fontdirs = fontdirs .. stringgsub(kpseexpand_path("$TTFONTS"), "^%.", "")
@@ -844,7 +851,7 @@ read_fonts_conf = function (path, results, passed_paths)
passed_paths[#passed_paths+1] = path
passed_paths_set = tabletohash(passed_paths, true)
if not fh then
- report("log", 2, "cannot open file", "%s", path)
+ report("log", 2, "db", "cannot open file", "%s", path)
return results
end
local incomments = false
@@ -895,7 +902,7 @@ read_fonts_conf = function (path, results, passed_paths)
include = filejoin(file.dirname(path), include)
end
if lfs.isfile(include)
- and kpse.readable_file(include)
+ and kpsereadable_file(include)
and not passed_paths_set[include]
then
-- maybe we should prevent loops here?
@@ -953,8 +960,8 @@ local function scan_os_fonts(fontnames, newfontnames)
- fontcache for Unix (reads the fonts.conf file and scans the directories)
- a static set of directories for Windows and MacOSX
]]
- report("info", 0, "Scanning OS fonts...")
- report("info", 2, "Searching in static system directories...")
+ report("info", 1, "db", "Scanning OS fonts...")
+ report("info", 2, "db", "Searching in static system directories...")
for _,d in next, get_os_dirs() do
scan_dir(d, fontnames, newfontnames, false)
end
@@ -966,7 +973,7 @@ update_names = function (fontnames, force)
- fontnames is the final table to return
- force is whether we rebuild it from scratch or not
]]
- report("info", 0, "Updating the font names database")
+ report("info", 1, "db", "Updating the font names database")
if force then
fontnames = fontnames_init()
@@ -976,8 +983,8 @@ update_names = function (fontnames, force)
end
if fontnames.version ~= names.version then
fontnames = fontnames_init()
- report("log", 0, "No font names database or old one found; "
- .."generating new one")
+ report("log", 1, "db", "No font names database or old "
+ .. "one found; generating new one")
end
end
local newfontnames = fontnames_init()
@@ -1000,14 +1007,14 @@ save_names = function (fontnames)
dirmkdirs(path)
end
path = filejoin(path, names.path.basename)
- if file.iswritable(path) then
+ if fileiswritable(path) then
local luaname, lucname = make_name(path)
tabletofile(luaname, fontnames, true)
caches.compile(fontnames,luaname,lucname)
- report("info", 0, "Font names database saved")
+ report("info", 0, "db", "Font names database saved")
return path
else
- report("info", 0, "Failed to save names database")
+ report("info", 0, "db", "Failed to save names database")
return nil
end
end